【问题标题】:wp_nav_menu change sub-menu class name?wp_nav_menu 更改子菜单类名?
【发布时间】:2011-06-29 10:07:00
【问题描述】:

有没有办法将 WordPress 自己生成的子 <ul class="sub-menu"> 更改为自定义类名?

我知道父 <ul>,您可以使用 'menu_class' => 'newname' 删除或更改名称。

我找不到答案。试了'submenu_class' => 'customname'。对我来说这似乎是合乎逻辑的,但显然这是不正确的。

有什么想法吗?

【问题讨论】:

    标签: wordpress


    【解决方案1】:

    对此没有选项,但您可以扩展 WordPress 用来创建菜单 HTML 的“walker”对象。只需要重写一种方法:

    class My_Walker_Nav_Menu extends Walker_Nav_Menu {
      function start_lvl(&$output, $depth) {
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indent<ul class=\"my-sub-menu\">\n";
      }
    }
    

    然后,您只需将 walker 的实例作为参数传递给 wp_nav_menu,如下所示:

    'walker' => new My_Walker_Nav_Menu()
    

    【讨论】:

    • 我会先检查 $depth 是否正确。如果某些广告比自定义菜单更上一层楼,您不希望菜单混乱
    • 我认为我是一个工具,但我似乎无法让它发挥作用!我在functions.php 文件中插入了代码的class 部分,第二部分被引用为wp_nav_menu()$defaults 数组的一部分。这是正确的吗?
    • @Richard M 你知道这个调试错误是否可以修复吗?我尝试使用下面的字符串,但它导致了问题。我怎样才能编辑你上面的答案以符合这个标准? PHP 严格标准:My_Walker_Nav_Menu::start_lvl() 的声明应该与 Walker_Nav_Menu::start_lvl(&$output, $depth = 0, $args = Array) 兼容
    • @Drai 我也收到了这个警告,并通过这个小调整解决了这个问题。 class My_Walker_Nav_Menu extends Walker_Nav_Menu { function start_lvl(&amp;$output, $depth = 0, $args = Array() ) { $indent = str_repeat("\t", $depth); $output .= "\n$indent&lt;ul class=\"mp-level\"&gt;\n"; } }
    • 请看我的回答:stackoverflow.com/a/44666092/1694902。也许在编写最佳答案时该资源不可用,但我认为这是实现所要求的更清洁的方式。
    【解决方案2】:

    这是 Richard 所做的更新,它添加了“深度”指示器。输出为level-0、level-1、level-2等。

    class UL_Class_Walker extends Walker_Nav_Menu {
      function start_lvl(&$output, $depth) {
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indent<ul class=\"level-".$depth."\">\n";
      }
    }
    

    【讨论】:

    • 有没有办法给这个巢 UL 的孩子添加一个类名?
    • 当然!您要添加的类名的示例是什么?
    • 除了上面显示的内容(向嵌套的 UL 添加一个类)之外,我还想将类“nav-main-sub-item”添加到嵌套的 LI。如上所示,我已经想出了如何将“nav-main-sub-item”类添加到主级别 LI 和二级 UL 中。但不能将它们与嵌套 LI 上的类联系在一起。如果您想查看它,我实际上在这里有一个悬而未决的问题:stackoverflow.com/questions/23941129/…
    • 这是我需要的答案。通过添加深度,可以独立设置不同级别的样式。有很多关于walker 菜单的复杂代码,但这使得设置Underscores 导航变得容易。对于像我一样困惑的其他人-这可能就是您所需要的。要了解更多信息,请阅读以下内容:code.tutsplus.com/tutorials/…
    【解决方案3】:

    就像往常一样,在向网站写东西之前找了很长时间之后,在我在这里发布一分钟后,我找到了我的解决方案。

    它以为我会在这里分享它,以便其他人可以找到它。

    //Add "parent" class to pages with subpages, change submenu class name, add depth class
    
        class Prio_Walker extends Walker_Nav_Menu {
        function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ){
            $GLOBALS['dd_children'] = ( isset($children_elements[$element->ID]) )? 1:0;
            $GLOBALS['dd_depth'] = (int) $depth;
            parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
        }
    
         function start_lvl(&$output, $depth) {
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indent<ul class=\"children level-".$depth."\">\n";
      }
    }
    
    add_filter('nav_menu_css_class','add_parent_css',10,2);
    function  add_parent_css($classes, $item){
         global  $dd_depth, $dd_children;
         $classes[] = 'depth'.$dd_depth;
         if($dd_children)
             $classes[] = 'parent';
        return $classes;
    }
    
    //Add class to parent pages to show they have subpages (only for automatic wp_nav_menu)
    
    function add_parent_class( $css_class, $page, $depth, $args )
    {
       if ( ! empty( $args['has_children'] ) )
           $css_class[] = 'parent';
       return $css_class;
    }
    add_filter( 'page_css_class', 'add_parent_class', 10, 4 );
    

    这是我找到解决方案的地方: Solution in WordPress support forum

    【讨论】:

      【解决方案4】:

      在上面我需要一个小改动,但我无法做到这一点, 您的输出将如下所示

      <ul>
      <li id="menu-item-13" class="depth0 parent"><a href="#">About Us</a>
      <ul class="children level-0">
          <li id="menu-item-17" class="depth1"><a href="#">Sample Page</a></li>
          <li id="menu-item-16" class="depth1"><a href="#">About Us</a></li>
      </ul>
      </li>
      </ul> 
      

      我在找什么

      <ul>
      <li id="menu-item-13" class="depth0"><a class="parent" href="#">About Us</a>
      <ul class="children level-0">
          <li id="menu-item-17" class="depth1"><a href="#">Sample Page</a></li>
          <li id="menu-item-16" class="depth1"><a href="#">About Us</a></li>
      </ul>
      </li>
      </ul> 
      

      在上面我已经将父类放在&lt;li id="menu-item-13" class="depth0"&gt;&lt;a class="parent" href="#"&gt;About Us&lt;/a&gt;的父锚链接中

      【讨论】:

        【解决方案5】:

        选项的选择。

        1. 将“echo”参数切换为 false,您可以替换类名。
            echo str_replace('sub-menu', 'menu menu_sub', wp_nav_menu( array(
                'echo' => false,
                'theme_location' => 'sidebar-menu',
                'items_wrap' => '<ul class="menu menu_sidebar">%3$s</ul>' 
              ) )
            );
        
        1. 从 WP 4.8 开始,我们可以使用 nav_menu_submenu_css_class 过滤器。
        add_filter( 'nav_menu_submenu_css_class', 'my_custom_submenu_classnames', 10, 3 );
        /**
         * Filters the CSS class(es) applied to a menu list element.
         *
         * @param string[] $classes Array of the CSS classes that are applied to the menu `<ul>` element.
         * @param stdClass $args    An object of `wp_nav_menu()` arguments.
         * @param int      $depth   Depth of menu item. Used for padding.
         * @return string[]
         */
        function my_custom_submenu_classnames( $classes, $args, $depth ) {
            // Here we can additionally use menu arguments.
            if ( 'header-menu' === $args->theme_location ) {
                $default_class_name_key = array_search( 'sub-menu', $classes );
                if ( false !== $default_class_name_key ) {
                    unset( $classes[ $default_class_name_key ] );
                }
                $classes[] = 'header-submenu';
                $classes[] = "depth-{$depth}";
            }
        
            return $classes;
        }
        
        1. 自定义菜单漫游器:
        class My_Nav_Menu_Walker extends Walker_Nav_Menu {
            /**
             * Starts the list before the elements are added.
             *
             * @see Walker::start_lvl()
             *
             * @param string   $output Used to append additional content (passed by reference).
             * @param int      $depth  Depth of menu item. Used for padding.
             * @param stdClass $args   An object of wp_nav_menu() arguments.
             */
            public function start_lvl( &$output, $depth = 0, $args = null ) {
                if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) {
                    $t = '';
                    $n = '';
                } else {
                    $t = "\t";
                    $n = "\n";
                }
                $indent = str_repeat( $t, $depth );
        
                // ! You default class names.
                $classes = array( 'sub-menu', 'my-class' );
                // ! Example of using arguments.
                if ( 'header-menu' === $args->theme_location ) {
                    $default_class_name_key = array_search( 'sub-menu', $classes );
                    if ( false !== $default_class_name_key ) {
                        unset( $classes[ $default_class_name_key ] );
                    }
                    $classes[] = 'header-submenu';
                    $classes[] = "depth-{$depth}";
                }
        
                /**
                 * Filters the CSS class(es) applied to a menu list element.
                 *
                 * @since 4.8.0
                 *
                 * @param string[] $classes Array of the CSS classes that are applied to the menu `<ul>` element.
                 * @param stdClass $args    An object of `wp_nav_menu()` arguments.
                 * @param int      $depth   Depth of menu item. Used for padding.
                 */
                $class_names = implode( ' ', apply_filters( 'nav_menu_submenu_css_class', $classes, $args, $depth ) );
                $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
        
                $output .= "{$n}{$indent}<ul{$class_names}>{$n}";
            }
        }
        

        仍然需要使用自定义 walker 包含文件并将其指向菜单:

        wp_nav_menu(
            array(
                'theme_location' => 'header-menu',
                'walker'         => new My_Nav_Menu_Walker()
            )
        );
        

        【讨论】:

        • 它不起作用。它仍然只是“子菜单”。没有变化。
        • 'echo' => false,这很重要!
        • 轻松最优雅的解决方案。
        【解决方案6】:

        我建议将您的 cutomclass css 类名替换为子菜单。 使用查找和替换:即。查找:.customclass 替换为 .sub-menu, 对我有用。

        【讨论】:

          【解决方案7】:

          我不得不改变:

          function start_lvl(&amp;$output, $depth)

          到:

          function start_lvl( &amp;$output, $depth = 0, $args = array() )

          因为我遇到了不兼容错误:

          Strict Standards: Declaration of My_Walker_Nav_Menu::start_lvl() should be compatible with Walker_Nav_Menu::start_lvl(&amp;$output, $depth = 0, $args = Array)

          【讨论】:

            【解决方案8】:

            要更改默认的“子菜单”类名,有一个简单的方法。 您可以在 wordpress 文件中更改它。

            位置:www/project_name/wp-includes/nav-menu-template.php。

            打开这个文件,在第 49 行,用您的自定义类更改子菜单类的名称。

            或者您也可以在子菜单旁边添加自定义类。

            完成。

            它对我有用。我使用了 wordpress-4.4.1。

            【讨论】:

            • 您的答案仅在 WordPress 更新其核心文件之前有效。如果 WordPress 发布的更新更改了您操作的文件,那么您的更改将被删除。最好按照上面的建议创建一个 Walker Nav。永远不要修改核心文件是一个很好的经验法则,因为它们会随着核心更新而改变。
            【解决方案9】:

            这可能对你有用

            如何为菜单项添加父类

            function wpdocs_add_menu_parent_class( $items ) {
            $parents = array();
            
            // Collect menu items with parents.
            foreach ( $items as $item ) {
                if ( $item->menu_item_parent && $item->menu_item_parent > 0 ) {
                    $parents[] = $item->menu_item_parent;
                }
            }
            
            // Add class.
            foreach ( $items as $item ) {
                if ( in_array( $item->ID, $parents ) ) {
                    $item->classes[] = 'menu-parent-item';
                }
            }
            return $items;
             }
            add_filter( 'wp_nav_menu_objects', 'wpdocs_add_menu_parent_class' );
            
            /**
             * Add a parent CSS class for nav menu items.
             * @param array  $items The menu items, sorted by each menu item's menu order.
             * @return array (maybe) modified parent CSS class.
            */
            

            向菜单项添加条件类

            function wpdocs_special_nav_class( $classes, $item ) {
                if ( is_single() && 'Blog' == $item->title ) {
                // Notice you can change the conditional from is_single() and $item->title
                $classes[] = "special-class";
            }
            return $classes;
            }
            add_filter( 'nav_menu_css_class' , 'wpdocs_special_nav_class' , 10, 2 );
            

            供参考:click me

            【讨论】:

              【解决方案10】:

              您可以使用 WordPress preg_replace 过滤器(在您的主题 functions.php 文件中) 示例:

              function new_submenu_class($menu) {    
                  $menu = preg_replace('/ class="sub-menu"/','/ class="yourclass" /',$menu);        
                  return $menu;      
              }
              
              add_filter('wp_nav_menu','new_submenu_class'); 
              

              【讨论】:

              • 谢谢!我认为这种方法要容易得多
              【解决方案11】:

              这是一个老问题,我不确定我要提到的解决方案在你问的时候是否可用,但我认为值得一提。您可以通过向nav_menu_submenu_css_class 添加过滤器来实现您想要的。请参阅下面的示例 - 您可以将 my-new-submenu-class 替换为您想要的类:

              function my_nav_menu_submenu_css_class( $classes ) {
                  $classes[] = 'my-new-submenu-class';
                  return $classes;
              }
              add_filter( 'nav_menu_submenu_css_class', 'my_nav_menu_submenu_css_class' );
              

              【讨论】:

                【解决方案12】:

                你可以只用一个钩子

                add_filter( 'nav_menu_submenu_css_class', 'some_function', 10, 3 );
                function some_function( $classes, $args, $depth ){
                    foreach ( $classes as $key => $class ) {
                    if ( $class == 'sub-menu' ) {
                        $classes[ $key ] = 'my-sub-menu';
                    }
                }
                
                return $classes;
                }
                

                在哪里

                $classes(array) - The CSS classes that are applied to the menu <ul> element.
                $args(stdClass) - An object of wp_nav_menu() arguments.
                $depth(int) - Depth of menu item. Used for padding.
                

                【讨论】:

                • Artemiy Egorov 请你把所有代码写在function.php里面谢谢!
                • 当然。如果您只想将类添加到子菜单,您可以使用:add_filter( 'nav_menu_submenu_css_class', 'some_function', 10, 3 ); function some_function( $classes, $args, $depth ){ foreach ( $classes as $key =&gt; $class ) { if ( $class == 'sub-menu' ) { $classes[ $key ] = 'my-sub-menu'; } } return $classes; }
                【解决方案13】:

                您不需要扩展 Walker。这样就可以了:

                function overrideSubmenuClasses( $classes ) {
                    $classes[] = 'myclass1';
                    $classes[] = 'myclass2';
                
                    return $classes;
                }
                add_action('nav_menu_submenu_css_class', 'overrideSubmenuClasses');
                

                【讨论】:

                • 这对我很有用。请记住,此函数会替换所有当前类,因此如果您已经在使用某个类,请不要忘记将其包含在数组中。
                • 好点@Jake,我已经更新它以追加新类而不是替换现有类。
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-07-06
                • 1970-01-01
                • 1970-01-01
                • 2019-08-16
                • 2011-12-28
                • 1970-01-01
                相关资源
                最近更新 更多