Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.
<div class="menu">
    <ul>
        <?php wp_list_pages('exclude=&title_li='); ?>
    </ul>
</div>

creates the following output...

<div class="menu">
    <ul>
        <li><a href="#">Page 1</a></li>
        <li><a href="#">Page with Subpages</a>
            <ul class="children">
                <li><a href="#">Page with another subpage</a>
                    <ul class="children">
                        <li><a href="#">subsubpage</a></li>
                    </ul>
                </li>
            </ul>
        </li>
        <li><a href="#">Page 3</a></li>
        <li><a href="#">Page 4</a></li>
    </ul>
</div>

All pages with children have a ul class="children" applied. Is it possible to create any function (or any other way) to append a classname to all pages THAT HAVE CHILDREN? In my example above only the "Page with Subpages" and it's first child-page "Page with another subpage" should have a li.parent applied.

Is that possible on the serverside? I'm able to do it with javascript, however I wonder if there is a better and cleaner way to do it serverside?

thank you

share|improve this question
add comment

2 Answers

up vote 6 down vote accepted

Phew! Bit more complex than I would've liked - if only the filter page_css_class passed back $args it would save a lot of effort (may submit this to trac).

Since 3.3 it's as easy as this!

function add_parent_class( $css_class, $page, $depth, $args )
{
    if ( ! empty( $args['has_children'] ) )
        $css_class[] = 'parent';
    return $css_class;
}
add_filter( 'page_css_class', 'add_parent_class', 10, 4 );

For those on pre WordPress 3.3, here's the workhorse:

/**
 * Extend the default page walker class to append class names for pages that
 * are parents.
 * @uses Walker_Page
 */ 
class My_Page_Walker extends Walker_Page
{
    /**
     * Filter in the classes for parents.
     */
    function _filterClass( $class )
    {
        $class[] = 'parent'; // change this to whatever classe(s) you require
        return $class;
    }

    /**
     * This is effectively a wrapper for the default method, dynamically adding
     * and removing the class filter when the current item has children.
     */
    function start_el( &$output, $page, $depth, $args, $current_page )
    {
        if ( !empty($args['has_children']) )
            add_filter( 'page_css_class', array( &$this, '_filterClass') );

        parent::start_el( $output, $page, $depth, $args, $current_page );

        if ( !empty($args['has_children']) )
            remove_filter( 'page_css_class', array( &$this, '_filterClass') );
    }
}

I'd advise placing the class in your functions.php, then it's available wherever you'd like to use it.

To use it, call wp_list_pages() like so;

// You need to pass the walker argument to wp_list_pages(). You must use an
// array to do this.
wp_list_pages(array(
    'walker'   => new My_Page_Walker,
    'title_li' => ''
));
share|improve this answer
2  
you are amazing! thank you very much. didn't mean to ask a question that ends in a mega answer. I hope this will help others as well. thank you again! –  mathiregister Mar 12 '11 at 18:53
1  
core.trac.wordpress.org/ticket/17727 - would be a nice improvement I think :) –  TheDeadMedic Jun 8 '11 at 19:24
1  
Patch made it to core! Answer updated. –  TheDeadMedic Jan 11 '12 at 9:31
1  
I'm running WordPress v3.4.1. I had to use $args['has_children'] instead of $args['children']. –  Stephen Watkins Jul 16 '12 at 18:16
1  
@Steve Woops - thanks, updated :) –  TheDeadMedic Jul 16 '12 at 19:53
add comment

I guess there is a more simple solution for that, you could add the following filter in the functions.php file in the theme folder. You don't have to change anything else.

add_filter('page_css_class', 'check_parent', 10, 2 );

function check_parent($css_class, $page) {
    if (wp_list_pages("title_li=&child_of=".$page->ID."&echo=0"))
        array_push($css_class, "parent");
    return $css_class;
}

Hope that helps

share|improve this answer
2  
Ewww, look at all those db queries! I've updated my answer for >=3.3 –  TheDeadMedic Jan 11 '12 at 9:31
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.