Advanced WordPress Tutorial: Making a Switching Category Menu

A client of mine wanted to make a horizontal menu that listed all of their categories. Easy enough! But the client was going to have lots of categories, which meant that most would either have to be left out, or the horizontal list of categories was going to have to be multi-line. Not so good. So they asked if I could do something fancy and make an almost-slideshow-like menu with next/prev links to switch between them all. It looked like this:

1

And of course, when clicking the more button:

2

I knew I needed to set up the links in an unordered list in groups of seven. My first challenge was to figure out how to do this automatically, so the client wouldn’t need to do anything but create his categories.

By using the WordPress function¬†get_the_category(), I’d have more control over the output and could use some PHP to break things up. A simple counter would work for this:

<ul class="category-nav">
	<?php
		$categories = get_categories();
		$li=1;
		if($categories){
			foreach($categories as $category) {
 
				if($li==1) {
					echo '<li>';
				};
 
				echo '<a class="item'.$li.'" href="'.get_category_link( $category->term_id ).'">'.$category->cat_name.'</a>';
 
				if($li==7) {
					echo '</li>';
					$li=1;
				} else $li++;
			}
		}
	?>
</ul>

Super easy! Now I had to add the prev/more links to the beginning and end of the list. Of course, we only want these to show in the appropriate places. There didn’t need to be a “more” link on the very last slide, and there didn’t need to be a “prev” link on the first slide. (This is assuming the client will only have 2 slides – otherwise, the appearance of both prev & more means they’ll need to use shorter category names to fit)

I accomplished this using another PHP counter, and a bit of :first-child, :last-child CSS

<ul class="category-nav">
	<?php
		$categories = get_categories();
		$li=1;
		$class=1;
		if($categories){
			foreach($categories as $category) {
 
				if($li==1) {
					echo '<li class="li-item'.$class.'">';
					echo '<a class="prev" href="#">&larr; Prev</a>';
				};
 
				echo '<a class="item'.$li.'" href="'.get_category_link( $category->term_id ).'">'.$category->cat_name.'</a>';
 
				if($li==7) {
					echo '<a class="more" href="#">More &rarr;</a>';
					echo '</li>';
					$li=1;
					$class++;
				} else $li++;
			}
		}
	?>
</ul>
.category-nav li {
	display: none;
}
 
.category-nav li:first-child {
	display: block;
}
 
.category-nav li:first-child .prev,
.category-nav li:last-child .more {
	display: none;
}

Now for the jQuery! Making it actually work was super easy, just a click function for each link and a nice fadeIn for the slide:

$('.category-nav .more').click(function(e) {
	e.preventDefault();
	$(this).parent().hide();
	$(this).parent().next().fadeIn();
})
 
$('.category-nav .prev').click(function(e) {
	e.preventDefault();
	$(this).parent().hide();
	$(this).parent().prev().fadeIn();
})

Neato!