my first encounter with walkers

there was this cool function that adds a custom css class in the parent’s <li>:


// http://stackoverflow.com/questions/2983616/wordpress-filters-documentation-trying-to-understand-add-filter
function my_list_pages_filter($pages){
    $pages = preg_replace( '/<a/', '<a class="parent"', $pages );
    return $pages;
}
add_filter( 'wp_list_pages', 'my_list_pages_filter' );

output will look something like:


<ul>
    <li><a href="#">first level a</a>
    <li class="parent"><a href="#">first level b</a>
        <ul>
            <li><a href="#">level two a</a></li>
            <li><a href="#">level two b</a></li>
            <li><a href="#">level two a</a></li>
        </ul>
    <li>
</ul>

nice! but what if i need a css class on the parent's hyperlink instead? like so:


<ul>
    <li><a href="#">first level a</a>
    <li><a href="#" class="parent">first level b</a>
        <ul>
            <li><a href="#">level two a</a></li>
            <li><a href="#">level two b</a></li>
            <li><a href="#">level two a</a></li>
        </ul>
    <li>
</ul>

i asked around and i was advised to use WordPress' Walker Class. creating a simple php function is currently not possible as far as i have reached (i am using WP 3.5.1 as of writing). fair enough.

after hours of digging, i found this cool script. it was nice, quite detailed but it still took me several more hours to understand.

after a day of hair pulling and keyboard banging, i was able to identify those pages with children and add a class called parent. here is what i have so far:


class mark_parent_link extends Walker_page {

    function start_el(&$output, $page, $depth, $args, $current_page) {

        if ( !empty($args['has_children']) ) {
            $parentlinkclass = 'parent';
        }

        $css_class = implode( ' ', apply_filters( 'page_css_class', $css_class, $page, $depth, $args, $current_page ) );
        $output .= $indent . '<li><a href="' . get_permalink($page->ID) . '" class="' . $parentlinkclass . '">' . $link_before . apply_filters( 'the_title', $page->post_title, $page->ID ) . $link_after .'</a>';
    }
}

i think there is a better way to simplify this but i will let it as is for now. besides, it gives me what i need and i find it quite flexible.

#notetoself

place this class in function.php and call wp_list_pages like so:


wp_list_pages(array(
    'walker'   => new mark_parent_link,
    'title_li' => ''
));

  • http://twitter.com/badfunpro Ken Dirschl

    I believe a certain amount of hair-pulling is obligatory when digging into WP’s dark side. Congratulations on your solution!