Link separator for wp_list_pages()
The Problem
A common problem with the WordPress built-in function for page navigation is the lack of anchor text separator support.
In version 2.7 two more arguments for wp_list_pages() were added to mitigate this inconvenience: link_before and link_after. When using these, the function prepends or appends the specified strings to the generated anchor text. This works well for styling vertical menus.
However, for horizontal menus like the one below, you want the separator to appear between consecutive links and both options become unsuitable:
link_beforewould produce extra markup before the first linklink_afterwould produce extra markup after the last link

The solution
The solution I came up with for a recent project involves using regular expressions to inject the page separator. Basically, you want to alter the structure of all links except the last one. This can be accomplished by searching for all list elements that are followed by an extra list element.
The code
$args = array( 'sort_column' => 'menu_order', 'title_li' => '', 'depth' => '1', 'echo' => 0 ); $separator = ' | '; $pattern = '/(<\\/a>).*?(<\\/li>).*?(<li)/is'; $replace = '</a>' . $separator . '</li><li'; $subnav = preg_replace($pattern,$replace,wp_list_pages($args)); echo $subnav;
You can specify the separator string in the $separator variable and alter its appearance position by changing the $replace variable.
Resources
- The wp_list_pages() codex reference page
- The wonderful http://txt2re.com regular expression generator
Notable Tech Posts – 2010.04.18 | The Life of Lew Ayotte
wrote on April 19, 2010, 07:02
[...] Link separator for wp_list_pages [...]
Capn My Way
wrote on June 1, 2010, 20:41
One question: Where does this code go? (Meaning, where do I paste it?)
Thanks for the code, and the explanation!
Rares
wrote on June 2, 2010, 11:31
Wherever you output the navigation code in your templates.
This article assumes you’re building the nav menu with the
wp_list_pages()function.You have to find out where this function is called. (most probably
header.php)There’s an alternative solution to this problem, if you don’t mind a little bit of client side processing (jQuery).
If the nav menu list element has an id of
#nav:$(document).ready(function(){ $("ul#nav li:not(:last-child)").append(" | "); });Capn My Way
wrote on June 2, 2010, 15:37
Thanks! I just didnt understand that code went inside the <?php tag.
Works like a charm!
Bizim Oyun Sitesi
wrote on June 3, 2010, 10:58
I will use this solution at my site. thank you.
Chris Boggs
wrote on December 13, 2010, 17:43
Thanks for sharing this code, I appreciate it. I have a question or two. I implemented the PHP version (not the js) and it works but with two problems:
1. The seperators come before each nav li, not after, so there is a “|” before the first nav element and not one before the last. How do I alter this output?
2. The “|” seperators are showing up 30 to 40 pixels BELOW the menu items, as if they are on a seperate line. How do I control their placement?
Any suggestions would be greatly appreciated and, once again, thanks for posting this solution.
Rares
wrote on December 14, 2010, 14:42
You’re welcome.
#1: Did you take a look at the source code of the page to confirm the right position of the separators?
#2: This sounds more like a styling problem. Can you provide me with a link to the site in question?
Link separators for wp_list_pages() code snippet | WebDino.net
wrote on May 25, 2011, 01:19
[...] note: I got this code from Rares Comes (very nice lavalamp menu [...]
Matt
wrote on September 16, 2011, 19:16
preg_replace is expensive and you should always try to do the code right from the sever if possible and not just fix it using jQuery. The best way is looping through get_pages(). You can then format it any way you want.
$pages = get_pages( array('parent' => 0, 'sort_column' => 'menu_order, post_title') ); for ($x = 0; $x < count($pages); $x++) { if ($x != 0) echo " | "; echo "<a href='" . get_permalink( $pages[$x]->ID ) . ">" . $pages[$x]->post_title . "</a>"; }David Cunniffe
wrote on October 7, 2011, 15:53
Cool. I had spent ages trying to figure that out. Just one question. How do I include a link to the home page?
Rares
wrote on October 7, 2011, 16:02
David,
You could try to replace the
wp_list_pages()call withwp_page_menu(). Then you can pass in the'show_home' => 1parameter (add it to the$argsarray).David Cunniffe
wrote on October 7, 2011, 22:49
Great, Thanks. That did the trick.
Marcus
wrote on December 1, 2011, 20:40
Worked perfectly. Thanks a million!