WordPress fixes part 3 – Customising the wp_list_pages navigation menu drop-downs to insert elements between each menu heading dynamically

This is the last bit I’ll be writing on some customised features I’ve added to my theme – again, because the community (especially in this instance) has been so good to me, the least I can do is return the favour by publicly posting the code/solution to my problem.

When I built my template, I designed it so that between each menu item sits a div to create a space between menu items. While this is easy enough to do in static HTML, I needed a solution that would allow me to do this for my menu system in WordPress through using the wp_list_pages function. Now, it wouldn’t be too hard to programmatically add the div in if the menu was operating as a single unordered (<ul>) list, but I was also leveraging some jQuery to render the drop-down menu system for my sub-menu items two more levels deep; thus, simply adding divs as wrappers with list item tags with the wp_list_pages function wouldn’t work, as the divs would also get added to each of the sub-menu list items.

Ideally, what I needed was a script to treat the menu as two objects – the first would be the top-level navigation, the second would be the two-levels of sub-menu navigation that fly out as drop-downs. Once the output from the database has been extracted into two objects for manipulation within the code, the first object will require an extra div to be added in front of the text block. We add it to the front of each text block so that there isn’t a div left over and placed after the final top-level list item, because that looks messy.

For the second object, all the list items cascade out into sub-lists within the primary menu item. These list items have no additional HTML inserted between elements, and styling them is handled by all the CSS coded up when the template was initially rendered as static HTML.

This of course creates issues with adding in a link back to ‘Home’ via the WordPress widgets – to get around it, I simply added a static link back to home in the header.php file. Crude, but effective.

Not being too cluey with PHP (I’m still on my training wheels!), I took my situation to the WordPress forums and received some fantastic assistance by one of the members on there, vtxyzzy. The following is the eventual code that resulted from our discussion, with vtxyzzy creating the solution whilst I made a couple of tweaks to fix some of the bugs:

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php // Custom menu, author: vtxyzzy; source:  http://wordpress.org/support/topic/360306; minor corrective alts by GisokuBudo, see thread for details
	$my_pages = wp_list_pages('echo=0&depth=3&title_li=&exclude=313');
	$parts = preg_split('/(<ul|<li|<\/ul>)/',$my_pages,null,PREG_SPLIT_DELIM_CAPTURE);
	$insert = '<li class="nav-menu-divider"></li>';
	$newmenu = '';
	$level = 0;
	foreach ($parts as $part) {
		if ('<ul' == $part) {++$level;}
		if ('</ul>' == $part) {--$level;}
		if ('<li' == $part && $level == 0) {$newmenu .= $insert;}
		$newmenu .= $part;
	}
	echo $newmenu;
?>

In the code you’ll notice the $insert function which adds the dividers between each entry in the top-level menu, and leaves the remainder without touching them. Very clever, and certainly isn’t anything I could have achieved without outside help!

So, incorporating this function into my header.php along with the static link back to the homepage looks like this:

header.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<ul id="nav-menu">
	<li><a href="/">Home</a></li>
	<?php // Custom menu, author: vtxyzzy; source:  http://wordpress.org/support/topic/360306; minor corrective alts by GisokuBuo, see thread for details
		$my_pages = wp_list_pages('echo=0&depth=3&title_li=&exclude=313');
		$parts = preg_split('/(<ul|<li|<\/ul>)/',$my_pages,null,PREG_SPLIT_DELIM_CAPTURE);
		$insert = '<li class="nav-menu-divider"></li>';
		$newmenu = '';
		$level = 0;
		foreach ($parts as $part) {
			if ('<ul' == $part) {++$level;}
			if ('</ul>' == $part) {--$level;}
			if ('<li' == $part && $level == 0) {$newmenu .= $insert;}
			$newmenu .= $part;
		}
		echo $newmenu;
	?>
</ul>

Feel free to use the code if you feel it might prove useful to your site. There’s no need to link back/credit, but I wouldn’t mind if you left the comment in the code, posted a comment on the blog or send me a message to let me know if you’ve used it as I’d love to see other people’s use of this great little function!

… and that’s the end of the technical/Wordpress stuff! Expect normal programming to resume form next week, finally! 🙂

Share

3 Responses to “WordPress fixes part 3 – Customising the wp_list_pages navigation menu drop-downs to insert elements between each menu heading dynamically”

  1. This is a great blog you got here. The theme looks nice, awesome color combination.

  2. Hi! I want to say thanks for an interesting site about a subject I have had an interest in for a long time now. I have been lurking and reading the posts avidly so just wanted to express my thanks for providing me with some very good reading material. I look forward to more, and taking a more active part in the discussions here.

Companion blogs

Calendar

March 2010
M T W T F S S
« Feb   Apr »
1234567
891011121314
15161718192021
22232425262728
293031