Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Customise wp_list_categories output WordPress

  • SOLVED

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!

Answers (2)

2011-05-08

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!

2011-05-08

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