问题描述

(主持人注意:最初标题为 「wp_nav_menu Ancestor class without children in navigation structure」)

我的标题中有一个 wp_nav_menu,其中有三个页面。当我在这些页面之一时,菜单中包含该页面的 li 将获得.current_page_item 类。这三个页面都有模板,这些模板包含自定义查询以获取特定内容类型的所有帖子。实际上,这个顶级页面的”children” 实际上并不是孩子,它们只是一个使用模板与顶级页面相关联的内容类型。

当用户正在浏览特定帖子类型的单个页面时,我想要顶级菜单项目,以获取'current-ancestor'类别,再次与模板文件中的自定义查询中的该页面相关联。

希望有道理 – 如果不是,让我知道我在哪里失去了你!非常感谢任何帮助。

– 已编辑细节:例如,我有一个名为 Workshops 的静态页面正在使用模板。它的 s 子是车间。该模板具有自定义的 get_posts 功能,并在其中循环,它拉出并显示称为工作室的自定义内容类型的所有帖子。如果我点击这些研讨会的其中一个题目,我将被带到该内容的全部内容。自定义帖子类型的永久链接结构设置为研讨会/ postname,以便用户看到,这些内容是 Workshops 页面的子代,实际上它们都是一个内容类型,但与该页面无关。这是我需要在菜单中有效关闭的差距,当浏览’workshop’ 类型的内容时突出显示’Workshops’ 菜单项。

再次,希望是有道理的,我想我在一段话中说’workshop’ 高达 20 倍!

最佳解决方案

有一个更简单的解决方案。忘记为每个帖子类型创建页面,以便您可以使用导航项目,因为您已经了解到,WP 无法识别您正在浏览的自定义类型与该页面相关。

而应在 Appearance-> 菜单中创建一个自定义链接。只需将 URL 返回您的自定义类型并给它一个标签,然后按 「添加到菜单」 。

http://example.com/workshops/

或 non-pretty-permalinks:

http://example.com/?post_type=workshops

只需创建一个导航按钮即可显示该自定义帖子类型的所有帖子,并且当您点击该导航项目时,还会添加 current-menu-item 类 – 但是它不会在除此之外的任何 URL 上添加导航类一

然后,一旦创建,进入新项目的配置,并在”Title Attribute” 字段中输入自定义帖子类型的块 (您也可以使用描述字段,但默认情况下,该属性隐藏在管理屏幕选项中) 。

现在,您需要钩住 nav_menu_css_class 过滤器 (为每个导航项目被触发),并检查正在查看的内容是否是您的自定义导航项目中指示的帖子类型:

add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2 );
function current_type_nav_class($classes, $item) {
    $post_type = get_query_var('post_type');
    if ($item->attr_title != '' && $item->attr_title == $post_type) {
        array_push($classes, 'current-menu-item');
    };
    return $classes;
}

在这种情况下,我们将检查 「标题属性」 字段内容是否为空,并且与当前正在查询的 post_type 匹配。如果是,我们将 current-menu-item 类添加到其类数组中,然后返回修改后的数组。

您可以将其修改为简单地匹配导航项目的标题,但是如果由于某种原因您想要对导航项目进行标题,那么使用 「标题属性」 或 「描述」 字段,可以使用 「标题属性」 或 「描述」 字段来标记该导航项目。

现在任何时候您都可以查看与导航菜单项匹配的帖子类型的单个项目 (或者甚至可能是归档列表),该项目将被赋予 CSS 类别 current-menu-item,以便您的突出显示工作。

不需要页面或页面模板;-) URL 查询负责获取正确的帖子。您的循环模板负责显示查询输出。该函数负责识别所显示的内容并添加 CSS 类。

奖金

您甚至可以使用 wp_update_nav_menu_item 自动执行该过程,方法是自动生成所有帖子类型的菜单项。对于这个例子,您需要首先检索要添加到此项目的导航菜单的 $menu_id

$types = get_post_types( array( 'exclude_from_search' => false, '_builtin' => false  ), 'objects' );
foreach ($types as $type) {
    wp_update_nav_menu_item( $menu_id, 0, array(
        'menu-item-type' => 'custom',
        'menu-item-title' => $type->labels->name,
        'menu-item-url' => get_bloginfo('url') . '/?post_type=' . $type->rewrite['slug'],
        'menu-item-attr-title' => $type->rewrite['slug'],
        'menu-item-status' => 'publish'
        )
    );
}

次佳解决方案

而不是使用

$post_type = get_query_var(‘post_type’);

你可能想尝试:

$post_type = get_post_type();

由于没有在查询 var 中设置 post 类型。这是”post” 的默认 post_type 的情况,因此,如果要突出显示从列表页面列出的帖子,则需要使用此选项. get_very_var() 只返回一个不自定义的帖子类型的空字符串。

add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2 );
function current_type_nav_class($classes, $item) {
    $post_type = get_post_type();
    if ($item->attr_title != '' && $item->attr_title == $post_type) {
        array_push($classes, 'current-menu-item');
    };
    return $classes;
}

参考文献

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