Full code<\/summary>\n\/**\n * Walker Navigation Menu class to insert dynamic content into menus\n * use the constructor at creation to pass the dynamic menu content\n *\/\nclass AddExtraMenuItems_Walker extends Walker_Nav_Menu{\n public $insertMenus = array();\n protected $nextMenu = '';\n \/**\n * Constructor takes an array\n *\n *@param array $menu_insert an array of key=>value pairs with\n *each key being the parent menu underwhich to insert the extra menu items,\n *and the value being an array containing menu items as array values of the following form,\n *array( 'url' => permalink for the menu item (default ='#'),\n * 'title' => menu title (default = '<i> Missing Title<\/i>'),\n * 'id' => css id value for the <li> term (default = ''),\n * 'class' => ',' delimited string of css classes for the <li> term (default='') ), each\n *menu will be wrapped in <a> tags that will open in a new window. \n *\/\n function __construct($menu_insert = array()) {\n $this->insertMenus = $menu_insert;\n } \n \n function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {\n $menu_item = apply_filters( 'the_title', $item->title, $item->ID );\n if(array_key_exists($menu_item,$this->insertMenus)){\n \/\/check if to be listed or inserted as sub-menu\n $menuTree = $this->insertMenus[$menu_item];\n $subMenu = ! empty($menuTree['sub-menu']) ? true:false;\n \/*\n *if this is a sub-mneu insert, ;let's make sure our current\n *menu-item has the required class to identify it as such\n *\/\n if($subMenu && ! empty($menuTree['class'])) $item->classes[]=$menuTree['class'];\n \/\/call parent function\n parent::start_el($output, $item, $depth, $args);\n \/\/now if we have a sub-menu tree we need to insert it here\n if($subMenu){\n $classes = ! empty($menuTree['ul-class']) ? ' class=\"'.$menuTree['class'].'\"' : ' class=\"sub-menu\"';\n $output .= '<ul'.$class.'>';\n foreach($menuTree['sub-menu'] as $menu_item){\n $classes = ! empty($menu_item['class']) ? '\" class=\"'.$menu_item['class'].'\"' : '';\n $id = ! empty($menu_item['id']) ? ' id=\"'.$menu_item['id'].'\"' : '';\n $url =! empty($menu_item['url']) ? $menu_item['url'] : '#';\n $title=! empty($menu_item['title']) ? $menu_item['title'] : '<i>Missing Title<\/i>';\n $output .= '<li'.$id.$classes.'><a href=\"'.$url.'\" target=\"_blank\">'.$title.'<\/a><\/li>';\n }\n $output .= '<\/ul>'; \/\/let's close our sub-menu\n }else $this->nextMenu = $menuTree; \/\/else we pass the menu items to be inserted as list items in the start call\n }else parent::start_el($output, $item, $depth, $arg);\n }\n \n function start_lvl( &$output, $depth = 0, $args = array()) {\n parent::start_lvl($output, $depth, $args);\n if($this->nextMenu){\n foreach($this->nextMenu as $menu_item){\n $classes = ! empty($menu_item['class']) ? '\" class=\"'.$menu_item['class'].'\"' : '';\n $id = ! empty($menu_item['id']) ? ' id=\"'.$menu_item['id'].'\"' : '';\n $url =! empty($menu_item['url']) ? $menu_item['url'] : '#';\n $title=! empty($menu_item['title']) ? $menu_item['title'] : '<i>Missing Title<\/i>';\n $output .= '<li'.$id.$classes.'><a href=\"'.$url.'\" target=\"_blank\">'.$title.'<\/a><\/li>';\n }\n $this->nextMenu=''; \/\/reset\n }\n }\n \n}<\/code><\/pre>\n<\/details>\n\n\n\nSo the Walker class is simply called in the wordpress function to display a menu structure,<\/p>\n\n\n\n
wp_nav_menu( array('walker'=> new AddExtraMenuItems_Walker($extra_menu), 'theme_location' => 'primary-menu', 'container' => '', 'fallback_cb' => '', 'menu_class' => 'my-menu-class', 'menu_id' => 'top-menu', 'echo' => false ) );<\/code><\/pre>\n\n\n\nRemains to define the $extra_menu array arguments that are passed to the walker in order to insert it into the right menu. Here is an example. It assumes that there is a primary menu created in the Dashboard with the top level menu item ‘Conferences’ and a sub-item below this called ‘Past’,<\/p>\n\n\n\n
$extra_menu = array(\n 'Conferences'=>array(array('title'=>'ISOl 2015',\n 'url' => 'http:\/\/syllogic.asia\/2015\/',\n 'id' => 'menu_item_isol_2',\n 'class'=> 'menu-item menu-item-type-custom menu-item-object-custom'),\n array('title'=>'ISOl Chicago',\n 'url' => 'http:\/\/syllogic.asia\/2015\/',\n 'id' => 'menu_item_isol_3',\n 'class'=> 'menu-item menu-item-type-custom menu-item-object-custom')),\n 'Past'=>array('ul-class'=>'sub-menu',\n 'class'=>'menu-item-has-children left-sub-menu',\n 'sub-menu'=>array(array('title'=>'ISOl 2015',\n 'url' => 'http:\/\/syllogic.asia\/2015\/',\n 'id' => 'menu_item_isol_2',\n 'class'=> 'menu-item menu-item-type-custom menu-item-object-custom'),\n array('title'=>'ISOl Chicago',\n 'url' => 'http:\/\/syllogic.asia\/2015\/',\n 'id' => 'menu_item_isol_3',\n 'class'=> 'menu-item menu-item-type-custom menu-item-object-custom'))));<\/code><\/pre>\n\n\n\nThere is 2 type of menu being inserted here, the first one under ‘Conferences’ menu item, are 2 extra sub-item which are simply listed within the existing sub-menu list of ‘Conferences’.
\nThe second set of menu is an entire sub-menu structure being replaced instead of an existing menu-item. In other words, ‘Past’ is a sub-item of top menu item ‘Conferences’. As such ‘Past’ does not have any children. This 2nd set of dynamic menu are placed below the ‘Past’, making it into a sub-menu.<\/p>\n\n\n\n
Menu structures are dined as an array with,<\/p>\n\n\n\n
array('title'=>the text of the menu item<\/em>,\n 'url' => the permalink for the menu<\/em>,\n 'id' => a css id for the <li> element<\/em>,\n 'class'=> css classes for the <li> element<\/em>)<\/code><\/pre>\n\n\n\nTo add an entire sub-menu to a given item, you need to specify some extra arguments, namely the classes that changes an item into a sub-menu (on hover the sub-menu will appear) if you are using pure CSS for your menus. This is done using the following structure,<\/p>\n\n\n\n
array('ul-class'=>the css class for the sub-menu <\/em> element<\/em>,\n 'class'=>the css class for the menu item that will change to a sub-menu structure<\/em>,\n 'sub-menu'=>array( sub-menu items as arrays, as defined above<\/em> )<\/ul><\/code><\/pre>\n\n\n\nThat’s it. Feel free to comment, query, clarify below…<\/p>\n","protected":false},"excerpt":{"rendered":"
There are many good tutorials to build custom menus for logged in\/logged out users, see also our own post on the ajax login menu. There are more complex approaches in order to customise the individual menu items using a the wordpress Walker class. An excellent review of a custom walker can be found on the […]<\/p>\n","protected":false},"author":2,"featured_media":343,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,14],"tags":[16,17],"yoast_head":"\n
Dynamic Menus - Tiffin Consulting<\/title>\n\n\n\n\n\n\n\n\n\n\n\n\t\n\t\n\t\n\n\n\n\t\n\t\n\t\n