Opened 9 years ago
Last modified 8 years ago
#35127 new enhancement
Allow wp_nav_menu() function to add container attributes, including Schema.org structured data
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | 4.4 |
Component: | Menus | Keywords: | |
Focuses: | Cc: |
Description
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 SiteNavigationElement as 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
- 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() );
- 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 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!
For anyone looking to incorporate schema.org attributes into the nav, you can accomplish this using the 'wp_nav_menu' filter.
Here's a quick function that you can copy and modify as needed: