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

custom walker for wp_nav_menu (custom html outputted) WordPress

  • REFUNDED

Hey there,
I would like help with a custom walker for wp_nav_menu. I need this for a template I am building.

The walker will need to determine if a menu item is a parent link and whether or not it has
any children links. It will also need to determine whether or not the children links have any ancestors and output the necessary markup accordingly.
The outputted html I am looking for is:
foreach top link that has no children I would like the following code outputted:
<ul>
<li>
<a class="'.$title_class.'" href="'$link'" >$toplink_title<span>$description</span></a>
</li>
</ul>';


foreach top link that has sublinks I would like the following code outputted:
<ul>
<li>
<a class="'.$title_class.'" href="$link">'$toplink_title'<span>$description</span>
<!--[if IE 7]><!--></a><!--<![endif]-->
<table>
<tr>
<td>
<ul>'.$list_of_sub_links.'
</ul>
</td>
</tr>
</table>
<!--[if lte IE 6]></a><![endif]-->
</li>
</ul>


foreach $sublink that has no sublinks I would like the following code outputted:
<li><a href="'.$link_to_sublink.'"> '$sublink_title.'</a></li>


foreach $sublink that has a sublinks I would like the following code outputted:
<li>
<a href="'.$link_to_sublink.'"> '$sublink_title.'
<!--[if IE 7]><!--></a><!--<![endif]-->
<table>
<tr>
<td>
<ul>'.$list_of_sub_links'.'
</ul>
</td>
</tr>
</table>
<!--[if lte IE 6]></a><![endif]-->
</li>


I hope this makes sense If you need any clarification then please don't hesitate to contact me

Answers (4)

2011-01-31

Rashad Aliyev answers:

Hello,

What's the URL of your site?


Leo Kimble comments:

the url is zimbillion.com at the moment the menu is outputting the correct html however this was from a function that just modified the page menu wp_list_pages. I would like to update the theme so that it makes use of wp_nav_menu instead of wp_list_pages so I can include other links.


Leo


Rashad Aliyev comments:

Yes that's clear.

You can use for this for default using.



<div id="yourclass">
<ul class="yourclass">

<?php wp_nav_menu(); ?>

</ul>
</div>


For example if you want to use specific nav menu then make like this.

Firstly register header-menu function for this. Type it to your functions.php
function register_my_menus() {
register_nav_menus(
array('header-menu' => __( 'Header Menu' ) )
);
}
add_action( 'init', 'register_my_menus' );



Make your specific menu as header-menu and use it your theme.

<?php wp_nav_menu( array( 'theme_location' => 'header-menu' ) ); ?>

That's all..


Rashad Aliyev comments:

P.S: Good documentation for this. [[LINK href="http://justintadlock.com/archives/2010/06/01/goodbye-headaches-hello-menus"]]http://justintadlock.com/archives/2010/06/01/goodbye-headaches-hello-menus[[/LINK]]


Leo Kimble comments:

I understand that but the problem is a little more complex than that I am looking for a walker that outputs the same html that is in the menu on Zimbillion.com.
If I use wp_nav_menu
the outputted html is like this <div class="menu-page-menu-a-container"><ul id="menu-page-menu-a" class="menu"><li id="menu-item-98" class="menu-item menu-item-type-custom current-menu-item current_page_item menu-item-home menu-item-98"><a href="http://www.website.com/">Home</a></li>
<li id="menu-item-99" class="menu-item menu-item-type-post_type menu-item-99"><a href="http://www.website.com/page-0">Page #0</a></li>
<li id="menu-item-100" class="menu-item menu-item-type-post_type menu-item-100"><a href="http://www.website.com/page-1">Page #1</a>

