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.

Hello I'm using this code to print a list of Pages and Subpages:

<ul>
<?php wp_list_pages('title_li=&depth=2&child_of='); ?>
</ul>

It outputs:

<ul>
    <li><a href="#">Page 1</a></li>
    <li><a href="#">Page 2</a>
        <ul class="children">
            <li><a href="#">Subpage 2a</a></li>
            <li><a href="#">Subpage 2b</a></li>
        </ul>
    </li>
    <li><a href="#">Page 3</a></li>
        <ul class="children">
            <li><a href="#">Subpage 3a</a></li>
            <li><a href="#">Subpage 3b</a></li>
        </ul>
    <li><a href="#">Page 4</a></li>
</ul>

Is there a way to override the <ul class="children"> for something else in the functions.php? like <div class="container"><div class="container2"><ul> and the closing to </ul></div></div>

I was checking this example but I don't know how to apply it to my case... Any help appreciated, thanks!

share|improve this question

1 Answer 1

You can override this by supplying your on Walker Object when calling wp_list_pages, like this:

<your-template>.php

wp_list_pages(array(
    'title_li' => null,
    'depth' => 2,
    'child_of' => 0,
    'walker' => new My_Walker(),
));

Instead of the default Walker_Page this will make wp_list_pages use your custom walker, My_Walker. The only difference we need here is to make your entire list wrapped in the two divs you described in your question. To do this we need to override the methods start_lvl and end_lvl of Walker_Page. As defined below, the list will be wrapped in two divs when it's on level 0 (the top most level), while subsequent lists will be plain ul elements.

functions.php

class My_Walker extends Walker_Page {

    function start_lvl( &$output, $depth = 0, $args = array() ) {
        $indent = str_repeat("\t", $depth);

        if ($depth == 0) {
            $output .= "\n$indent<div class='container'><div class='container2'><ul>\n";
        } else {
            $output .= "\n$indent<ul class='children'>\n";
        }
    }

    function end_lvl( &$output, $depth = 0, $args = array() ) {
        $indent = str_repeat("\t", $depth);

        if ($depth == 0) {
            $output .= "$indent</ul></div></div>\n";
        } else {
            $output .= "$indent</ul>\n";
        }
    }
}

Alternatively, as described in the link you supplied, just override the page_css_class and wrap each function call with your divs manually:

functions.php

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

<your-template>.php

<div class="container"><div class="container2"><ul>
<ul>
<?php wp_list_pages('title_li=&depth=2&child_of='); ?>
</ul>
</div></div>
share|improve this answer
    
It worked perfectly!!! Thanks a lot :D I was going crazy with it! –  Shirou June Jan 31 '13 at 19:51
    
There are lot of warning messages... Warning: Missing argument 2 for add_parent_class() –  Rana Muhammad Usman Nov 11 '13 at 8:44
    
@RanaMuhammadUsman: Perhaps WordPress (or another filter) is not supplying all of the function parameters for the page_css_class filter (anymore). Just add some default values for your callback function and you should be fine. See updated answer for details. –  Simon Nov 11 '13 at 9:54
    
it worked... thanks :) –  Rana Muhammad Usman Nov 11 '13 at 10:07
    
Can I do same thing for li of children ul ? –  Rana Muhammad Usman Nov 11 '13 at 10:51

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.