从wp_NAV_MENU中动态排除菜单项

时间:2011-10-21 作者:Marventus

我试图查找有关如何从自定义菜单中排除/删除导航菜单项的信息,并且thread 我发现没有任何对我有用的答案。

1. Background:

我使用WP自定义菜单(WP\\U nav\\U菜单)和jqDock 在我的网站上。由于jqDock需要连续的图像或图像链接才能发挥其魔力,因此我使用了一个自定义walker,使导航菜单HTML输出看起来像这样:

<div id="menu-first" class="nav">
<a><img src="http://path/to/image-1.png"/></a>
<a><img src="http://path/to/image-2.png"/></a>
<a><img src="http://path/to/image-3.png"/></a>
etc...
</div>
我的自定义walker的代码是:

class custom_nav_walker extends Walker_Nav_Menu 
{
    var $tree_type = array( \'post_type\', \'taxonomy\', \'custom\' );
    var $db_fields = array( \'parent\' => \'menu_item_parent\', \'id\' => \'db_id\' );

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

    function end_lvl(&$output, $depth) {
        $indent = str_repeat("\\t", $depth);
        $output .= "$indent</ul>\\n";
    }

    function start_el(&$output, $item, $depth, $args) {
        global $wp_query;
        $indent = ( $depth ) ? str_repeat( "\\t", $depth ) : \'\';

        $class_names = $value = \'\';

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        $classes[] = \'menu-item-\' . $item->ID;

        $class_names = join( \' \', apply_filters( \'nav_menu_css_class\', array_filter( $classes ), $item, $args ) );
        $class_names = \' class="\' . esc_attr( $class_names ) . \'"\';

        $id = apply_filters( \'nav_menu_item_id\', \'menu-item-\'. $item->ID, $item, $args );
        $id = strlen( $id ) ? \' id="\' . esc_attr( $id ) . \'"\' : \'\';

        //$output .= $indent . \'<li\' . $id . $value . $class_names .\'>\';

        $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        ) .\'"\' : \'\';
        $attributes .= ! empty( $item->url )        ? \' href="\'   . esc_attr( $item->url        ) .\'"\' : \'\';

        $description  = ! empty( $item->description ) ? esc_attr( strtolower( $item->description )) : \'\';
        $item_title   = ! empty( $item->attr_title )  ? esc_attr( $item->attr_title ) : \'\';

        if ( strpos($description, \';\') !== false ) {
        $description_array = explode (\';\', $description);
            $image_name = $description_array[0];
            $image_alt = $description_array[1];
        } else {
            $image_name = $description;
            $image_alt = $item_title;
        }

        $item_output = $args->before;
        $item_output .= \'<a\'. $attributes .\'>\';
        $item_output .= $args->link_before .\'<img src="\'.get_bloginfo(\'template_url\').\'/images/skin1/\'.$image_name.\'" alt="\'.$image_alt.\'" title="\'.$item_title.\'" />\'.$args->link_after;
        $item_output .= \'</a>\';
        $item_output .= $args->after;

        $output .= apply_filters( \'walker_nav_menu_start_el\', $item_output, $item, $depth, $args );
    }

    function end_el(&$output, $item, $depth) {
        $output .= "";
    }

}
然后,jqDock脚本捕获菜单ID(“menu-first”),并将wp\\u nav\\u菜单输出替换为停靠菜单。停靠菜单的HTML输出会根据加载jqDock时指定的选项进行更改。

2. The Question:

我不想根据用户在站点上的位置显示(即排除)某些菜单项。例如,我只想在用户不在家时显示主页项目,而仅在用户在家时显示随机发布项目。

3. Discarded solutions:

<多菜单:注册和创建多个菜单,然后有条件地调用它们可以工作;然而,出于许多原因,我认为这不是一个理想的或干净的解决方案。此外,多个菜单不容易维护或更新。

b、 Regex搜索和替换:这可能会迫使我每次更改jqDock选项时都更改needle参数,因为HTML输出被修改了。

c、 CSS“display”属性:通过CSS display属性隐藏项目是可行的,但由于它必须应用于jqDock菜单输出,因此会影响菜单的视觉渲染。

4. Failed Solutions:

a、 筛选到wp\\u nav\\u menu\\u items:我尝试捕获“$items”变量(字符串),并通过具有以下代码的条件标记为其分配不同的值:

function userf_dynamic_nav_menu ($items) {
    $items_array_home = explode(\'<a\', $items);
    $items_array_nothome = $items_array_home;

    unset($items_array_home[1]);
    unset($items_array_nothome[2]);

    $items_home = implode(\'<a\', $items_array_home);
    $items_nothome = implode(\'<a\', $items_array_nothome);

    if ( is_home() ) {
        $items = $items_home;
    } else {
        $items = $items_nothome;
    }
    return $items;
}
add_filter(\'wp_nav_menu_first_items\', \'userf_dynamic_nav_menu\');
这只能部分起作用,因为菜单项确实会更改,但条件标记会被忽略。我想这是有意义的,因为应用过滤器的时刻。

b、 自定义导航菜单函数:我尝试创建自己的自定义导航菜单函数,以便能够向$defaults数组添加排除参数,并使用wp_list_pages 要填充附加参数,请执行以下操作:

$exclude_array = ( $args->exclude ) ? explode(\',\', $args->exclude) : array();
$args->exclude = implode( \',\', apply_filters(\'wp_nav_menu_excludes\', $exclude_array) );
有什么想法吗?

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

方法1可以将构造函数添加到自定义Walker中,以存储一些额外的排除参数,例如:

class custom_nav_walker extends Walker_Nav_Menu {
    function __construct( $exclude = null ) {
        $this->exclude = $exclude;
    }

    function skip( $item ) {
        return in_array($item->ID, (array)$this->exclude);
        // or
        return in_array($item->title, (array)$this->exclude);
        // etc.
    }

    // ...inside start_el, end_el
    if ( $this->skip( $item ) ) return;
}
或者删除构造函数并设置其$exclude 在将其作为步行者传递给wp_nav_menu() 像这样:

$my_custom_nav_walker = new custom_nav_walker;
$my_custom_nav_walker->exclude = array( ... );
根据要排除的内容,为排除提供正确的表单。

方法2这是通过连接wp_get_nav_menu_items 滤器

function wpse31748_exclude_menu_items( $items, $menu, $args ) {
    // Iterate over the items to search and destroy
    foreach ( $items as $key => $item ) {
        if ( $item->object_id == 168 ) unset( $items[$key] );
    }

    return $items;
}

add_filter( \'wp_get_nav_menu_items\', \'wpse31748_exclude_menu_items\', null, 3 );
注:object_id 是菜单指向的对象,而ID 是菜单ID,这些是不同的。

让我知道你的想法。

SO网友:saq

这有帮助吗

$exclude_array = ( $args->exclude ) ? explode(\',\', $args->exclude) : array();
$args->exclude = implode( \',\', apply_filters(\'wp_nav_menu_excludes\', $exclude_array) );
例如

< ?php wp_nav_menu( array( \'container_class\' => \'menu-header\', \'theme_location\' => \'primary\', \'exclude\' => \'66\' ) ); ?>

结束

相关推荐

如何让我的自定义帖子类型出现在NAV-menus.php‘Menu’中?

我的自定义帖子类型有点问题。我可以在我的主题中很好地创建它们,但我无法让它们显示在“菜单”屏幕中。。。至少在默认情况下不是这样。我曾尝试在代码中添加菜单和UI标志(见下文),但没有成功。有趣的是,当我启用自定义帖子类型UI插件时,自定义帖子类型在“菜单”屏幕中显示良好(有时)。这似乎向我暗示,我在某个地方遗漏了一个步骤,而且不知何故,自定义帖子类型UI插件设置了该标志,并允许我的自定义帖子类型和分类显示在导航菜单中。php“菜单”屏幕。编辑::以上位已回答。谢谢你,米洛。我应该在“屏幕选项”选项卡中打开它