Here is how to add a Data Attribute to a Menu List Item via the Walker Menu Class. Some of the markup of the WordPress menu is hard to filter or hook into, the Walker class allows for a full custom menu mark up.
One request I find is to add a data attribute to the list item itself, instead of the link tag <a> which can be accomplished using nav_menu_link_attributes , for the <li> item you will need to create a whole new menu using the Walker Menu Class.
Register and Position a New Menu
First up is to register a new menu and link it to an instance of the Walker Class
So in the above gist I am registering a new menu with wp_nav_menu with a theme location of tertiary, adding support for it with add_theme_support as I am using Genesis and also positioning it before the loop with an action.
Notice in the $args for wp_nav_menu I am giving a value to ‘walker’ – this is the new instance of the walker class named WPB_Custom _Walker
Making a New Walker Class Instance
Make a copy of class Walker_Nav_Menu from the original /wp-includes/class-walker-nav-menu.php – here I have added it to my theme’s /inc directory and named it custom-walker.php Make sure you change the class name from the original in the file, my one starts – class WPB_Custom_Walker extends Walker
In essence now the new menu will follow the new walker instance so you can alter the output in custom-walker.php which will reflect on the rendered output on the new menu.
Adding Custom Fields for Data Attributes
There is a great library that allows us to add custom fields to the menu items in the backend of WordPress, which we then can output in our custom-walker.php file.
The library is here. Download it and extract the files in the screen grab, remember we already have custom-walker.php and add into your themes /inc folder and bring in one of them to your functions.php file.
Bring in menu-item-custom-fields.php into functions.php
require_once dirname( __FILE__ ) . '/inc/menu-item-custom-fields.php';
This file menu-item-custom-fields.php in turn references the other walker-nav-menu-edit.php and the file in the doc directory – walker-nav-menu-edit.php gives us our sample custom fields which need to be copied and added to functions.php
So in the above I have added one new specific field and left the other one at the default text…
self::$fields = array( 'field_description' => __( 'Data Content', 'menu-item-custom-fields-example' ), 'field_02' => __( 'Custom Field #2', 'menu-item-custom-fields-example' ), );
I have also changed any text from menu-item-%s to _menu_item_%s in the function _save and function_fields
This is then ready in the admin backend…
Output in the Front End Markup
Final thing is to retrieve the field with get_post_meta in the custom-walker.php file
$item->datacontent = get_post_meta( $item->ID, '_menu_item_field_description', true );
Then call it in the <li> item
$output .= $indent . '<li' . $attributes . $id . $class_names . 'data-content="' . $item->datacontent . '">';
custom-walker.php with custom field added at line 81 and called in the output at line 123
Mammoth task complete! – In some instances you may just want to add a jQuery fix but in others you may need the attribute value to change by the end user in which case you’ll need a custom solution.