Jump to content

Multi-level menu


Recommended Posts


I am trying to set up a multi-level menu in nested unordered lists. Specifically, I want to get pages from the first three levels in the page hierarchy. Since the page structure is somewhat complex and I wanted it to be flexible in the future, I added a checkbox field named "in_main_menu" that I can then use as a selector, in case some pages should not appear in the menu.

The top level menu was easy:

$main_menu = $pages->find('parent=/, in_main_menu=1, sort=sort, limit=7');

Then, as I was thinking through how to set up the nested navigation under each main menu item, I was thinking a "maximum depth" selector would be handy. Return all pages matching this selector that are no more than 3 levels deep in the hierarchy. I could not find a way to do that with selectors, though. I believe such a method would not return the pages in the exact order I want, anyway.

My next thought was that I can just perform a find that returns all pages with in_main_menu, then process the results and build an array in the desired format. I'm not totally sure how that processing would work; I think it would be a bit complicated.

Rather than dive into that . . . my final attempt (before posting now :)) was to loop through the main menu pages and call children() on each of those. Then repeat for the third level. This seems to work, except for the third level, where I get an error.

# loop: main menu pages
foreach ( $main_menu as $main )
	// output top-level menu item

	# if: secondary menu
	if ( $secondary_menu = $main->children('in_main_menu=1') )

		# loop: secondary menu pages
		foreach ( $secondary_menu as $second )
			// output second-level menu item

			# if: tertiary menu
			if ( $tertiary_menu = $second->children('in_main_menu=1') )

				# loop: tertiary menu pages
				foreach ( $tertiary_menu as $third )
					// output third-level menu item
				} # end loop: tertiary menu pages

			} # end if: tertiary menu

		} # end loop: secondary menu pages

	} # end if: secondary menu

} # end loop: main menu pages

And it looks like this will work! My question, though, is whether I'm overlooking a simpler method. I would welcome your feedback. I realize I could abstract my code into a function (that would also allow N-levels), but I'm curious if there's even easier ways with the PW API.

Link to comment
Share on other sites

Hi gRegor, first of all welcome!

Before going into your code, are you aware that there is an excellent and simple module for this already? You can choose maxdepth as well as your own custom selectors. 

Here is the relevant thread http://processwire.com/talk/topic/1036-markupsimplenavigation/

You may well be aware of this already and want to code your own but just in case ;)

  • Like 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Create New...