Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Menu walker with levels WordPress

  • SOLVED

Hi Guys,

we need 2 custom menu walker functions to fit with our site design. I have included a picture of all navigation levels, here is an explanation.

Basically we have 3 levels of navigation, displaying in menus. Each level can include pages, categories and/or posts and the whole system has to be compatible with WPML, so our only option is to use the build-in menu system of WordPress. We can not use child-parent relationships between pages.

We need to display 4 menu item altogether:
- In the header: A list of all Level 1 items from the menu. This can be done with the default walker by limiting the depth to 1, it is not a problem.
- The name of the topmost parent of the current page IN THE MENU SYSTEM - so, if we click on Careers in the top menu, we will see Careers here. If we go down in the navigation we will continue to see "Careers". This is basically the site section. I am stressing on the need to use the menu system as in some cases we will be disaplaing archives or taxonomy pages.
- Level 2 Items from the current branch
- Level 3 Items from the current branch

What the two walkers need to do to achieve this is:

<strong>Walker 1 (for 2nd level menu)</strong>
1. Walk the menu and determine the current depth.

2A. If the current depth is "1", than:
2A.1. return the Name and Link of the current item and apply class "section-header"
2A.2. walk one level down on the current branch, display the items and apply class "section-level2"

2B. If the current depth is "2" or greater:
2B.1. return the Name and Link of the topmost parent of the current item (from the navigation) and apply class "section-header"
2B.2. return all items in level 2 of the current branch, display them and apply class "section-level2"
2B.3. apply class "level2-current" to the current item or it's level-2 parent

<strong>Walker 2 (for 3rd level menu)</strong>
1. Walk the menu and determine the current depth.

2A. If the current depth is "1" do nothing.

2B. If the current depth is "2" than walk the current branch one level down and display all items in level 3 (title + link) and apply class "level3"

2C. If the current depth is "3" or greater, display all items in level 3 (link + title) and apply class "level3". Apply class "level3-current" to the current item or it's parent.

Of course, you can use other names if it makes the task easier.

Answers (2)

2012-09-16

Dbranes answers:

Have you tried this menu plugin?

[[LINK href="http://wordpress.org/extend/plugins/codepress-menu/"]]http://wordpress.org/extend/plugins/codepress-menu/[[/LINK]]


Dbranes comments:

the plugin allows you to use "level" in the wp_nav_menu

for example:

Show level 0 only with depth 1:
<?php
echo wp_nav_menu( array(
'level' => 0,
'depth' => 1
));
?>


Show level 1 only with depth 1:
<?php
wp_nav_menu( array(
'level' => 1,
'depth' => 1
));
?>


and so on.


Yavor Trampov comments:

Dbranes,

thanks for the recomendatio. This seems to be what I need, but I can't get it to work. I have a test install of WordPress where I try all the plugins before I use them on any development installation - kind of trying to save time debugging. Once installed, this plugin breaks my menus and the site in general ("Fatal error: Call to undefined method stdClass::setChildren() in /Volumes/ahorn-design work/Ahorn Design/0010AD_WP_Playground/WebDev/wp-content/plugins/codepress-menu/codepress-menu.php on line 43"). It's just a basic 20/11 theme, so it's not really supposed to break.


Dbranes comments:

hmm... I also installed this plugin on my test machine with TwentyEleven theme and it runs smoothly

I'm using php 5.3.8.


Dbranes comments:

Here is another approach:

Activate the <strong>Advanced menu widget</strong> plugin

[[LINK href="http://wordpress.org/extend/plugins/advanced-menu-widget/screenshots/"]]http://wordpress.org/extend/plugins/advanced-menu-widget/screenshots/[[/LINK]]

Then you get access to the following options in wp_menu_nav :


$menu_args= array(
'fallback_cb' => '',
'menu' => "main_menu", // Select menu
'walker' => new Related_Sub_Items_Walker(), // Walker class
'depth' => 0, // How many levels to display: 0 unlimited depth, 1 level deep, 2 level deep, 3 level deep, ...
'only_related' => 0, // Show hierarchy: 0 display all, 1 only related sub-items
'strict_sub' => 0, // Show only strictly related sub-items: 0 or 1 (then only_related has to be 1)
'filter' => 0, // Filter selection: 0 None, 1 Display direct path, 2 Display only children of selected item
'include_parent' => 0, // Include parents, 0 no, 1 yes
'filter_selection' => '', // Filter selection: page titles
'container' => 'div', // Container: Whether to wrap the ul, and what to wrap it with.
'container_id' => '', // Container ID: The ID that is applied to the container.
'menu_class' => 'menu', // Menu Class: CSS class to use for the ul element which forms the menu.
'before' => '', // Before the link: Output text before the <a> of the link.
'after' => '', // After the link: Output text after the <a> of the link.
'link_before' => '', // Before the link text: Output text before the link text.
'link_after' => '', // After the link text: Output text after the link text.
'start_depth' => 0 // Starting depth levels 0,1,2,...
);

wp_nav_menu($menu_args);


I constructed the above options + comments from the Widget source code:

[[LINK href="http://plugins.svn.wordpress.org/advanced-menu-widget/trunk/advanced-menu-widget.php"]]http://plugins.svn.wordpress.org/advanced-menu-widget/trunk/advanced-menu-widget.php[[/LINK]]

This Walker seems to be very powerful.

