【问题标题】:Wordpress Nav Walker - Multilevel navigationWordpress Nav Walker - 多级导航
【发布时间】:2016-05-03 13:06:25
【问题描述】:

我需要有关在 Wordpress 网站中导航的帮助。我正在尝试让 Wordpress 以这种格式打印我的导航:

<ul data-menu="main" class="menu__level">
        <li class="menu__item"><a class="menu__link" data-submenu="submenu-1" href="#">Vegetables</a></li>
        <li class="menu__item"><a class="menu__link" data-submenu="submenu-2" href="#">Fruits</a></li>
        <li class="menu__item"><a class="menu__link" data-submenu="submenu-3" href="#">Grains</a></li>
        <li class="menu__item"><a class="menu__link" data-submenu="submenu-4" href="#">Mylk & Drinks</a></li>
      </ul>
      
<!-- Submenu 1 / Shown when user clicks the first list item (item with data-submenu="submenu-1") on data-menu="main" -->
      <ul data-menu="submenu-1" class="menu__level">
        <li class="menu__item"><a class="menu__link" href="#">Stalk Vegetables</a></li>
        <li class="menu__item"><a class="menu__link" href="#">Roots & Seeds</a></li>
        <li class="menu__item"><a class="menu__link" href="#">Cabbages</a></li>
        <li class="menu__item"><a class="menu__link" href="#">Salad Greens</a></li>
        <li class="menu__item"><a class="menu__link" href="#">Mushrooms</a></li>
        <li class="menu__item"><a class="menu__link" data-submenu="submenu-1-1" href="#">Sale %</a></li>
      </ul>
      
<!-- Submenu 2 / Shown when user clicks the second list item (item with data-submenu="submenu-2") on data-menu="main" -->
      <ul data-menu="submenu-2" class="menu__level">
        <li class="menu__item"><a class="menu__link" href="#">Citrus Fruits</a></li>
        <li class="menu__item"><a class="menu__link" href="#">Berries</a></li>
        <li class="menu__item"><a class="menu__link" data-submenu="submenu-2-1" href="#">Special Selection</a></li>
        <li class="menu__item"><a class="menu__link" href="#">Tropical Fruits</a></li>
        <li class="menu__item"><a class="menu__link" href="#">Melons</a></li>
      </ul>
      
<!-- Submenu 3 / Shown when user clicks the third list item (item with data-submenu="submenu-3") on data-menu="main" -->
      <ul data-menu="submenu-3" class="menu__level">
        <li class="menu__item"><a class="menu__link" href="#">Buckwheat</a></li>
        <li class="menu__item"><a class="menu__link" href="#">Millet</a></li>
        <li class="menu__item"><a class="menu__link" href="#">Quinoa</a></li>
        <li class="menu__item"><a class="menu__link" href="#">Wild Rice</a></li>
        <li class="menu__item"><a class="menu__link" href="#">Durum Wheat</a></li>
        <li class="menu__item"><a class="menu__link" data-submenu="submenu-3-1" href="#">Promo Packs</a></li>
      </ul>
      
<!-- Submenu 4 / Shown when user clicks the forth list item (item with data-submenu="submenu-4") on data-menu="main" -->
      <ul data-menu="submenu-4" class="menu__level">
        <li class="menu__item"><a class="menu__link" href="#">Grain Mylks</a></li>
        <li class="menu__item"><a class="menu__link" href="#">Seed Mylks</a></li>
        <li class="menu__item"><a class="menu__link" href="#">Nut Mylks</a></li>
        <li class="menu__item"><a class="menu__link" href="#">Nutri Drinks</a></li>
        <li class="menu__item"><a class="menu__link" data-submenu="submenu-4-1" href="#">Selection</a></li>
      </ul>

但我不知道如何将子项指定给特定的父项,然后使用 data-submenu 打印它们。

导航结构取自这里: http://tympanus.net/Blueprints/MultiLevelMenu/

谢谢!

更新:我想到了:用 php 获取导航数据然后用 Javascript 以正确的格式填充它会更容易或更干净吗?有谁知道这是否是更好的处理方法?