<ul class="sub-menu">
<li id="menu-item-102" class="menu-item menu-item-type-post_type menu-item-102"><a href="http://www.website.com/page-1/sub-page-1-1">Sub Page 1.1</a></li>
<li id="menu-item-103" class="menu-item menu-item-type-post_type menu-item-103"><a href="http://www.website.com/page-1/sub-page-1-2">Sub Page 1.2</a></li>
<li id="menu-item-104" class="menu-item menu-item-type-post_type menu-item-104"><a href="http://www.website.com/page-1/sub-page-1-3">Sub Page 1.3</a></li>
<li id="menu-item-105" class="menu-item menu-item-type-post_type menu-item-105"><a href="http://www.website.com/page-1/sub-page-1-4">Sub Page 1.4</a></li>
<li id="menu-item-106" class="menu-item menu-item-type-post_type menu-item-106"><a href="http://www.website.com/page-1/sub-page-1-5">Sub Page 1.5</a></li>
</ul>

</li>



however on my site there is a function that has been written that makes the output like this <ul class="menu">
<li class="top" ><a href="http://zimbillion.com" id="Home" class="top_link"><span>Home</span></a></li>

<li class="top"><a href="http://zimbillion.com/about" id="About" class="top_link"><span class="down">About</span>
<!--[if gte IE 7]><!--></a><!--<![endif]-->
<!--[if lte IE 6]><table><tr><td><![endif]-->
<ul class="dropdown">
<li><a class="fly" href="http://zimbillion.com/about/zimbabwean-money">Zimbabwean Money<!--[if gte IE 7]><!--></a><!--<![endif]-->
<!--[if lte IE 6]><table><tr><td><![endif]-->
<ul>
<li><a href="http://zimbillion.com/about/zimbabwean-money/coins">Coins</a></li>

<li><a href="http://zimbillion.com/about/zimbabwean-money/first-dollar-zwd">The First Dollar (ZWD)</a></li>
<li><a href="http://zimbillion.com/about/zimbabwean-money/second-dollar-zwn">The Second Dollar (ZWN)</a></li>
<li><a href="http://zimbillion.com/about/zimbabwean-money/third-dollar-zwr">The Third Dollar (ZWR)</a></li>
<li><a href="http://zimbillion.com/about/zimbabwean-money/fourth-dollar-zwl">The Fourth Dollar (ZWL)</a></li>
</ul>
<!--[if lte IE 6]></td></tr></table></a><![endif]-->
</li>

<li><a href="http://zimbillion.com/about/zimbillion">Zimbillion</a></li>
</ul>
<!--[if lte IE 6]></td></tr></table></a><![endif]-->
</li>

(the reason for this different markup is to allow for using css sliding doors and also the drop down menu works in all browsers). The function that I have only works on wordpress pages because the theme was written before wordpress 3.0. I am wanting now to upgrade the theme so was wandering if I could get a walker written which would allow me to alter the mark up of wp_nav_menu.
Hope that makes sense?

2011-01-31

John Cotton answers:

Hi Leo

Is the current output directly from wp_list_pages?

If so, have you tried using that walker as the walker for nav_menu?

JC


Leo Kimble comments:

Sorry I was actually wrong. If you read the post below the code doesn't make use of wp_list_pages it actually makes use of a database call that gets all pages and then constructs the menu from there. Otherwise yes your answer would have been perfect

2011-01-31

Sébastien | French WordpressDesigner answers:

could you paste here your function custom please ?


Leo Kimble comments:

