是否突出显示导航结构中没有子项的祖先类wp_NAV_MENU()?

时间:2010-10-18 作者:Gavin

(Moderators note: 最初的标题是“wp\\U nav\\U菜单祖先类,导航结构中没有子类”)

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

我想让顶级菜单项\'current-ancestor\' 当用户浏览特定帖子类型的单个页面时,再次初始化,该页面仅在模板文件中的自定义查询中与该页面关联。

希望这有意义-如果没有,请告诉我我在哪里失去了你!非常感谢您的帮助。

--具体编辑:例如,我有一个名为Workshops的静态页面,该页面使用模板。它的鼻涕虫是车间。模板中有一个自定义的get\\u posts函数和循环,它可以提取和显示名为workshop的自定义内容类型的所有帖子。如果我点击其中一个研讨会的标题,我就会看到该内容的全部内容。自定义帖子类型的permalink结构设置为workshops/postname,因此用户可以看到,这些内容是workshops页面的子内容,而实际上它们都是一种内容类型,但与页面无关。我需要有效地缩小菜单中的差距,在浏览“workshop”类型的内容时突出显示“workshop”菜单项。

同样,希望这是有意义的,我想我在一段话中说了20多次“研讨会”!

7 个回复
最合适的回答,由SO网友:somatic 整理而成

有一个更简单的解决方案。忘记为每种帖子类型创建页面,这样您就可以拥有导航项目,因为正如您所了解的,WP无法识别您正在浏览的自定义类型与该页面相关。

相反,请在外观->菜单中创建自定义链接。只需输入将返回自定义类型的URL并给它一个标签,然后按“添加到菜单”。

http://example.com/workshops/
或不漂亮的永久链接:

http://example.com/?post_type=workshops
仅此一项就可以创建一个nav按钮,该按钮将显示具有该自定义帖子类型的所有帖子,并在您单击该nav项目时添加当前菜单项类,但它还不会在除此之外的任何URL上添加nav类

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

现在,你需要钩住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;
}
在本例中,我们将检查Title属性字段内容是否为空,以及它们是否与正在查询的当前post_类型匹配。如果是这样,我们将当前菜单项类添加到其类数组中,然后返回修改后的数组。

您可以将其修改为仅与导航项目的标题匹配,但如果出于某种原因,您希望以不同于post类型的普通slug的方式对导航项目进行标题,则使用title属性或Description字段可以提供这种灵活性。

现在,每当您查看与nav菜单项匹配的post类型的单个项目(甚至可能是存档列表)时,该项目都将被赋予CSS类当前菜单项,以便突出显示。

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

BONUS

您甚至可以使用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\'
        )
    );
}

SO网友:Eric

而不是使用

$post\\u type=get\\u query\\u var(\'post\\u type\');

您可能想尝试:

$post\\u type=get\\u post\\u type();

由于有时在查询变量中未设置post类型。这是默认post\\u类型“post”的情况,因此如果要突出显示从列表页面列出的帖子,则需要使用此选项。get\\u very\\u var()只为非自定义的post类型返回一个空字符串。

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;
}

SO网友:tzeldin88

@身体的-那太棒了!我对您的代码进行了一些修改,以便它也适用于特定的分类法(我仅对相关的post\\u类型使用)。其思想是使用菜单项的Title属性存储post\\u类型的名称和分类法的名称,用分号分隔,然后由函数分解。

