If you’re trying to make a fancy navigation menu with CSS, you might have found the default IDs and classes applied by WordPress to the nav menu elements to be quite lacking. However, you can fix that by adding a custom walker function to add your own conditional classes. The custom nav walker function I made below will add the following CSS classes:
CSS Classes
These requested features were can also be added to the code below. Click on each to be taken to the comment on this page describing how to integrate it.
This should make styling your Navigation Menus MUCH simpler.
Code
You call the function by supplying the name in the $args when you call the wp_nav_menu function in you theme. So for example, to enable our walker, we would call the menu with this:
Print Registered Nav Menu
This would create the nav menu for the location “navigation_menu_secondary” give it a div wrapper with an id and class, and the first level menu will get the added classes main-menu, menu-depth-0, andmenu-even. Now on to our custom walker function:
Custom Nav Menu Walker Function
In order to utilize this custom walker class, you would call wp_nav_menu() (likely from within a theme file) and pass it a new instance of the custom Walker child class.
CSS Classes
- .main-menu to top menu
- .sub-menu to menus inside the main-menu
- .menu-item to all <li>’s
- .main-menu-item to all <li>’s in the main menu
- .sub-menu-item to all <li>’s in a sub-menu
- .sub-sub-menu to all menus inside a sub-menu
- .menu-even/.menu-odd for <ul>’s (alternating)
- .menu-depth-# to tell you how deep each menu is
- .menu-item-even or .menu-item-odd (alternating)
- .menu-item-depth-# to tell you which level menu the <li> is in
- .menu-link to links
These requested features were can also be added to the code below. Click on each to be taken to the comment on this page describing how to integrate it.
This should make styling your Navigation Menus MUCH simpler.
Code
You call the function by supplying the name in the $args when you call the wp_nav_menu function in you theme. So for example, to enable our walker, we would call the menu with this:
Print Registered Nav Menu
wp_nav_menu( array( 'theme_location' => 'navigation_menu_primary', 'container' => 'div', 'container_id' => 'top-navigation-primary', 'conatiner_class' => 'top-navigation', 'menu_class' => 'menu main-menu menu-depth-0 menu-even', 'echo' => true, 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>', 'depth' => 10, 'walker' => new themeslug_walker_nav_menu ) ); // thanks nick
This would create the nav menu for the location “navigation_menu_secondary” give it a div wrapper with an id and class, and the first level menu will get the added classes main-menu, menu-depth-0, andmenu-even. Now on to our custom walker function:
Custom Nav Menu Walker Function
class themeslug_walker_nav_menu extends Walker_Nav_Menu { // add classes to ul sub-menus function start_lvl( &$output, $depth ) { // depth dependent classes $indent = ( $depth > 0 ? str_repeat( "\t", $depth ) : '' ); // code indent $display_depth = ( $depth + 1); // because it counts the first submenu as 0 $classes = array( 'sub-menu', ( $display_depth % 2 ? 'menu-odd' : 'menu-even' ), ( $display_depth >=2 ? 'sub-sub-menu' : '' ), 'menu-depth-' . $display_depth ); $class_names = implode( ' ', $classes ); // build html $output .= "\n" . $indent . '<ul class="' . $class_names . '">' . "\n"; } // add main/sub classes to li's and links function start_el( &$output, $item, $depth, $args ) { global $wp_query; $indent = ( $depth > 0 ? str_repeat( "\t", $depth ) : '' ); // code indent // depth dependent classes $depth_classes = array( ( $depth == 0 ? 'main-menu-item' : 'sub-menu-item' ), ( $depth >=2 ? 'sub-sub-menu-item' : '' ), ( $depth % 2 ? 'menu-item-odd' : 'menu-item-even' ), 'menu-item-depth-' . $depth ); $depth_class_names = esc_attr( implode( ' ', $depth_classes ) ); // passed classes $classes = empty( $item->classes ) ? array() : (array) $item->classes; $class_names = esc_attr( implode( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) ) ); // build html $output .= $indent . '<li id="nav-menu-item-'. $item->ID . '" class="' . $depth_class_names . ' ' . $class_names . '">'; // link attributes $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 ) .'"' : ''; $attributes .= ' class="menu-link ' . ( $depth > 0 ? 'sub-menu-link' : 'main-menu-link' ) . '"'; $item_output = sprintf( '%1$s<a%2$s>%3$s%4$s%5$s</a>%6$s', $args->before, $attributes, $args->link_before, apply_filters( 'the_title', $item->title, $item->ID ), $args->link_after, $args->after ); // build html $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args ); } }Tip: In this case, you could choose to extend Walker_Nav_Menu instead of Walker, and then you wouldn't need to define $db_fieldsmanually.
In order to utilize this custom walker class, you would call wp_nav_menu() (likely from within a theme file) and pass it a new instance of the custom Walker child class.
No comments:
Post a Comment