如何修改WP walker以获取自定义下拉列表?

时间:2017-12-21 08:27:21

标签: php html wordpress wp-nav-walker

我试图制作非标准主导航菜单并坚持使用子菜单项,根据大多数教程和wordpress指南,walker类适用于简单的菜单类型,如:

<ul>
 <li><a>Menu Item</a></li>
 <li><a>Menu Item</a>
  <ul>
   <li><a>Submenu Item</a></li>
  </ul>
 </li>
</ul>

哪个不适合我的菜单结构:

<ul class="navbar-nav">
    <li class="nav-item">
        <a class="nav-link">
            <i class="nav-icons home_icon"></i>
            <p>Home</p>
        </a>
    </li>
    <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            <i class="nav-icons catalog_icon"></i>
            <p>Catalog</p>
        </a>
        <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
            <a class="dropdown-item">Catalog 1</a>
            <a class="dropdown-item">Catalog 2</a>
        </div>
    </li>
</ul>

我知道walker类形成了4个函数的菜单(start_lvl,start_el,end_el,end_lvl),但有没有任何教程或任何其他有关如何制作simillar的信息,或者有人可以提供代码示例来实现我的结果需要?我的菜单只包含1个子菜单级别。

1 个答案:

答案 0 :(得分:2)

这适用于Bootstrap导航菜单walker类,

if (!class_exists('BootstrapBasicMyWalkerNavMenu')) {
class BootstrapBasicMyWalkerNavMenu extends Walker_Nav_Menu
{


    //Overwrite display_element function to add has_children attribute. Not needed in >= Wordpress 3.4
    /**
     * @link https://gist.github.com/duanecilliers/1817371 copy from this url
     */
    function display_element($element, &$children_elements, $max_depth, $depth = 0, $args, &$output)
    {
        if (!$element)
            return;
        $id_field = $this->db_fields['id'];

        //display this element
        if (is_array($args[0]))
            $args[0]['has_children'] = !empty($children_elements[$element->$id_field]);
        else if (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;

        // descend only when the depth is right and there are childrens for this element
        if (($max_depth == 0 || $max_depth > $depth + 1) && isset($children_elements[$id])) {

            foreach ($children_elements[$id] as $child) {

                if (!isset($newlevel)) {
                    $newlevel = true;
                    //start the child delimiter
                    $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);
            }
            unset($children_elements[$id]);
        }

        if (isset($newlevel) && $newlevel) {
            //end the child delimiter
            $cb_args = array_merge(array(&$output, $depth), $args);
            call_user_func_array(array(&$this, 'end_lvl'), $cb_args);
        }

        //end this element
        $cb_args = array_merge(array(&$output, $element, $depth), $args);
        call_user_func_array(array(&$this, 'end_el'), $cb_args);
    }// display_element


    /**
     * @link https://gist.github.com/duanecilliers/1817371 copy from this url
     */
    public function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) 
    {
        if ((is_object($item) && $item->title == null) || (!is_object($item))) {
            return ;
        }

        $indent = ($depth) ? str_repeat("\t", $depth) : '';

        $li_attributes = '';
        $class_names = $value = '';

        $classes = empty($item->classes) ? array() : (array) $item->classes;
        //Add class and attribute to LI element that contains a submenu UL.
        if (is_object($args) && $args->has_children) {
            //$classes[] = 'dropdown';
            $li_attributes .= ' data-dropdown="dropdown"';
        }
        $classes[] = 'menu-item-' . $item->ID;
        //If we are on the current page, add the active class to that menu item.
        $classes[] = ($item->current) ? 'active' : '';

        //Make sure you still add all of the WordPress classes.
        $class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args));
        $class_names = ' class="' . esc_attr($class_names) . '"';

        $id = apply_filters('nav_menu_item_id', 'menu-item-' . $item->ID, $item, $args);
        $id = strlen($id) ? ' id="' . esc_attr($id) . '"' : '';

        $output .= $indent . '<li' . $id . $value . $class_names . $li_attributes . '>';

        //Add attributes to link element.
        $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 .= (is_object($args) && $args->has_children) ? ' class="dropdown-toggle" data-toggle="dropdown"' : '';

        $item_output = (is_object($args)) ? $args->before : '';
        $item_output .= '<a' . $attributes . '>';
        $item_output .= (is_object($args) ? $args->link_before : '') . apply_filters('the_title', $item->title, $item->ID) . (is_object($args) ? $args->link_after : '');
        $item_output .= (is_object($args) && $args->has_children) ? ' <span class="caret"></span> ' : '';
        $item_output .= '</a>';
        $item_output .= (is_object($args) ? $args->after : '');

        $output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
    }// start_el


    public function start_lvl(&$output, $depth = 0, $args = array()) 
    {
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indent<ul class=\"sub-menu dropdown-menu\">\n";
    }


}
}

如何使用它,

 <?php wp_nav_menu(array('theme_location' => 'your-menu-location', 'container' => false, 'menu_class' => 'nav navbar-nav', 'walker' => new BootstrapBasicMyWalkerNavMenu())); ?> 

希望这会对你有所帮助。

欲了解更多信息,