ok here is the function:
<?php
function le_get_page (){
global $wpdb;
if ( ! $pages_query = wp_cache_get('page_results', 'pages') ) {
$pages_query = $wpdb->get_results('select post_parent, menu_order, post_title, post_type, ID from '. $wpdb->posts .' where post_status = "publish" and post_type = "page" order by post_parent, menu_order');
wp_cache_add('page_results', $pages_query, 'pages');
}
return $pages_query;
}
?>
<?php
//********** Start Of Page Menu Scrript ***************//
function le_list_pages($div_class='',$title='',$title_class='',$parent_class='',$child_class='',$grandchild_class='',$post_class='',$exclude=''){
global $wpdb;

$pieces = explode(",", $exclude);
$pages_query = le_get_page ();
if (isset($pages_query)){
$t=0;
foreach ($pages_query as $path){
if ($path->post_parent == 0){
$ultimate_parent = $path->ID;
}
foreach ($pages_query as $path){
if ($path->post_parent == $ultimate_parent){
$boohoo = $path->ID;
$travel_path[$t] = array('ultimate'=>$ultimate_parent,'child'=> $boohoo);
$parent_is_parent[$t] = $ultimate_parent;
$second_parent = $ultimate_parent;
}
foreach ($pages_query as $path){
if ($path->post_parent == $boohoo){
$travel_path[$t] = array('ultimate'=>$ultimate_parent,'child'=> $boohoo,'grand'=> $path->cat_ID);
$wahh = $path->cat_ID;
$child_is_parent[$t] = $boohoo;
$parent_is_parent[$t] = $second_parent;
}
$t++;
}
$t++;
}
$t++;
}

$result = array_merge((array)$parent_is_parent, (array)$child_is_parent);
$last = array_unique($result);
$last = array_diff($last, $pieces);
//TOP LEVEL
foreach ($pages_query as $path){
//If Page is Top and Has Subs
if ($path->post_parent == 0 && in_array($path->ID,$last)){
$ultimate_parent = $path->ID;
$output .= '
<li class="top"><a href="'.get_page_link($path->ID).'" id="'.$path->post_title.'" class="top_link"><span class="down">'.$path->post_title.'</span>
<!--[if gte IE 7]><!--></a><!--<![endif]-->
';
$output .= ' <!--[if lte IE 6]><table><tr><td><![endif]-->
<ul class="dropdown">
';
//Second Level
foreach ($pages_query as $path){
if (in_array($path->ID,$last) && $path->post_parent == $ultimate_parent){
$boohoo = $path->ID;
$output .= ' <li><a class="fly" href="'.get_page_link($path->ID).'">'.$path->post_title.'<!--[if gte IE 7]><!--></a><!--<![endif]-->
';
$output .= ' <!--[if lte IE 6]><table><tr><td><![endif]-->
<ul>
';
//Third Level
foreach ($pages_query as $path){
if ($path->post_parent == $boohoo && !in_array($path->ID,$pieces)){
$wahh = $path->ID;
$output .= '<li><a href="'.get_page_link($path->ID).'">'.$path->post_title.'';
$output .= '</a></li>
';
}
$t++;
}
$output .= '</ul>
<!--[if lte IE 6]></td></tr></table></a><![endif]-->
</li>
';
}elseif ($path->post_parent == $ultimate_parent && !in_array($path->ID,$pieces)){
$boohoo = $path->ID;
$output .= '<li><a href="'.get_page_link($path->ID).'">'.$path->post_title.'';
$output .= '</a></li>
';
}
$t++;
}
$output .= ' </ul>
<!--[if lte IE 6]></td></tr></table></a><![endif]-->
</li>
';
//Page Is Top And Has No Subs
}elseif ($path->post_parent == 0 && !in_array($path->ID,$pieces) ){
$ultimate_parent = $path->ID;
$output .= '
<li class="top"><a href="'.get_page_link($path->ID).'" id="'.$path->post_title.'" class="top_link"><span>'.$path->post_title.'</span>';
$output .= '</a></li>
';
}
$t++;
}
echo $output;
}
}
//********** End Of Page Menu Scrript ***************//

as you can see it doesn't make use of wp_list_pages... Sorry for the misleading information I made an assumption. The function makes use of a database call for all pages then constructs the menu from that call. I would like this code modified though so that it does not just do the modified html for pages but instead does it for whatever a person puts into wp_nav_menu.


Sébastien | French WordpressDesigner comments:

so, you don't use wp_nav_menu for the moment ?


Leo Kimble comments:

For the moment no but I would like to upgrade the theme so that I can make use of the new features in wordpress 3.0+.

2011-02-01

Peter Michael answers:

Since you want to upgrade your scripts, maybe you change that menu too. Maybe [[LINK href="http://users.tpg.com.au/j_birch/plugins/superfish/"]]Superfish[[/LINK]] together with wp_nav_menu is something for you.