Hello,
I am trying to create a dynamic menu using the "appearance > menu" from WP Dashboard.
My issue is as follows;
assume i have a layout a site structure as follows;
Parent
Parent
Child
Child
Child
Parent
Parent
Child
So this is what i want to achieve, i would like all the Parents with Children to have a different class than parents without a child.
The reason i am trying to do this is to add a small graphic to indicate that the parent has children.
I would also like to preserve wordpress's classes (i.e. current_page_item) etc.
I would like to achieve this without the use of a plugin.
Thanks;
Peter Michael answers:
[[LINK href="http://goldenapplesdesign.com/2010/10/05/dropdown-menus-walker_nav_menu/"]]http://goldenapplesdesign.com/2010/10/05/dropdown-menus-walker_nav_menu/[[/LINK]]
xavier comments:
Hello Peter,
With the second set of code on that site, how would i hook that in, using the first example it seemed to work fine but with the second snippet of code it doesn't append the classes.
Peter Michael comments:
Use it like this:
<?php wp_nav_menu( 'walker' => new dropdown_walker() ); ?>
xavier comments:
Parse error: syntax error, unexpected T_DOUBLE_ARROW
Peter Michael comments:
Oops:
<?php wp_nav_menu( array( 'walker' => new dropdown_walker() ) ); ?>
xavier comments:
Still is not adding a class to the parent, only to the sub-menu ul
xavier comments:
let me paste in the code im using then;
class dropdown_walker extends Walker_Nav_Menu
{
var $link_counter=0;
function start_lvl(&$output, $depth) {
global $link_counter;
$class = 'scriptaculously';
$indent = str_repeat("\t",$depth);
$output .= "\n$indent<ul class=\"$class\" id=\"sub-".$link_counter."\" style=\"display:none;\">\n";
}
function start_el(&$output, $item, $depth, $args)
{
global $wp_query;
global $link_counter;
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
$class_names = $value = '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
$class_names = ' class="'. esc_attr( $class_names ) . '"';
if (in_array('has_children',$classes)) $counter++;
$output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';
$attributes = ! empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) .'"' : '';
$attributes .= ! empty( $item->target ) ? ' target="' . esc_attr( $item->target ) .'"' : '';
$attributes .= ! empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) .'"' : '';
$attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : '';
if (strpos($class_names,'has_children')) {
$link_counter++;
$attributes .= ' class="drops" id="link-'.$link_counter.'"';
}
$item_output = $args->before;
$item_output .= '<a'. $attributes .'>';
$item_output .= $args->link_before .apply_filters( 'the_title', $item->title, $item->ID );
$item_output .= $description.$args->link_after;
$item_output .= '</a>';
$item_output .= $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
}
and to call the menu;
<?php wp_nav_menu( array( 'walker' => new dropdown_walker() ) ); ?>
Peter Michael comments:
It's actually the filter function 'check_for_submenu' which adds the classes (has_children) for the parent items, the walker 'dropdown_walker' just extends the whole thing so it can be used with the droplicious menu script.
In your case, the filter function does the job very well, you don't need a custom walker.
Andrzej answers:
Hi Xavier,
Writing a custom walker with this budget might be problematic, however, you can use this trick to get around it:
[[LINK href="http://nbm.im/20110220-10p-109kb.jpg"]]view screenshot[[/LINK]]
This way you can manually add any classes you want. Not dynamic, but does the job pretty well.
xavier comments:
Hello Andrzej,
This is for a clients site, i will end up hiding all these additional facilities such as CSS Classes,
i want to make it as streamline as possible, so this solution would not be acceptable.
Thanks
Darrin Boutote answers:
If all you're wanting to do is add a class, why not use jQuery?
Asuming your structure is something along these lines:
<div id="site-nav">
<ul id="primary-nav">
<li class="top-level"><a href="#" title="">Parent</a>
<ul>
<li><a href="#">Child</a></li>
<li><a href="#">Child</a></li>
</ul>
</li>
<li class="top-level"><a href="#" title="">Non Parent</a></li>
<li class="top-level"><a href="#" title="">Parent</a>
<ul>
<li><a href="#">Child</a></li>
<li><a href="#">Child</a></li>
</ul>
</li>
</ul>
</div>
You could try:
jQuery(document).ready(function($){
// find the first link in the parent element and add a class of "parent" to it
$("#site-nav ul ul").parent().find("a:eq(0)").addClass('parent');
});