Does roots filter menus?

The following code outputs a menu but does not output a nav tag as a container. Is roots filtering this somewhere?

$menu_settings = array(
    'menu' => 'Packages',
    'container' => 'nav',
    'container_class' => 'aclass',
    'container_id' => 'anid',
    'menu_class' => 'menu',
    'menu_id' => '',
    'echo' => true,
    'fallback_cb' => false,
    'before' => '',
    'after' => '',
    'link_before' => '',
    'link_after' => '',
    'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>',
    'depth' => 0,
    'walker' => '',
    'theme_location' => 'primary' );

?>

  <?php wp_nav_menu( $menu_settings ); ?>

I’m registering the menus in functions.php:

register_nav_menus( array(
                        'primary' => __( 'Packages Menu', 'themename'),
                        'secondary' => __( 'Services Menu', 'themename' ),
                    ) );

Output of wp menu list:

wp menu list

+---------+--------------------+--------------------+--------------------+-------+
| term_id | name               | slug               | locations          | count |
+---------+--------------------+--------------------+--------------------+-------+
| 4       | About              | about              |                    | 4     |
| 6       | Packages           | packages           | primary            | 6     |
| 5       | Partners           | partners           |                    | 5     |
| 2       | Primary Navigation | primary-navigation | primary_navigation | 7     |
| 3       | Services           | services           | secondary          | 7     |
+---------+--------------------+--------------------+--------------------+-------+

this removes the container param (https://github.com/roots/roots/blob/master/lib/nav.php#L79).

Thanks! Any idea on the reasoning behind removing it? Also should I be using a roots walker function instead (its new to me so any pointers appreciated ;-))

I would think the reason behind removing it is to move markup out of PHP and keeping it HTML, as it should be when possible.

You should read the Roots nav walker and decide based on your needs. It’s commented pretty thoroughly.

i’d definitely use Roots_Nav_Walker. it does a great job of cleaning up wp_nav_menu. and as @cfx said, read up on it in nav.php (https://github.com/roots/roots/blob/master/lib/nav.php). the comments explain what each function in the file does and why. also… checkout how the menu looks when you use it and how it looks without it. the markup is a lot leaner and cleaner with Roots_Nav_Walker.

1 Like

@slobich thanks. If I want the menu output like this -

    <div class="col col-md-4 w-clearfix">
      <ul class="w-list-unstyled about-list">
        <li>one</li>
        <li>two</li>
        <li>three</li>
      </ul>
    </div>
    <div class="col col-md-4 w-clearfix">
      <ul class="w-list-unstyled about-list">
        <li>one</li>
        <li>two</li>
        <li>three</li>
      </ul>
    </div>

Do I need to create my own walker to inject these tags after each set of three menu items?

I got most of the way with this:

class Footer_Split_Nav_Walker extends Roots_Nav_Walker {

	public $count = 0;

	function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) {

		$item_html = '';

		if ($this->count == 0 || $this->count % 3 == 0) {
			$item_html .= '<div class="col col-md-4 w-clearfix">'."\n"
			              .'<ul class="w-list-unstyled about-list">'."\n";
		}
		parent::start_el($item_html, $item, $depth, $args);

		if ($item->is_dropdown && ($depth === 0)) {
			$item_html = str_replace('<a', '<a class="dropdown-toggle" data-toggle="dropdown" data-target="#"', $item_html);
			$item_html = str_replace('</a>', ' <b class="caret"></b></a>', $item_html);
		}
		elseif (stristr($item_html, 'li class="divider')) {
			$item_html = preg_replace('/<a[^>]*>.*?<\/a>/iU', '', $item_html);
		}
		elseif (stristr($item_html, 'li class="dropdown-header')) {
			$item_html = preg_replace('/<a[^>]*>(.*)<\/a>/iU', '$1', $item_html);
		}

		$item_html = apply_filters('roots/wp_nav_menu_item', $item_html);

		$output .= $item_html;
		$this->count++;
	}

	function end_el( &$output, $item, $depth = 0, $args = array() ) {
		$output .= "</li>\n";

		if ($this->count % 3 == 0) {
			$output .= "</ul></div>\n";
		}
	}

}

But this gives me an issue because the whole menu is wrapped in another <ul> and its not valid HTML to nest a <div> within a <ul>

you’re on the right track by extending Roots_Nav_Walker class. as for the <div> issue… why not use a <li> element instead? if your menu is a <ul> than it should contain <li> elements.