Ask your WordPress questions! Pay money and get answers fast! (more info)

Custom Walker for wp_list_categories() WordPress

  • SOLVED

Please can someone help me write a Custom Walker for wp_list_categories().

When a list item has children, I would like a class name of "parent" added to the list items anchor link. See the code below (line 3) for an example of the required output. All other default behaviour of wp_list_categories should remain unchanged.

<ul>
<li class="cat-item cat-item-18 current-cat">
<a class="parent" href="http://localhost/browse/vegetables/" title="Super healthy fresh Vegetables">Vegetables</a>
<ul class='children'>
<li class="cat-item cat-item-36">
<a href="http://localhost/browse/vegetables/green-vegetables/" title="View all posts filed under Green Vegetables">Green Vegetables</a>
</li>
</ul>
</li>
<li class="cat-item cat-item-9">
<a href="http://localhost/browse/fruit/" title="View all posts filed under Fruit">Fruit</a>
</li>
<ul>

The Custom Walker should be called as per the below. Please note, I am creating a dropdown menu using WooCommerce product categories as my base.

wp_list_categories(
array(
'taxonomy' => 'product_cat',
'walker' => new WPQuestions_Walker
)
);

Thank you.

Answers (4)

2013-06-29

Dbranes answers:

You can try this one:

class WPQuestions_Walker extends Walker_Category {
function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
extract($args);

$cat_name = esc_attr( $category->name );
$cat_name = apply_filters( 'list_cats', $cat_name, $category );

// ---
$termchildren = get_term_children( $category->term_id, $category->taxonomy );
if(count($termchildren)>0){
$aclass = ' class="parent" ';
}

$link = '<a '.$aclass.' href="' . esc_url( get_term_link($category) ) . '" ';
// ---

if ( $use_desc_for_title == 0 || empty($category->description) )
$link .= 'title="' . esc_attr( sprintf(__( 'View all posts filed under %s' ), $cat_name) ) . '"';
else
$link .= 'title="' . esc_attr( strip_tags( apply_filters( 'category_description', $category->description, $category ) ) ) . '"';
$link .= '>';
$link .= $cat_name . '</a>';

if ( !empty($show_count) )
$link .= ' (' . intval($category->count) . ')';

if ( 'list' == $args['style'] ) {
$output .= "\t<li";
$class = 'cat-item cat-item-' . $category->term_id;

if ( !empty($current_category) ) {
$_current_category = get_term( $current_category, $category->taxonomy );
if ( $category->term_id == $current_category )
$class .= ' current-cat';
elseif ( $category->term_id == $_current_category->parent )
$class .= ' current-cat-parent';
}
$output .= ' class="' . $class . '"';
$output .= ">$link\n";
} else {
$output .= "\t$link<br />\n";
}
}
}


<strong>update:</strong> modified the walker slightly.


designbuildtest comments:

Perfect - that did the trick. Many thanks Dbranes.

2013-06-29

isp_charlie answers:

try this.
<?php
$args = array(
'show_option_all' => '',
'orderby' => 'name',
'order' => 'ASC',
'style' => 'list',
'show_count' => 0,
'hide_empty' => 1,
'use_desc_for_title' => 1,
'child_of' => 0,
'feed' => '',
'feed_type' => '',
'feed_image' => '',
'exclude' => '',
'exclude_tree' => '',
'include' => '',
'hierarchical' => 1,
'title_li' => __( 'Categories' ),
'show_option_none' => __('No categories'),
'number' => null,
'echo' => 1,
'depth' => 0,
'current_category' => 0,
'pad_counts' => 0,
'taxonomy' => 'product_cat',
'walker' => null
);
$categories = wp_list_categories($args);
$category_array = preg_split('/n/', $categories);
$count = count($category_array);
$i = 0;
while ( $i < $count ) {
if ( preg_match('/<ul class=('|")children('|")/i', $category_array[$i+1]) ) {
echo preg_replace('/<li class=('|")(.+)('|")>/i', '<li class=$1parent $2$3>', $category_array[$i]) . "n";
} else {
echo $category_array[$i] . "n";
}
$i++;
}
?>


designbuildtest comments:

Hi. This doesn't work I'm afraid. There's a syntax error in your code and I'm pretty sure your attempting to apply a class name to the list item (li) rather than the anchor (a) link.

2013-06-29

Abdelhadi Touil answers:

Hi.
Do you know the wp_nav_menu() function? It's ideal in your situation and better than using wp_list_categories() as we full control of it in such situations:

http://codex.wordpress.org/Function_Reference/wp_nav_menu[[LINK href="http://codex.wordpress.org/Function_Reference/wp_nav_menu"]]
[[/LINK]]
Good luck.


designbuildtest comments:

Hi Abdelhadi, yip, I'm aware of wp_nav_menu(). Specifically needed to modify wp_list_categories() in this case however. Thanks.

2013-06-29

Arnav Joy answers:

you can try this using jQuery also , place a id in the ul then write following code


<script>
jQuery(document).ready(function(){
jQuery('ul#categories_ul li').find('ul').each(function(){
if( jQuery(this).hasClass('children') ){
jQuery(this).parent().find('a').addClass('parent');
}

});
})
</script>



so your first ul will be like

<ul id="categories_ul">

so your actual output of wp_list_categories will look like

<ul id="categories_ul">

<li class="cat-item cat-item-18 current-cat">

<a href="http://localhost/browse/vegetables/" title="Super healthy fresh Vegetables">Vegetables</a>

<ul class='children'>

<li class="cat-item cat-item-36">

<a href="http://localhost/browse/vegetables/green-vegetables/" title="View all posts filed under Green Vegetables">Green Vegetables</a>

</li>

</ul>

</li>

<li class="cat-item cat-item-9">

<a href="http://localhost/browse/fruit/" title="View all posts filed under Fruit">Fruit</a>

</li>

</ul>


designbuildtest comments:

Hi Arnav, thanks for the jQuery solution. I specifically wanted a custom walker in this instance however which Dbranes was able to supply. Thanks for your time.