Edit: after doing some research I've found that in the wp_nav_menu function uses the following code to display the containers value.

if ( $args->container ) {
     * Filter the list of HTML tags that are valid for use as menu containers.
     * @since 3.0.0
     * @param array $tags The acceptable HTML tags for use as menu containers.
     *                    Default is array containing 'div' and 'nav'.
    $allowed_tags = apply_filters( 'wp_nav_menu_container_allowedtags', array( 'div', 'nav' ) );
    if ( is_string( $args->container ) && in_array( $args->container, $allowed_tags ) ) {
        $show_container = true;
        $class = $args->container_class ? ' class="' . esc_attr( $args->container_class ) . '"' : ' class="menu-'. $menu->slug .'-container"';
        $id = $args->container_id ? ' id="' . esc_attr( $args->container_id ) . '"' : '';
        $nav_menu .= '<'. $args->container . $id . $class . '>';

lines 341 to 357 https://developer.wordpress.org/reference/functions/wp_nav_menu/

$nav_menu .= '<'. $args->container . $id . $class . '>';

The above line deals with the output of the container information I'm now trying to figure out how to modify this information within the custom walker class to add the extra fields.

End of Edit

I'm currently trying to add aria roles and schema markup to a custom walker I've created.

I'm trying to avoid wrapping the menu inside the tags directly like below. I would prefer to edit the container and attach the extra elements dynamically.

<nav class="" role="navigation" itemscope="itemscope"  itemtype="http://schema.org/SiteNavigationElement">
  wp_nav_menu( $defaults );

Currently my wp_nav_menu call looks like this.

$defaults = array(
    'menu'              => '',
    'menu_class'        => '',
    'menu_id'           => '',
    'container'         => 'nav',
    'container_class'   => 'a-primarymenu',
    'container_id'      => '',
    'before'            => '',
    'after'             => '',
    'link_before'       => '',
    'link_after'        => '',
    'depth'             => 0,
    'walker'            => new Custom_Nav_Walker( 'a-primarymenu' ),
    'theme_location'    => 'primary',
    'items_wrap'        => '<ul>%3$s</ul>',
); wp_nav_menu( $defaults );

The container class I assign is passed to the custom walker class and allows my menu output to be as follows.

<nav class="a-primarymenu">
   <li class="a-primarymenu__item"><a href="#link">Link</a></li>
   <li class="a-primarymenu__item"><a href="#link">Link</a></li>
   <li class="a-primarymenu__item"><a href="#link">Link</a></li>
   <li class="a-primarymenu__item"><a href="#link">Link</a></li>
   <li class="a-primarymenu__item"><a href="#link">Link</a></li>

What I need help with is figuring out how to modifer the container html output

aka <nav class="a-primarymenu">

so I can add role="navigation" and itemscope="itemscope" itemtype="http://schema.org/SiteNavigationElement" to the element.

Which would then produce.

<nav class="a-primarymenu" role="navigation" itemscope="itemscope" itemtype="http://schema.org/SiteNavigationElement">

The closest match I could find to this desired output was https://core.trac.wordpress.org/ticket/35127 however this is just a request to the wordpress core and not a modifiered walker.

  • 1
    You can set container => false and wrap ul list inside your nav element.
    – wpclevel
    May 8, 2016 at 14:05
  • Thanks Dan, But using the wrap element would create a loop of schema information. As the information site element is only meant to be on the container itself and not the sub levels. By adding it to the wrap it would repeat down the depths.
    – 550
    May 8, 2016 at 14:09

1 Answer 1


@Dan meant this:

<nav role="navigation" itemscope="itemscope" itemtype="http://schema.org/SiteNavigationElement"><?php

        'container'  => '',
        'items_wrap' => '<ul>%3$s</ul>',

  • Alright thanks dead. Problem with this solution is it result in outputting the following; <nav role="navigation" itemscope="itemscope" itemtype="schema.org/SiteNavigationElement"><ul class="a-primarymenu">links</ul></nav>
    – 550
    May 8, 2016 at 15:24
  • Idea behind the concept is to use the custom walker to deliver the correct aria and schema markup for each site nav element. So header, footer, top menu etc. The container_class is passed to the container walker and outputs a bem style menu with semantic naming. By wrapping the element inside the <nav> as suggested and mentioned in my original post you take the dynamic element away from the markup and it becomes static.
    – 550
    May 8, 2016 at 15:27
  • @550 So you need the schema markup added automatically to your nav element, right? I think how lazy it is. Btw, please call the name @TheDeadMedic correctly, well thanks dead.
    – wpclevel
    May 8, 2016 at 15:54
  • @Dan the basic idea behind it is to add the static markup dynamically to the wp_nav_menu. I've sorted all the sub level markup which googles schema validation reads perfectly. It also works fine from an aria accessability point of view. The general idea behind the walker design is to take the assigned container_class say .a-primary it then generates the a-primarymenu__item, a-primarymenu-submenu for each level and adds other bem based elements. I would use the markup you suggested but it ends up being <nav class="a-primarymenu"><ul class="a-primarymenu"><li class="a-primarymenu__item">
    – 550
    May 8, 2016 at 16:06
  • if I go the direction of skipping the top level class it removes it's semantic purpose. The added bonus of having the walker generate the classes according to it's container_class name is that it can be applied to each nav element which uses the name entered. It then generates the markup and helps from a css point of view because it greatly reduces the nested selectors. So instead of nav > ul > li > a it's simply .a-primarymenu__item > a. or .a-primarymenu-submenu > a.
    – 550
    May 8, 2016 at 16:09

Your Answer

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

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