或者如何使用rest-api(我对这个很新,所以有必要将它用作小型网站项目的一部分)

【问题讨论】:

    标签: javascript php wordpress wordpress-theming wordpress-rest-api


    【解决方案1】:

    实际上,您可以将所有菜单数据(从某个位置)抓取到数组中并以您喜欢的任何方式输出。

    例如,你有这样的菜单结构:

    Menu_parent1_item
        Submenu_item_1
        Submenu_item_2
        Submenu_item_3
    Menu_parent2_item
        Submenu2_item_1
        Submenu2_item_2
        Submenu2_item_3
    Menu_parent3_item
        Submenu3_item_1
        Submenu3_item_2
        Submenu3_item_3
    

    把这段代码放在function.php中:

    function custom_menu_output( $theme_location ) {
        if ( ($theme_location) && ($locations = get_nav_menu_locations()) && isset($locations[$theme_location]) ) {
            $menu = get_term( $locations[$theme_location], 'nav_menu' );
            $menu_items = wp_get_nav_menu_items($menu->term_id);
    
            $menus = array();
    
            foreach( $menu_items as $menu_item ) {
                $pid = $menu_item->menu_item_parent ? $menu_item->menu_item_parent : 0;
    
                $menus[$pid][] = array(
                    'link' => $menu_item->url,
                    'title' => $menu_item->title,
                    'id' => $menu_item->ID,
                );
            }
    
            foreach($menus as $key => $menu) {
                if($key == 0)
                    echo '<ul data-menu="main" class="menu__level">';
                else
                    echo '<ul data-menu="submenu-'.$key.'" class="menu__level">';
                foreach($menu as $item) {
                    if(isset($menus[$item['id']]))
                        echo '<li class="menu__item"><a class="menu__link" data-submenu="submenu-'.$item['id'].'" href="'.$item['link'].'">'.$item['title'].'</a></li>';
                    else
                        echo '<li class="menu__item"><a class="menu__link" href="'.$item['link'].'">'.$item['title'].'</a></li>';
                }
                echo '</ul>';
            }
    
        } else {
            $menu_list = '<!-- no menu defined in location "'.$theme_location.'" -->';
        }
        echo $menu_list;
    }
    

    并在您的模板中像这样使用它:

    <?php custom_menu_output('menu_location_name_from_register_nav_menu'); ?>
    

    它会生成这样的 HTML(我是根据你的问题描述生成的):

    <ul data-menu="main" class="menu__level">
        <li class="menu__item"><a class="menu__link" data-submenu="submenu-717" href="http://yourdomain.tld/your_link/">Menu_parent1_item</a></li>
        <li class="menu__item"><a class="menu__link" data-submenu="submenu-720" href="http://yourdomain.tld/your_link/">Menu_parent2_item</a></li>
        <li class="menu__item"><a class="menu__link" data-submenu="submenu-725" href="http://yourdomain.tld/your_link/">Menu_parent3_item</a></li>
    </ul>
    
    <ul data-menu="submenu-717" class="menu__level">
        <li class="menu__item"><a class="menu__link" href="http://yourdomain.tld/your_link/">Submenu_item_1</a></li>
        <li class="menu__item"><a class="menu__link" href="http://yourdomain.tld/your_link/">Submenu_item_2</a></li>
        <li class="menu__item"><a class="menu__link" href="http://yourdomain.tld/your_link/">Submenu_item_3</a></li>
    </ul>
    
    <ul data-menu="submenu-720" class="menu__level">
        <li class="menu__item"><a class="menu__link" href="http://yourdomain.tld/your_link/">Submenu2_item_1</a></li>
        <li class="menu__item"><a class="menu__link" href="http://yourdomain.tld/your_link/">Submenu2_item_2</a></li>
        <li class="menu__item"><a class="menu__link" href="http://yourdomain.tld/your_link/">Submenu2_item_3</a></li>
    </ul>
    
    <ul data-menu="submenu-725" class="menu__level">
        <li class="menu__item"><a class="menu__link" href="http://yourdomain.tld/your_link/">Submenu2_item_1</a></li>
        <li class="menu__item"><a class="menu__link" href="http://yourdomain.tld/your_link/">Submenu2_item_2</a></li>
        <li class="menu__item"><a class="menu__link" href="http://yourdomain.tld/your_link/">Submenu2_item_3</a></li>
    </ul>
    

    您可以根据需要进一步自定义此代码。

    【讨论】:

    • 完美!正是我想要的。我错误地认为步行者课程是唯一的出路。谢谢!
    • 如果我在 wordpress 中有 3 级菜单,那么如何在具有子菜单的 li 项目上显示悬停菜单,请分享 css 或其他 sutffs。
    【解决方案2】:

    您可以使用 walker 类来更改 ul 和 li 结构。

    class themeslug_walker_nav_menu extends Walker_Nav_Menu {
    
    
            private $color_idx = 0;
    
            // add classes to ul sub-menus
            function start_lvl( &$output, $depth) {
                //p($output);
                // 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(
                    'sidebar-menu',
                    ( $display_depth % 2  ? 'menu-odd' : 'menu-even' ),
                    ( $display_depth >=2 ? 'sub-sub-menu' : '' ),
                    'level-' . $display_depth
                    );
                $class_names = implode( ' ', $classes );
    
                $back_btn = '';
                if($display_depth > 0){
    
                    /*$parent_label = '<li class="top custom-row">
                                        <a class="close-menu" href="#"><span class="parent_label"></span><i class="fa fa-close"></i></a>
                                      </li>';
    
                    $back_btn = '<li class="sidebar-item back no-children back'.$display_depth.'">
                                  <div class="inner">
                                    <a class="hit-area" href="#">Back</a>
                                    <i class="fa fa-chevron-left"></i>
                                  </div>
                                </li>';*/
                }
    
                // build html
                $incri = $this->color_idx-1;
                $output .= "\n" . $indent . '<ul class="menu__level" data-menu="submenu-'.$incri.'">' .$parent_label.$back_btn. "\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(
                    'sidebar-item',
                    ( $depth == 0 ? 'li0' : '' ),
                    ( $depth == 1 ? 'li1' : '' ),
                    ( $depth == 2 ? 'li2' : '' ),
                    ( $depth == 3 ? 'li3' : '' ),
                    /*( $depth % 2 ? 'menu-item-odd' : 'menu-item-even' ),
                    'menu-item-depth-' . $depth
                );*/
    
    
    
                if(in_array('menu-item-has-children',$item->classes)){
                    $has_children = 'data-has-children="1"';
                    $has_children_var = 1;
                    $depth_classes[] = 'has-children';
                } else{
                    $has_children_var = 0;
                    $depth_classes[] = 'no-children';
                }
    
    
                $li_attributes = 'data-level="'.$depth.'" data-title="'.apply_filters( 'the_title', $item->title, $item->ID ).'" '.$has_children;
    
    
    
                $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 class="menu__item">';
    
                // 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        ) .'"' : '';
                if($has_children_var == 1){
                    $attributes .= ' data-submenu="submenu-'.$this->color_idx.'"';
                } 
                $attributes .= ' class="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 ),
                    ($has_children_var == 1 ? $args->link_after : ''),
                    $args->after
                );
    
                // build html
                $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    
                if($has_children_var == 1){
                    $this->color_idx++;
                }
            }
    
        }
    

    但它没有提供将子菜单ul与父li分开的方法。

    否则所有像submenu-1, submenu-2这样的类都可以管理。

    尝试修改此代码。

    参考见本站Energy & Manpower

    点击页面右侧的菜单按钮时的右侧菜单也是以同样的方式构建的

    【讨论】:

    • 或者您必须从后端为每个 ul 创建单独的菜单,并通过 walker 类为它们分配类和数据属性
    • 这非常接近我想要做的事情。但要让特定的鼓膜蓝图菜单工作,这些子菜单必须分开。我已经试着把它放在你的代码示例中,但是这种结构有点滞后。但如果没有任何新的答案,我可能不得不对我的菜单结构使用不同的方法。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 2012-12-11
    相关资源
    最近更新 更多