问题描述

我正在为 wp_nav_menu 编写一个自定义的 walker 类,并希望能够指定 li 是否包含子菜单。所以我想要我的标记是:

<li class="has_children [other-wordpress-classes]">
    <a class="parent-link">Some item</a>
    <ul class="sub-menu">

我知道如何添加和删除课程,我只是找不到任何东西告诉我,如果当前项目有子项目。

有任何想法吗?

提前致谢。

最佳解决方案

start_el()应该在 $args 参数中获取此信息,但是如果 $args 是一个数组,则 WordPress 只会填写此信息,而对于自定义导航菜单则是 WordPress 的一个对象。这在 a Trac ticket 中报道。但是没有问题,您可以自己填写,如果您还可以在自定义步行者中覆盖 display_element()方法 (因为这是访问子元素数组最简单的地方):

class WPSE16818_Walker extends Walker_Nav_Menu
{
    function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output )
    {
        $id_field = $this->db_fields['id'];
        if ( is_object( $args[0] ) ) {
            $args[0]->has_children = ! empty( $children_elements[$element->$id_field] );
        }
        return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
    }

    function start_el( &$output, $item, $depth, $args ) {
        if ( $args->has_children ) {
            // ...
        }
    }

次佳解决方案

更新:从 WordPress 3.7(2013 年 10 月) 开始,添加 CSS 类以在主题菜单中指示子菜单项和页面 – 无需使用自定义步行器,因为它在 WordPress 核心中处理。

CSS 类名为 menu-item-has-childrenpage_item_has_children


对于任何人匆忙的完整解决方案 (信用于 Jan Fabry 之前的答案),请参阅下面的完整实现。

输出主题模板中的导航:

wp_nav_menu( array(
    'theme_location' => 'navigation-primary',
    'container' => false,
    'container_class' => '',
    'container_id' => '',
    'menu_class' => '',
    'menu_id' => '',
    'walker' => new Selective_Walker(),
    'depth' => 2
    )
);

然后,在主题的 functions.php 中包含以下内容:

class Selective_Walker extends Walker_Nav_Menu {
    function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
        $id_field = $this->db_fields['id'];

        if ( is_object( $args[0] ) ) {
            $args[0]->has_children = !empty( $children_elements[$element->$id_field] );
        }

        return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
    }

    function start_el( &$output, $item, $depth, $args ) {
        if ( $args->has_children ) {
            $item->classes[] = 'has_children';
        }

        parent::start_el(&$output, $item, $depth, $args);
    }
}

生成的 HTML 输出将类似于以下内容:

<ul>
    <li><a href="#">Home</a></li>
    <li class="has_children"><a href="#">About</a>
        <ul class="sub-menu">
            <li><a href="#">Our Mission</a></li>
        </ul>
    </li>
    <li><a href="#">Services</a></li>
    <li class="has_children"><a href="#">Products</a>
        <ul class="sub-menu">
            <li><a href="#">Lorem Ipsum</a></li>
            <li><a href="#">Lorem Ipsum</a></li>
        </ul>
    </li>
    <li><a href="#">Contact Us</a></li>
</ul>

有关使用 WordPress’walker 类的更多信息,请参阅 Understanding the Walker Class

请享用!

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。