[wp-trac] [WordPress Trac] #35127: Allow wp_nav_menu() function to add container attributes, including Schema.org structured data

WordPress Trac noreply at wordpress.org
Thu Dec 17 00:06:36 UTC 2015


#35127: Allow wp_nav_menu() function to add container attributes, including
Schema.org structured data
-------------------------+-----------------------------
 Reporter:  sevenspark   |      Owner:
     Type:  enhancement  |     Status:  new
 Priority:  normal       |  Milestone:  Awaiting Review
Component:  Menus        |    Version:  4.4
 Severity:  normal       |   Keywords:
  Focuses:               |
-------------------------+-----------------------------
 I'd like to propose an enhancement that would improve the flexibility of
 the `wp_nav_menu()` function to allow additional attributes to be added to
 the `<nav>` container of menus.  The main purpose of this proposal is to
 enable the ability to add schema.org structured data attributes to the
 menu, but this could be extended to other purposes as well given its
 flexibility.

 Currently, `wp_nav_menu()` offers 3 container-related arguments:
 `$container`, `$container_id`, and `$container_class`.  Using these
 arguments, we can create container elements such as


 {{{
 <nav id="main-menu" class="my-menu">
 }}}

 However, it is not possible to create elements with Structured Data such
 as the [https://schema.org/SiteNavigationElement SiteNavigationElement] as
 [https://developers.google.com/structured-data/schema-org recommended by
 Google], which would look like this


 {{{
 <nav id="main-menu" class="my-menu" role="navigation"
 itemscope="itemscope" itemtype="http://schema.org/SiteNavigationElement">
 }}}


 Adding the `role`, `itemscope`, and `itemtype` attributes is currently
 impossible with `wp_nav_menu()` (without resorting to error-prone string
 replacement), so theme authors and end users need to resort to hard-coding
 the menu wrapper in order to add such attributes.


 My proposal is to add a new `container_atts` argument to `wp_nav_menu()`,
 which will allow arbitrary attributes to be added to the container when
 the `$container` argument is defined.

 The changes required are very minimal and only apply to the
 `wp_nav_menu()` function in `wp-includes/nav-menu-template.php`

 1. First, we just need to register `container_atts` as a valid argument in
 line 257 by adding it to the `$defaults` array


 {{{
 $defaults = array( 'menu' => '', 'container' => 'div', 'container_class'
 => '', 'container_id' => '', 'menu_class' => 'menu', 'menu_id' => '',
         'echo' => true, 'fallback_cb' => 'wp_page_menu', 'before' => '',
 'after' => '', 'link_before' => '', 'link_after' => '', 'items_wrap' =>
 '<ul id="%1$s" class="%2$s">%3$s</ul>',
         'depth' => 0, 'walker' => '', 'theme_location' => '' ,
 'container_atts' => array() );
 }}}

 2. Next, we process and concatenate the attributes and add them to the
 container via the `$nav_menu` string on line 355


 {{{
 $atts = '';  //initialize string to concatenate attributes
 foreach( $args->container_atts as $att => $att_val ){  //iterate over each
 attribute
         $atts.= ' '.$att;  //add attribute name, spaced out

         //Add attribute value, if it exists.  This logic allows for
 attributes without values
         if( ! empty( $att_val ) ) $atts.= '="'.esc_attr( $att_val ).'"';
 }
 $nav_menu .= '<'. $args->container . $id . $class . $atts . '>';   //add
 the string of attributes to the nav/div container
 }}}


 That's all the code that would be required to enable this capability.
 This then allows for function calls such as this:


 {{{#!php
 <?php
 wp_nav_menu( array(
   'theme_location'  => 'primary',
   'container'       => 'nav',
   'container_class' => 'my-menu',
   'container_atts'  => array(
     'role'      => 'navigation',
     'itemscope' => 'itemscope',
     'itemtype'  => 'http://schema.org/SiteNavigationElement',
   )
 ));
 }}}

 Which would produce this output for the container element:


 {{{
 <nav class="my-menu" role="navigation" itemscope="itemscope"
 itemtype="http://schema.org/SiteNavigationElement">
 }}}

 (The other thing I might consider is calling `unset()` on the `id` and
 `class` keys in the `$container_atts` array, to prevent users from adding
 those attributes, since there are already dedicated arguments for them.
 But that is likely adding more restriction than necessary.)


 I think this would be a really simple change, and add a lot of flexibility
 to the `wp_nav_menu()` function.  Beyond just adding valuable attributes
 like structured data, adding data-attributes could be useful for
 javascript-driven applications, and I'm sure there are plenty of other
 possibilities I haven't thought of.

 Thanks for your consideration!

--
Ticket URL: <https://core.trac.wordpress.org/ticket/35127>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list