One way to use it, is to play with the widget to find out the correct parameters for the $menu_args array above.


Dbranes comments:

By playing with the parameters, the following code seems to display the current branches for level 1, 2 and 3:


// current branch - level 1
echo "current branch - level 1";
$menu_args= array(
'menu' => "main_menu", // Select menu
'walker' => new Related_Sub_Items_Walker(), // Walker class
'depth' => 1, // How many levels to display: 0 unlimited depth, 1 level deep, 2 level deep, 3 level deep, ...
'menu_class' => 'section-level1', // Menu Class: CSS class to use for the ul element which forms the menu.
);
wp_nav_menu($menu_args);

// current branch - level 2
echo "current branch - level 2";
$menu_args= array(
'menu' => "main_menu", // Select menu
'walker' => new Related_Sub_Items_Walker(), // Walker class
'only_related' => 1, // Show hierarchy: 0 display all, 1 only related sub-items
'depth' => 2, // How many levels to display: 0 unlimited depth, 1 level deep, 2 level deep, 3 level deep, ...
'start_depth' => 1, // Starting depth levels 0,1,2,...
'menu_class' => 'section-level2', // Menu Class: CSS class to use for the ul element which forms the menu.
);
wp_nav_menu($menu_args);


// current branch - level 3
echo "current branch - level 3";
$menu_args= array(
'menu' => "main_menu", // Select menu
'walker' => new Related_Sub_Items_Walker(), // Walker class
'only_related' => 1, // Show hierarchy: 0 display all, 1 only related sub-items
'start_depth' => 2, // Starting depth levels 0,1,2,...
'depth' => 3, // How many levels to display: 0 unlimited depth, 1 level deep, 2 level deep, 3 level deep, ...
'menu_class' => 'section-level3', // Menu Class: CSS class to use for the ul element which forms the menu.
);
wp_nav_menu($menu_args);


where the current css-selectors are given by "current-menu-ancestor" and "current-menu-item".



Yavor Trampov comments:

Branes, thanks for this. We managed to get the sitepress solution from your first answer running. I also saw the advanced menu widget during my research and the info you gathered from the source-code - the arguments needed to use the plugin with PHP rather than just as a widget - is really valuable. Thanks for this! Cheers!

2012-09-16

Arnav Joy answers:

can you explain your question , in respect of a top menu item , like what you want when you click on "Karriere"


Yavor Trampov comments:

Hi Arnav,

when you cling "Karrierre" in the uppermost (main) you go to a landing page - the overview page for this site section. It contains the navigation elements as described in the picture. When you browse subpages of this menu tree, the tetle remains "Karriere" and links to the same overview page.

I will try to explain this better. Let's say you have the following tree:

Level 1 Item 1
Level 1 Item 2
_____Level 2 Item 1
_____Level 2 Item 2
_____Level 2 Item 3
__________Level 3 Item 1
__________Level 3 Item 2
__________Level 3 Item 3
_______________Level 4 Item 1
_____Level 2 Item 4
Level 1 Item 3


On the home page you only see the main menu, which looks like this:
<strong>Level 1 Item 1 Level 1 Item 2 Level 1 Item 3 Level 1 Item 3</strong>

When you click on "Level 1 Item 2" you go to the landing page which looks like this:

(Main manu, same as home page) <strong>Level 1 Item 1 Level 1 Item 2 Level 1 Item 3 Level 1 Item 3</strong>
(Section Title)<strong>Level 1 Item 2</strong>
(Second Level Menu)<em>Level 2 Item 1 Level 2 Item 2 Level 2 Item 3 Level 4 Item 3</em>


Click on "Level 2 Item 3" and the menu looks like this:

(Main manu, same as home page) <strong>Level 1 Item 1 Level 1 Item 2 Level 1 Item 3 Level 1 Item 3</strong>
(Section Title)<strong>Level 1 Item 2</strong>
(Second Level Menu)<em>Level 2 Item 1 Level 2 Item 2 <strong>Level 2 Item 3</strong> Level 4 Item 3</em>
(Third level Menu in the Sidebar)Level 3 Item 1 Level 3 Item 2 Level 3 Item 3


Click on "Level 3 Item 3" and the item receives some additional styling:

(Main manu, same as home page) <strong>Level 1 Item 1 Level 1 Item 2 Level 1 Item 3 Level 1 Item 3</strong>
(Section Title)<strong>Level 1 Item 2</strong>
(Second Level Menu)<em>Level 2 Item 1 Level 2 Item 2 <strong>Level 2 Item 3</strong> Level 4 Item 3</em>
(Third level Menu in the Sidebar)Level 3 Item 1 Level 3 Item 2 <strong>Level 3 Item 3</strong>

Go one level down to "Level 4 Item 1" and the menu does not change:

(Main manu, same as home page) <strong>Level 1 Item 1 Level 1 Item 2 Level 1 Item 3 Level 1 Item 3</strong>
(Section Title)<strong>Level 1 Item 2</strong>
(Second Level Menu)<em>Level 2 Item 1 Level 2 Item 2 <strong>Level 2 Item 3</strong> Level 4 Item 3</em>
(Third level Menu in the Sidebar)Level 3 Item 1 Level 3 Item 2 <strong>Level 3 Item 3</strong>


Arnav Joy comments:

so your problem is at when you click on "level item 1" then you did not get selected itmes?

BTW all these are itmes are pages?