I am not a WordPress expert by any standards. However, I did quite a few WP projects and got to know it well enough to try to hack things up here and there. I'd like to share my latest "hack" with you although there is a big possibility that you already know to how to handle situation mentioned in todays post or that there is a better solution out there.
The Problem
The problem is common and I encounter it on every site that I work on. What I need is to have menu label different than page's title. So, one phrase for menu list, and other for page title. As you know, by default WP will use the page title in the menu. If you want to add a longer title, something like "What can we do for you" it will not suitable for navigation. Not only for it's length but the context is wrong too. Navigation must use short, straight to the point words or phrases. In this case the word would be "Services".

"Wait, there is a plugin for that" - you'll say. Yes there is and I used it many times. The plugin is called Page Menu Editor, created by SarahG. You can find it here.
So, why am I not using it now and what's the purpose of this article? Well, on this particular project I wanted to use SPANs nested inside anchors so I can have rounded corners (using sliding doors technique).
<li><a href="#"><span>Home</span></a></li>
I used 2.7's link_before and link_after parameters
<ul id="nav">
<?php wp_list_pages('include=2,3,7,9&link_before=<span>&link_after=</span>&title_li='); ?>
</ul>
For some reason the Sarah's plugin didn't work. I am not going into searching for the reason why it didn't work, it just refused to display the values I provided as page menu labels. When I removed link_before and link_after parameters I had no problems and the plugin worked fine, but with those parameters included I had no luck.
I came up with my own short 'n' sweet solution.
The Solution
I call this solution a "hack" because, in order to get this done, we need to update a file outside your theme's directory, directly in WP's core - classes.php (/wp-includes/classes.php) For that reason alone I suggest you be very careful when applying this hack. :)
The idea behind this is to use WP's custom fields. On each page with long title (or a title you just wish to replace) add a custom field called "menutext" and add a desired value. We are going to use that for navigation item.

Now, carefuly open classes.php file :) (/wp-includes/classes-php) and search for the class named Walker_Page. In it you'll find a function called start_el. Search for this line (1175th line in my classes.php):
$output .= $indent . '<li class="' . $css_class . '"><a href="' . get_page_link($page->ID) . '" title="' . attribute_escape(apply_filters('the_title', $page->post_title)) . '">' . $link_before . apply_filters('the_title', $page->post_title) . $link_after . '</a>';
Immediately before that line put:
$menutext = get_post_meta($page->ID,"menutext",true);
if(empty($menutext)) $menutext = apply_filters('the_title', $page->post_title);
and modify the line itself by replacing:
apply_filters('the_title', $page->post_title)
with:
$menutext
So, the code should now look like this:
$menutext = get_post_meta($page->ID,"menutext",true);
if(empty($menutext)) $menutext = apply_filters('the_title', $page->post_title);
$output .= $indent . '<li class="' . $css_class . '"><a href="' . get_page_link($page->ID) . '" title="' . attribute_escape(apply_filters('the_title', $page->post_title)) . '">' . $link_before . $menutext . $link_after . '</a>';
What we did just now is searched for value of a custom field named "menutext" for each item in the navigation and placed the value in the newly created variable. If the page has that custom field defined it will use it. Otherwise it will use the default value - page's title.
Ok, now, publish the file and that's it!
As I said, I am not an expert and at this moment I am not aware if there is a better solution, so let us all know if you have a better one.
Fouad Masoud 19 Jan, 2009
Sam Benson 19 Jan, 2009
There's something very personal about tearing open your favourite software and adding your own gooey-bits!
Thanks for this.
Hassan 19 Jan, 2009
Thanks for your informations.
Bill Kracke 19 Jan, 2009
However, this isn't "that kind of hack".
Wordpress gives us custom fields for uses like this. They allow us to add data to posts & pages and recall that data later in our code. Just like this.
@Alen: This is a brilliant use of the custom field. Simple. Elegant. I wish I had thought of it!
cssglobe 19 Jan, 2009
zinni 19 Jan, 2009
The problem is not actually the navigation, it is the page titles. I would instead set a custom field for the titles, if it is not null then you use it instead of wp_title(); this would also require editing the header.php file, however you are not changing core files...
cssglobe 19 Jan, 2009
Chris McMahon 19 Jan, 2009
cssglobe 20 Jan, 2009
Martin 21 Jan, 2009
I did a similar hack, but due to my coding background realized it as a separate plugin. This plugin offers a new function - my_list_pages_short with the very same usage as wp_list_pages. So, there is no need to modify standard wp code. If anyone is interested, I can make it publicly available.
Andrzej Stacherski 26 Jan, 2009
Ben Tupper 4 Feb, 2009
Thanks!
Martin 6 Feb, 2009
<li class="page_item page-item-4 current_page_ancestor current_page_parent">
and, of course current_page_item, for the current item. In my example above, page-item-4 is assigned to a page with an id 4. In order to assign different styles, you only have to define a style for a specific id.
Cheers,
M.
Sneha Gupta 12 Feb, 2009
Every post then this might be a tutorial for you. Function have come up with a great tutorial for creating your own custom write panels in wordpress. Well worth a look if you use custom fields a lot in your wordpress.
I am also interested in latest news, sometimes i posted on
<a href = "http://www.wildnettechnologies.com/web-development-services.htm"> Web Development</a>
Mick Thompson 4 Mar, 2009
http://davidmichaelthompson.com/?p=43
chi 28 Apr, 2009
nomad-one 30 May, 2009
Does anyone know of a way to use custom field data inside the link_after parameter?