I need to customise the output of wp_list_categories to show the top 6 categories, in the following format:
<ul>
    
    <li> 
    	<img src="img/CATEGORY_SLUG.jpg" alt="CATEGORY_NAME icon" /> 
    	<a href="CATEGORY_LINK">CATEGORY_NAME</a> 
    </li> 
    <li class="last"> 
    	<img src="img/CATEGORY_SLUG.jpg" alt="CATEGORY_NAME icon" /> 
    	<a href="CATEGORY_LINK">CATEGORY_NAME</a> 
    </li>
 
    <li> 
    	<img src="img/CATEGORY_SLUG.jpg" alt="CATEGORY_NAME icon" /> 
    	<a href="CATEGORY_LINK">CATEGORY_NAME</a> 
    </li> 
    <li class="last"> 
    	<img src="img/CATEGORY_SLUG.jpg" alt="CATEGORY_NAME icon" /> 
    	<a href="CATEGORY_LINK">CATEGORY_NAME</a> 
    </li> 
    <li> 
    	<img src="img/CATEGORY_SLUG.jpg" alt="CATEGORY_NAME icon" /> 
    	<a href="CATEGORY_LINK">CATEGORY_NAME</a> 
    </li> 
    <li class="last"> 
    	<img src="img/CATEGORY_SLUG.jpg" alt="CATEGORY_NAME icon" /> 
    	<a href="CATEGORY_LINK">CATEGORY_NAME</a> 
    </li>
</ul>
I'm currently using the following, which obviously doesn't output the images or add 'last' to alternate LI tags:
<ul>
	<?php wp_list_categories( array( 'orderby' => 'count', 'order' => 'DESC', 'show_count' => 'TRUE', 'title_li' => '', 'number' => '6' ) ); ?>
</ul>
So I need:
* Order by most popular cats, limit to six entries (as set already)
* Output CATEGORY_SLUG inside the IMG tag
* Output cat name
* Alternate between no class (or 'first' or something like that, if it's easier) and 'last'
Thanks!			
Ivaylo Draganov answers:
								Hi, you should use <em>get_categories</em> function (<em>wp_list_categories</em> uses it anyway), because then you get full control over the output. Try something like this:
$args=array(
	'orderby' => 'count',
	'order' => 'DESC',
	'show_count' => true,
	'title_li' => '',
	'number' => 6
	);
$categories = get_categories($args);
foreach($categories as $category) { 
	$output = '<li>';
    	$output .= '<img src="img/' . $category->slug . '.jpg" alt="' . $category->name . ' icon" />';
    	$output .= '<a href="' . get_category_link($category->term_id) . '">' . $category->name . '</a>';
    $output =. '</li>';
	
} 
If you plan on using it in multiple places you can wrap it in as a function.
For the alternating classes I'd have to dig a little bit (it's a simple PHP counter but it turns out that I can't do it straight). Or you could just do it with CSS (if you don't have to account for some of our old browser friends)							
Ivaylo Draganov comments:
										Updated code, wrapped as a function:
function my_list_categories( $args ) {
	
	// get category objects
	$categories = get_categories($args);
	// class alternator
	$odd_or_even = 'odd';
	// loop objects
	foreach($categories as $category) { 
		// build output
		$output = '<li class="' . $odd_or_even . '">';
			$output .= '<img src="img/' . $category->slug . '.jpg" alt="' . $category->name . ' icon" />';
			$output .= '<a href="' . get_category_link($category->term_id) . '">' . $category->name . '</a>';
		$output =. '</li>';
		
		$odd_or_even = ('odd'==$odd_or_even) ? 'even' : 'odd';
		
	} 
	
	// return output
	return $output;
	
}
Put the above code in <em>functions.php</em> and then call it in your template with the same arguments that you use for <em>wp_list_categories()</em>(omitting <em>title_li</em> and <em>show_count</em>):
<?php my_list_categories( array( 'orderby' => 'count', 'order' => 'DESC', 'number' => '6' ) ); ?>
Jon comments:
Thanks Ivaylo - that looks promising, but I can't seem to get it to work - I dropped the code into functions.php and then tried calling it (it's in my footer) but I get a 500 error as soon as I try loading the page. Any ideas?
Ivaylo Draganov comments:
										I'm sorry, there were two syntax errors. That was because I wrote the code without testing it. Here's the fixed (tested & working) version:
function my_list_categories( $args ) {
	
	// get category objects
	$categories = get_categories($args);
	// class alternator
	$odd_or_even = 'odd';
	// loop objects
	foreach($categories as $category) { 
		// build output
		$output = '<li class="' . $odd_or_even . '">';
			$output .= '<img src="img/' . $category->slug . '.jpg" alt="' . $category->name . ' icon" />';
			$output .= '<a href="' . get_category_link($category->term_id) . '">' . $category->name . '(' . $category->category_count . ')</a>';
		$output .= '</li>';
		
		$odd_or_even = ('odd'==$odd_or_even) ? 'even' : 'odd';
		
	} 
	
	// return output
	return $output;
	
}
I also forgot to mention that you'd have to echo the result of the function:
<?php echo my_list_categories( array( 'orderby' => 'count', 'order' => 'DESC', 'number' => 6 ) ); ?>
Jon comments:
Thanks for the quick reply - looks like it's almost there, but seems to be outputting only the sixth most popular cat, not the whole top 6?
Ivaylo Draganov comments:
										This time it should work as expected:
function my_list_categories( $args ) {
	
	// get category objects
	$categories = get_categories($args);
	// set vars
	$odd_or_even = 'odd';
	$output = '';
	
	// loop objects
	foreach($categories as $category) {
		// build output
		$output .= '<li class="' . $odd_or_even . '">';
			$output .= '<img src="img/' . $category->slug . '.jpg" alt="' . $category->name . ' icon" />';
			$output .= '<a href="' . get_category_link($category->term_id) . '">' . $category->name . '(' . $category->category_count . ')</a>';
		$output .= '</li>';
		
		$odd_or_even = ('odd'==$odd_or_even) ? 'even' : 'odd';
		
	} 
	
	// return output
	return $output;
	
}
Jon comments:
Brilliant - thanks a lot!
Dan | gteh answers:
								If you want to add a class to every other <li>,  use CSS3
li:nth-child(odd)		{ background-color:#eee; }
li:nth-child(even)		{ background-color:#fff; }
assign your .last styles to either odd or even