class=”parent” for wp_list_pages?

<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.

Read More

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

Related posts

Leave a Reply

2 comments

  1. 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' => ''
    ));
    
  2. 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