1

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!

1 Answer 1

3

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>
5
  • It worked perfectly!!! Thanks a lot :D I was going crazy with it! Jan 31, 2013 at 19:51
  • There are lot of warning messages... Warning: Missing argument 2 for add_parent_class() Nov 11, 2013 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, 2013 at 9:54
  • Can I do same thing for li of children ul ? Nov 11, 2013 at 10:51
  • I'm not sure I understand. The add_parent_class callback function will remove any css classes for pages having child pages, but I'm not sure how that would apply to lis in this case. If you want to add other classes or remove them in other cases, just modify the code to suit your needs.
    – Simon
    Nov 11, 2013 at 16:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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