In this article I show Bill Erickson's code can be used to display select menu from a WordPress custom menu. Also included is a custom shortcode using which you can display select menu in widgets and Page/Post editor in this format: [menudropdown menu="Header Menu"]
In your child theme directory, create lib/classes directory and upload a file named nav-menu-dropdown.php having this code:
<?php | |
/** | |
* Nav Menu Dropdown | |
* | |
* @package BE_Genesis_Child | |
* @since 1.0.0 | |
* @link https://github.com/billerickson/BE-Genesis-Child | |
* @author Bill Erickson <[email protected]> | |
* @copyright Copyright (c) 2011, Bill Erickson | |
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License | |
* | |
*/ | |
class Walker_Nav_Menu_Dropdown extends Walker_Nav_Menu { | |
function start_lvl(&$output, $depth){ | |
$indent = str_repeat("\t", $depth); // don't output children opening tag (`<ul>`) | |
} | |
function end_lvl(&$output, $depth){ | |
$indent = str_repeat("\t", $depth); // don't output children closing tag | |
} | |
/** | |
* Start the element output. | |
* | |
* @param string $output Passed by reference. Used to append additional content. | |
* @param object $item Menu item data object. | |
* @param int $depth Depth of menu item. May be used for padding. | |
* @param array $args Additional strings. | |
* @return void | |
*/ | |
function start_el(&$output, $item, $depth, $args) { | |
$url = '#' !== $item->url ? $item->url : ''; | |
$output .= '<option value="' . $url . '">' . $item->title; | |
} | |
function end_el(&$output, $item, $depth){ | |
$output .= "</option>\n"; // replace closing </li> with the option tag | |
} | |
} |
Now wherever you want to display your custom menu as a select menu, use this following PHP code:
<?php | |
//* Do NOT include the opening php tag | |
// Nav Menu Dropdown Class | |
include_once( CHILD_DIR . '/lib/classes/nav-menu-dropdown.php' ); | |
wp_nav_menu( array( | |
// 'theme_location' => 'mobile', | |
'menu' => 'Header Menu', | |
'walker' => new Walker_Nav_Menu_Dropdown(), | |
'items_wrap' => '<div class="mobile-menu"><form><select onchange="if (this.value) window.location.href=this.value">%3$s</select></form></div>', | |
) ); |
Replace Header Menu with the name or slug or id of your custom menu.
For example when using Genesis:
To get
add this in child theme's functions.php:
<?php | |
//* Do NOT include the opening php tag | |
// Nav Menu Dropdown Class | |
include_once( CHILD_DIR . '/lib/classes/nav-menu-dropdown.php' ); | |
/** | |
* Mobile Menu | |
* | |
*/ | |
function be_mobile_menu() { | |
wp_nav_menu( array( | |
// 'theme_location' => 'mobile', | |
'menu' => 'Header Menu', | |
'walker' => new Walker_Nav_Menu_Dropdown(), | |
'items_wrap' => '<div class="mobile-menu"><form><select onchange="if (this.value) window.location.href=this.value">%3$s</select></form></div>', | |
) ); | |
} | |
add_action( 'genesis_before_header', 'be_mobile_menu' ); |
(replace Header Menu with the name or slug or id of your custom menu)
and this in child theme's style.css:
.mobile-menu { | |
max-width: 400px; | |
margin: 40px auto; | |
} |
What if you want to display the custom menu dropdown in a text widget or within the content of a Page or Post? We have two options.
The first is to use plugins like PHP Code Widget and Shortcode Exec PHP or Global Content Blocks that let you execute PHP in widgets and entries.
The second option is to create a shortcode that outputs the wp_nav_menu() with its walker and use this custom shortcode.
Add this in child theme's functions.php:
To view the full content, please sign up for the membership.
Already a member? Log in below or here.
Very useful tutorial especially when you want to get the menu in responsive web design , clearly explained , Thanks Sridhar !
Thanks! This worked perfectly.
If you are using root.io as a starter theme (I’d call it a framework though), you just have to copy the walker in the libs/extra.php file and then call it from your template like this:
'mobile',
'menu' => 'your_menu',
'walker' => new Walker_Nav_Menu_Dropdown(),
'items_wrap' => '%3$s',
) );
?>
No, I wonder if there is a way to show the current element as the first option.
Like if I'm on a certain category, the first element of the dropdown menu would be that category.
Cheers.
I tried to implement this in a custom menu using the shortcode, and it did put the dropdown in the footer as I requested, but it also put a dropdown in the header of the site, despite the fact that my custom menu is called “Dropdown” and I have no menu called “Header.” Any ideas? I’d be happy to pay for some assistance.
Can you pastebin the entire code in your child theme’s functions.php and share the link?
http://pastebin.com/
[…] Credit Goes To Sridhar Katakam […]
Hello,
After upgrading my server to php 7, I get these for error warning, thanks a lot for your lights 😉
Warning: Declaration of Walker_Nav_Menu_Dropdown::start_lvl(&$output, $depth) should be compatible with Walker_Nav_Menu::start_lvl(&$output, $depth = 0, $args = Array) in /…/lib/classes/nav-menu-dropdown.php on line 40
Warning: Declaration of Walker_Nav_Menu_Dropdown::end_lvl(&$output, $depth) should be compatible with Walker_Nav_Menu::end_lvl(&$output, $depth = 0, $args = Array) in /…/lib/classes/nav-menu-dropdown.php on line 40
Warning: Declaration of Walker_Nav_Menu_Dropdown::start_el(&$output, $item, $depth, $args = Array) should be compatible with Walker_Nav_Menu::start_el(&$output, $item, $depth = 0, $args = Array, $id = 0) in /…/lib/classes/nav-menu-dropdown.php on line 40
Warning: Declaration of Walker_Nav_Menu_Dropdown::end_el(&$output, $item, $depth) should be compatible with Walker_Nav_Menu::end_el(&$output, $item, $depth = 0, $args = Array) in /…/lib/classes/nav-menu-dropdown.php on line 40
Thanks for the Tutorial. This worked perfectly but wondering how can we open menu links in a new window if needed?