add_filter(\'nav_menu_css_class\', \'current_type_nav_class\', 10, 2 );
function current_type_nav_class($classes, $item) {

    # get Query Vars
    $post_type = get_query_var(\'post_type\');  
    $taxonomy = get_query_var(\'taxonomy\');

    # get and parse Title attribute of Menu item
    $title = $item->attr_title; // menu item Title attribute, as post_type;taxonomy
    $title_array = explode(";", $title);
    $title_posttype = $title_array[0];
    $title_taxonomy = $title_array[1];

    # add class if needed
    if ($title != \'\' && ($title_posttype == $post_type || $title_taxonomy == $taxonomy)) {
        array_push($classes, \'current-menu-item\');
    };
    return $classes;
}

SO网友:Temo

如果您想使用wp\\U list\\U页面,这里是我的解决方案。

将此添加到函数中。php

add_filter(\'page_css_class\', \'my_page_css_class\', 10, 2);
function my_page_css_class($css_class, $page){
    $post_type = get_post_type();
    if($post_type != "page"){
        $parent_page = get_option(\'page_for_custom_post_type-\'.$post_type);
        if($page->ID == $parent_page)
            $css_class[] = \'current_page_parent\';
    }
    return $css_class;
}
现在只需在wp\\u options表中添加一个新行option_name 属于page_for_custom_post_type-xxxx 和aoption_value 使用page-ID 你想连接。

也许您认识到已经有一个选项名为page_for_posts. 如果你只有1个自定义帖子类型,你可以将你的页面设置为/wp admin/options-reading。下拉菜单和导航中的php将正确设置当前的\\u页面。

我认为wordpress core应该扩展这一部分,为注册的每种帖子类型提供一个下拉列表。

SO网友:Steve

我决定继续使用页面,并将页面模板名称用作nav项上的类。这使我能够避免混淆title属性,我不喜欢其他一些解决方案。

add_filter(\'nav_menu_css_class\', \'mbudm_add_page_type_to_menu\', 10, 2 );
//If a menu item is a page then add the template name to it as a css class 
function mbudm_add_page_type_to_menu($classes, $item) {
    if($item->object == \'page\'){
        $template_name = get_post_meta( $item->object_id, \'_wp_page_template\', true );
        $new_class =str_replace(".php","",$template_name);
        array_push($classes, $new_class);
        return $classes;
    }   
}
我还将body类添加到header中。php

<body <?php body_class(); ?>>
最后,此解决方案需要一些额外的css来将选定/活动状态应用于导航菜单项。我使用它将与页面相关的分类法存档和自定义帖子类型显示为此页面的子级:

/* selected states - include sub pages for anything related to products */
#nav-main li.current-menu-item a,
body.single-mbudm_product #nav-main li.lp_products a,
body.tax-mbudm_product_category #nav-main li.lp_products a,
#nav-main li.current_page_parent a{color:#c00;}

SO网友:user8899

@体细胞-伟大的代码!我自己做了一个改变。我想保留Title属性以达到其预期目的,因此我将自定义的Post类型slug放在链接关系(XFN)高级菜单属性中,您可以在屏幕选项中启用该属性。我改了

if ($item->attr_title != \'\' && $item->attr_title == $post_type) {
并将其更改为

if ($item->xfn != \'\' && $item->xfn == $post_type) {

SO网友:Vayu

干得好身体。

不幸的是,我不明白你怎么能用你解释的方式在页面上列出你的自定义帖子类型。如果我不使用页面公文包。php并将其添加到页面中,我得到的只是404页面。

如果我像Gavin一样,我已经对you函数进行了一些修改,以便像这样从博客页面中删除“current\\u page\\u parent”。

add_filter(\'nav_menu_css_class\', \'current_type_nav_class\', 10, 2);
function current_type_nav_class($css_class, $item) {
$post_type = get_query_var(\'post_type\');

if (get_post_type()==\'portfolio\') {
    $current_value = "current_page_parent"; 
    $css_class = array_filter($css_class, function ($element) use ($current_value) { return ($element != $current_value); } );
}

if ($item->attr_title != \'\' && $item->attr_title == $post_type) {       
    array_push($css_class, \'current_page_parent\');
};
return $css_class;
}

结束

相关推荐

Menu API not switching menus?

我正在使用菜单API,我想切换到其他菜单,但出于某种原因,它保留了第一个菜单这是我的密码在函数中。php add_action( \'init\', \'register_my_menus\',10 ); function register_my_menus() { register_nav_menu(\'main-navigation\', \'Main Navigation\'); } 下面是我的主题文件(header.ph