diff --git a/CHANGELOG.md b/CHANGELOG.md index 70bf9b6..598780b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ ### HEAD +* Simplify nav walker and support 3rd level dropdowns * Update to Bootstrap 2.1.1, jQuery 1.8.1, Modernizr 2.6.2 * Add bundled docs * Update all templates to use [PHP Alternative Syntax](http://php.net/manual/en/control-structures.alternative-syntax.php) diff --git a/lib/cleanup.php b/lib/cleanup.php index 790a54e..ad53143 100644 --- a/lib/cleanup.php +++ b/lib/cleanup.php @@ -407,17 +407,6 @@ function roots_excerpt_more($more) { add_filter('excerpt_length', 'roots_excerpt_length'); add_filter('excerpt_more', 'roots_excerpt_more'); -/** - * Replace various active menu class names with "active" - */ -function roots_wp_nav_menu($text) { - $text = preg_replace('/(current(-menu-|[-_]page[-_])(item|parent|ancestor))/', 'active', $text); - $text = preg_replace('/( active){2,}/', ' active', $text); - return $text; -} - -add_filter('wp_nav_menu', 'roots_wp_nav_menu'); - /** * Cleaner walker for wp_nav_menu() * @@ -439,88 +428,56 @@ class Roots_Nav_Walker extends Walker_Nav_Menu { } function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) { - global $wp_query; - $indent = ($depth) ? str_repeat("\t", $depth) : ''; + $item_html = ''; + parent::start_el($item_html, $item, $depth, $args); - $slug = sanitize_title($item->title); - $id = 'menu-' . $slug; - - $class_names = $value = ''; - $li_attributes = ''; - $classes = empty($item->classes) ? array() : (array) $item->classes; - - $classes = array_filter($classes, array(&$this, 'check_current')); - - if ($args->has_children) { - $classes[] = 'dropdown'; - $li_attributes .= ' data-dropdown="dropdown"'; + if ($item->is_dropdown && ($depth === 0)) { + $item_html = str_replace('', ' ', $item_html); } - if ($custom_classes = get_post_meta($item->ID, '_menu_item_classes', true)) { - foreach ($custom_classes as $custom_class) { - $classes[] = $custom_class; - } - } - - $class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args)); - $class_names = $class_names ? ' class="' . $id . ' ' . esc_attr($class_names) . '"' : ' class="' . $id . '"'; - - $output .= $indent . ''; - - $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 .= ($args->has_children) ? ' class="dropdown-toggle" data-toggle="dropdown" data-target="#"' : ''; - - $item_output = $args->before; - $item_output .= ''; - $item_output .= $args->link_before . apply_filters('the_title', $item->title, $item->ID) . $args->link_after; - $item_output .= ($args->has_children) ? ' ' : ''; - $item_output .= ''; - $item_output .= $args->after; - - $output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args); + $output .= $item_html; } function display_element($element, &$children_elements, $max_depth, $depth = 0, $args, &$output) { - if (!$element) { return; } + $element->is_dropdown = !empty($children_elements[$element->ID]); - $id_field = $this->db_fields['id']; - - if (is_array($args[0])) { - $args[0]['has_children'] = !empty($children_elements[$element->$id_field]); - } elseif (is_object($args[0])) { - $args[0]->has_children = !empty($children_elements[$element->$id_field]); - } - - $cb_args = array_merge(array(&$output, $element, $depth), $args); - call_user_func_array(array(&$this, 'start_el'), $cb_args); - - $id = $element->$id_field; - - if (($max_depth == 0 || $max_depth > $depth+1) && isset($children_elements[$id])) { - foreach ($children_elements[$id] as $child) { - if (!isset($newlevel)) { - $newlevel = true; - $cb_args = array_merge(array(&$output, $depth), $args); - call_user_func_array(array(&$this, 'start_lvl'), $cb_args); - } - $this->display_element($child, $children_elements, $max_depth, $depth + 1, $args, $output); + if ($element->is_dropdown) { + if ($depth === 0) { + $element->classes[] = 'dropdown'; + } elseif ($depth === 1) { + $element->classes[] = 'dropdown-submenu'; } - unset($children_elements[$id]); } - if (isset($newlevel) && $newlevel) { - $cb_args = array_merge(array(&$output, $depth), $args); - call_user_func_array(array(&$this, 'end_lvl'), $cb_args); - } - - $cb_args = array_merge(array(&$output, $element, $depth), $args); - call_user_func_array(array(&$this, 'end_el'), $cb_args); + parent::display_element($element, $children_elements, $max_depth, $depth, $args, $output); } } +/** + * Remove the id="" on nav menu items + * Return 'menu-slug' for nav menu classes + */ +function roots_nav_menu_css_class($classes, $item) { + $slug = sanitize_title($item->title); + $classes = preg_replace('/(current(-menu-|[-_]page[-_])(item|parent|ancestor))/', 'active', $classes); + $classes = preg_replace('/((menu|page)[-_\w+]+)+/', '', $classes); + + $classes[] = 'menu-' . $slug; + + $classes = array_unique($classes); + + return array_filter($classes, 'is_element_empty'); +} + +function is_element_empty($element) { + $element = trim($element); + return empty($element) ? false : true; +} + +add_filter('nav_menu_css_class', 'roots_nav_menu_css_class', 10, 2); +add_filter('nav_menu_item_id', '__return_null'); + /** * Clean up wp_nav_menu_args * @@ -534,9 +491,8 @@ function roots_nav_menu_args($args = '') { $roots_nav_menu_args['items_wrap'] = '
    %3$s
'; } - // Bootstrap's navbar doesn't support multi-level dropdowns if (current_theme_supports('bootstrap-top-navbar')) { - $roots_nav_menu_args['depth'] = 2; + $roots_nav_menu_args['depth'] = 3; } if (!$args['walker']) {