在Start_el()Walker中按菜单ID或菜单ID的菜单位置

时间:2015-06-24 作者:Aurelian Pop

我正在创建一个自定义walker菜单,在其中向菜单项添加自定义字段,但我希望这些字段特定于菜单位置。我可以从以下位置获取所有菜单位置,并将菜单ID分配给它们:

$menu_locations = get_nav_menu_locations();
这将输出如下数组:

array:2 [
  "main_nav" => 27
  "footer_nav" => 29
]
或者,您可以获得所有菜单,但它们没有主题位置:

$menus = get_terms(\'nav_menu\');
这将输出一个对象列表,如:

array:3 [
  0 => {#762
    +"term_id": "28"
    +"name": "Footer Menu"
    +"slug": "footer-menu"
    +"term_group": "0"
    +"term_taxonomy_id": "28"
    +"taxonomy": "nav_menu"
    +"description": ""
    +"parent": "0"
    +"count": "1"
  }
  1 => {#761
    +"term_id": "27"
    +"name": "Menu 1"
    +"slug": "menu-1"
    +"term_group": "0"
    +"term_taxonomy_id": "27"
    +"taxonomy": "nav_menu"
    +"description": ""
    +"parent": "0"
    +"count": "11"
  }
]
我的问题是:你能通过ID/名称/slug获得特定菜单的菜单位置吗?或者您可以通过菜单ID获取菜单位置吗?

4 个回复
SO网友:anastymous

通过控制使用哪种助行器,您会发现控制显示哪些字段要容易得多。而不是试图“切换”助行器内的字段。

我还想显示一组自定义字段,并且只在特定菜单位置的菜单上显示它们。所以我用了下面的。。。

add_filter( \'wp_edit_nav_menu_walker\', function( $walker, $menu_id ) {

    $menu_locations = get_nav_menu_locations();

    if ( $menu_locations[\'main_menu\'] == $menu_id ) {
        return \'Walker_Nav_Menu_Custom\';
    } else {
        return $walker;
    }

}, 10, 2); 

SO网友:Aurelian Pop

我找到了这个问题的解决方案,我将在这里发布,也许其他人需要自己在后端菜单中添加自定义字段。我发现最好的方法是为每个后端菜单调用不同的walker类。

这将是一个很长的答案,由于字符限制,我无法发布所有代码,但如果你仔细观察,你会发现它只缺少了第二个Walker类,它与第一个类完全相同,但与此处发布的不同

答案基于此答案

https://wordpress.stackexchange.com/a/33495/75163

首先创建两个(或moore)菜单位置:

register_nav_menus([
      \'main_nav\' => __(\'Main nav menu\', \'textdomain\'),
      \'footer_nav\' => __(\'Footer nav menu\', \'textdomain\'),
]);
然后创建要在菜单位置上使用的导航菜单:

            $args = array(
                \'theme_location\' => \'main_nav\',
                \'menu\' => \'\',
                \'container\' => \'div\',
                \'container_id\' => \'\',
                \'menu_class\' => \'menu\',
                \'menu_id\' => \'\',
                \'echo\' => true,
                \'fallback_cb\' => \'wp_page_menu\',
                \'before\' => \'\',
                \'after\' => \'\',
                \'link_before\' => \'\',
                \'link_after\' => \'\',
                \'items_wrap\' => \'<ul role="navigation" id="nav-primary" class="nav">%3$s</ul>\',
                \'depth\' => 3,
            );

            wp_nav_menu($args);
AND:

$args = array(
                    \'theme_location\' => \'footer_nav\',
                    \'menu\' => \'\',
                    \'container\' => \'\',
                    \'container_id\' => \'\',
                    \'menu_class\' => \'menu\',
                    \'menu_id\' => \'\',
                    \'echo\' => true,
                    \'fallback_cb\' => \'wp_page_menu\',
                    \'before\' => \'\',
                    \'after\' => \'\',
                    \'link_before\' => \'\',
                    \'link_after\' => \'\',
                    \'items_wrap\' => \'%3$s\',
                    \'depth\' => 2,
                );

                wp_nav_menu($args);
在“外观->菜单->管理位置”的“菜单位置”部分中选择它们。

现在,开始根据上面的示例创建walker(位于functions.php文件中):

/**
 * Saves new field to postmeta for navigation
 */
add_action(\'wp_update_nav_menu_item\', \'custom_nav_update\', 10, 3);
function custom_nav_update($menu_id, $menu_item_db_id, $args)
{   
    if (isset($_REQUEST[\'menu-item-custom\']) && is_array($_REQUEST[\'menu-item-custom\'])) {
        if (isset($_REQUEST[\'menu-item-custom\'][$menu_item_db_id])) {
            $custom_value = $_REQUEST[\'menu-item-custom\'][$menu_item_db_id];
            update_post_meta($menu_item_db_id, \'_menu_item_custom\', $custom_value);
        } else {
            $post_meta = get_post_meta($menu_item_db_id, \'_menu_item_custom\', true);
            if ($post_meta == "checked") {
                delete_post_meta($menu_item_db_id, \'_menu_item_custom\');
            }
        }
    }

    if (isset($_REQUEST[\'menu-item-icon\']) && is_array($_REQUEST[\'menu-item-icon\'])) {
        if (isset($_REQUEST[\'menu-item-icon\'][$menu_item_db_id])) {
            $custom_value = $_REQUEST[\'menu-item-icon\'][$menu_item_db_id];
            update_post_meta($menu_item_db_id, \'_menu_item_icon\', $custom_value);
        } else {
            $post_meta = get_post_meta($menu_item_db_id, \'_menu_item_icon\', true);
            $icons = lpCustomIconsList();
            foreach($icons as $icon => $icon_name)
            if ($post_meta == $icon) {
                delete_post_meta($menu_item_db_id, \'_menu_item_icon\');
            }
        }
    }
}

/**
 * Adds values of new field to $item object that will be passed to Walker_Nav_Menu_Edit_Custom
 * @param  int $menu_item item id
 * @return obj            the whole item
 */
add_filter( \'wp_setup_nav_menu_item\',\'custom_nav_item\' );
function custom_nav_item($menu_item) {
    $menu_item->custom = get_post_meta( $menu_item->ID, \'_menu_item_custom\', true );
    $menu_item->icon = get_post_meta( $menu_item->ID, \'_menu_item_icon\', true );
    return $menu_item;
}

/**
 * Creates a menu walker with custom Checkbox or Select box 
 *
 * @param $walker
 * @param $menu_id
 * @return string
 */
add_filter( \'wp_edit_nav_menu_walker\', \'custom_nav_edit_walker\',10,2 );
function custom_nav_edit_walker($walker,$menu_id) {
  $menu_locations = get_nav_menu_locations();

  $main_nav_obj = get_term( $menu_locations[\'main_nav\'], \'nav_menu\' );
  $footer_nav_obj = get_term( $menu_locations[\'footer_nav\'], \'nav_menu\' );
  if($main_nav_obj->term_id == $menu_id) {
    return \'BackendHeader\';
  } elseif($footer_nav_obj->term_id == $menu_id) {
    return \'BackendFooter\';
  } else {
    return $walker;
  }

}
这些唤醒器基于Walker\\u Nav\\u Menu\\u Edit类

class BackendHeader extends Walker_Nav_Menu_Edit
{


    /**
     * @see Walker::start_el()
     * @since 3.0.0
     *
     * @param string $output Passed by reference. Used to append additional content.
     * @param object $item Menu item data object.
     * @param int $depth Depth of menu item. Used for padding.
     * @param array|object $args
     * @param int $id
     */
    function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 )
    {        global $_wp_nav_menu_max_depth;
        $_wp_nav_menu_max_depth = $depth > $_wp_nav_menu_max_depth ? $depth : $_wp_nav_menu_max_depth;

        $indent = ($depth) ? str_repeat("\\t", $depth) : \'\';

        ob_start();
        $item_id = esc_attr($item->ID);
        $removed_args = array(
            \'action\',
            \'customlink-tab\',
            \'edit-menu-item\',
            \'menu-item\',
            \'page-tab\',
            \'_wpnonce\',
        );

        $original_title = \'\';
        if (\'taxonomy\' == $item->type) {
            $original_title = get_term_field(\'name\', $item->object_id, $item->object, \'raw\');
            if (is_wp_error($original_title))
                $original_title = false;
        } elseif (\'post_type\' == $item->type) {
            $original_object = get_post($item->object_id);
            $original_title = $original_object->post_title;
        }

        $classes = array(
            \'menu-item menu-item-depth-\' . $depth,
            \'menu-item-\' . esc_attr($item->object),
            \'menu-item-edit-\' . ((isset($_GET[\'edit-menu-item\']) && $item_id == $_GET[\'edit-menu-item\']) ? \'active\' : \'inactive\'),
        );

        $title = $item->title;

        if (!empty($item->_invalid)) {
            $classes[] = \'menu-item-invalid\';
            /* translators: %s: title of menu item which is invalid */
            $title = sprintf(__(\'%s (Invalid)\'), $item->title);
        } elseif (isset($item->post_status) && \'draft\' == $item->post_status) {
            $classes[] = \'pending\';
            /* translators: %s: title of menu item in draft status */
            $title = sprintf(__(\'%s (Pending)\'), $item->title);
        }

        $title = empty($item->label) ? $title : $item->label;
        ?>
    <li id="menu-item-<?php echo $item_id; ?>" class="<?php echo implode(\' \', $classes); ?>">
        <dl class="menu-item-bar">
            <dt class="menu-item-handle">
                <span class="item-title"><?php echo esc_html($title); ?></span>
                <span class="item-controls">
                    <span class="item-type"><?php echo esc_html($item->type_label); ?></span>
                    <span class="item-order hide-if-js">
                        <a href="<?php
                        echo wp_nonce_url(
                            add_query_arg(
                                array(
                                    \'action\' => \'move-up-menu-item\',
                                    \'menu-item\' => $item_id,
                                ),
                                remove_query_arg($removed_args, admin_url(\'nav-menus.php\'))
                            ),
                            \'move-menu_item\'
                        );
                        ?>" class="item-move-up"><abbr title="<?php esc_attr_e(\'Move up\'); ?>">&#8593;</abbr></a>
                        |
                        <a href="<?php
                        echo wp_nonce_url(
                            add_query_arg(
                                array(
                                    \'action\' => \'move-down-menu-item\',
                                    \'menu-item\' => $item_id,
                                ),
                                remove_query_arg($removed_args, admin_url(\'nav-menus.php\'))
                            ),
                            \'move-menu_item\'
                        );
                        ?>" class="item-move-down"><abbr title="<?php esc_attr_e(\'Move down\'); ?>">&#8595;</abbr></a>
                    </span>
                    <a class="item-edit" id="edit-<?php echo $item_id; ?>"
                       title="<?php esc_attr_e(\'Edit Menu Item\'); ?>" href="<?php
                    echo (isset($_GET[\'edit-menu-item\']) && $item_id == $_GET[\'edit-menu-item\']) ? admin_url(\'nav-menus.php\') : add_query_arg(\'edit-menu-item\', $item_id, remove_query_arg($removed_args, admin_url(\'nav-menus.php#menu-item-settings-\' . $item_id)));
                    ?>"><?php _e(\'Edit Menu Item\'); ?></a>
                </span>
            </dt>
        </dl>

        <div class="menu-item-settings" id="menu-item-settings-<?php echo $item_id; ?>">
            <?php if (\'custom\' == $item->type) : ?>
                <p class="field-url description description-wide">
                    <label for="edit-menu-item-url-<?php echo $item_id; ?>">
                        <?php _e(\'URL\'); ?><br/>
                        <input type="text" id="edit-menu-item-url-<?php echo $item_id; ?>"
                               class="widefat code edit-menu-item-url" name="menu-item-url[<?php echo $item_id; ?>]"
                               value="<?php echo esc_attr($item->url); ?>"/>
                    </label>
                </p>
            <?php endif; ?>
            <p class="description description-thin">
                <label for="edit-menu-item-title-<?php echo $item_id; ?>">
                    <?php _e(\'Navigation Label\'); ?><br/>
                    <input type="text" id="edit-menu-item-title-<?php echo $item_id; ?>"
                           class="widefat edit-menu-item-title" name="menu-item-title[<?php echo $item_id; ?>]"
                           value="<?php echo esc_attr($item->title); ?>"/>
                </label>
            </p>

            <p class="description description-thin">
                <label for="edit-menu-item-attr-title-<?php echo $item_id; ?>">
                    <?php _e(\'Title Attribute\'); ?><br/>
                    <input type="text" id="edit-menu-item-attr-title-<?php echo $item_id; ?>"
                           class="widefat edit-menu-item-attr-title"
                           name="menu-item-attr-title[<?php echo $item_id; ?>]"
                           value="<?php echo esc_attr($item->post_excerpt); ?>"/>
                </label>
            </p>

            <p class="field-link-target description">
                <label for="edit-menu-item-target-<?php echo $item_id; ?>">
                    <input type="checkbox" id="edit-menu-item-target-<?php echo $item_id; ?>" value="_blank"
                           name="menu-item-target[<?php echo $item_id; ?>]"<?php checked($item->target, \'_blank\'); ?> />
                    <?php _e(\'Open link in a new window/tab\'); ?>
                </label>
            </p>

            <p class="field-css-classes description description-thin">
                <label for="edit-menu-item-classes-<?php echo $item_id; ?>">
                    <?php _e(\'CSS Classes (optional)\'); ?><br/>
                    <input type="text" id="edit-menu-item-classes-<?php echo $item_id; ?>"
                           class="widefat code edit-menu-item-classes" name="menu-item-classes[<?php echo $item_id; ?>]"
                           value="<?php echo esc_attr(implode(\' \', $item->classes)); ?>"/>
                </label>
            </p>

            <p class="field-xfn description description-thin">
                <label for="edit-menu-item-xfn-<?php echo $item_id; ?>">
                    <?php _e(\'Link Relationship (XFN)\'); ?><br/>
                    <input type="text" id="edit-menu-item-xfn-<?php echo $item_id; ?>"
                           class="widefat code edit-menu-item-xfn" name="menu-item-xfn[<?php echo $item_id; ?>]"
                           value="<?php echo esc_attr($item->xfn); ?>"/>
                </label>
            </p>

            <p class="field-description description description-wide">
                <label for="edit-menu-item-description-<?php echo $item_id; ?>">
                    <?php _e(\'Description\'); ?><br/>
                    <textarea id="edit-menu-item-description-<?php echo $item_id; ?>"
                              class="widefat edit-menu-item-description" rows="3" cols="20"
                              name="menu-item-description[<?php echo $item_id; ?>]"><?php echo esc_html($item->description); // textarea_escaped
                        ?></textarea>
                    <span
                        class="description"><?php _e(\'The description will be displayed in the menu if the current theme supports it.\'); ?></span>
                </label>
            </p>
            <?php
            /*
             * This is the added field
             */
            ?>
            <p class="field-custom description description-wide">
                <label for="edit-menu-item-custom-<?php echo $item_id; ?>">
                    <?php _e(\'Checkbox\'); ?><br/>
                    <input type="checkbox" id="edit-menu-item-custom-<?php echo $item_id; ?>"
                           class="widefat code edit-menu-item-custom"
                           name="menu-item-custom[<?php echo $item_id; ?>]" <?php if ($item->custom == \'checked\') {
                        echo "checked";
                    } ?> value="checked"/>
                </label>
            </p>
            <?php
            /*
             * end added field
             */
            ?>
            <div class="menu-item-actions description-wide submitbox">
                <?php if (\'custom\' != $item->type && $original_title !== false) : ?>
                    <p class="link-to-original">
                        <?php printf(__(\'Original: %s\'), \'<a href="\' . esc_attr($item->url) . \'">\' . esc_html($original_title) . \'</a>\'); ?>
                    </p>
                <?php endif; ?>
                <a class="item-delete submitdelete deletion" id="delete-<?php echo $item_id; ?>" href="<?php
                echo wp_nonce_url(
                    add_query_arg(
                        array(
                            \'action\' => \'delete-menu-item\',
                            \'menu-item\' => $item_id,
                        ),
                        remove_query_arg($removed_args, admin_url(\'nav-menus.php\'))
                    ),
                    \'delete-menu_item_\' . $item_id
                ); ?>"><?php _e(\'Remove\'); ?></a> <span class="meta-sep"> | </span> <a class="item-cancel submitcancel"
                                                                                       id="cancel-<?php echo $item_id; ?>"
                                                                                       href="<?php echo esc_url(add_query_arg(array(\'edit-menu-item\' => $item_id, \'cancel\' => time()), remove_query_arg($removed_args, admin_url(\'nav-menus.php\'))));
                                                                                       ?>#menu-item-settings-<?php echo $item_id; ?>"><?php _e(\'Cancel\'); ?></a>
            </div>

            <input class="menu-item-data-db-id" type="hidden" name="menu-item-db-id[<?php echo $item_id; ?>]"
                   value="<?php echo $item_id; ?>"/>
            <input class="menu-item-data-object-id" type="hidden" name="menu-item-object-id[<?php echo $item_id; ?>]"
                   value="<?php echo esc_attr($item->object_id); ?>"/>
            <input class="menu-item-data-object" type="hidden" name="menu-item-object[<?php echo $item_id; ?>]"
                   value="<?php echo esc_attr($item->object); ?>"/>
            <input class="menu-item-data-parent-id" type="hidden" name="menu-item-parent-id[<?php echo $item_id; ?>]"
                   value="<?php echo esc_attr($item->menu_item_parent); ?>"/>
            <input class="menu-item-data-position" type="hidden" name="menu-item-position[<?php echo $item_id; ?>]"
                   value="<?php echo esc_attr($item->menu_order); ?>"/>
            <input class="menu-item-data-type" type="hidden" name="menu-item-type[<?php echo $item_id; ?>]"
                   value="<?php echo esc_attr($item->type); ?>"/>
        </div>
        <!-- .menu-item-settings-->
        <ul class="menu-item-transport"></ul>
        <?php
        $output .= ob_get_clean();
    }
}
/**
* The same as the one on top but with a different fiel
*/
class BackendFooter extends Walker_Nav_Menu_Edit
{

            /*
             * This is the added field
             */
            ?>
            <p class="field-icon description description-wide">
                <label for="edit-menu-item-icon-<?php echo $item_id; ?>">
                    <?php _e(\'Icon\'); ?><br/>
                    <select id="edit-menu-item-icon-<?php echo $item_id; ?>" class="widefat code edit-menu-item-icon" name="menu-item-icon[<?php echo $item_id; ?>]">
                            <option <?php if(\'icon\' == $item->icon) { echo "selected=\'selected\'"; } ?> value="icon">Icon One</option>
<option <?php if(\'icon2\' == $item->icon) { echo "selected=\'selected\'"; } ?> value="icon2">Icon Two</option>
<option <?php if(\'icon3\' == $item->icon) { echo "selected=\'selected\'"; } ?> value="icon3">Icon Three</option>
                        <?php } ?>
                    </select>
                </label>
            </p>
            <?php
            /*
             * end added field
             */
            ?>

}

SO网友:Jake

只需转置get_nav_menu_locations() 为您提供从菜单ID到菜单位置的映射:

$menu_locations = \\array_flip(\\get_nav_menu_locations());
$menu_location = $menu_locations[$menu_id] ?? null; 
if ($menu_location === \'main_nav\') {
  do_something();
}
上述代码包括通过ID获取特定菜单的菜单位置。

如果没有菜单ID,但有名称或slug,则可以使用wp_get_nav_menu_object() 首先获取ID:

$menu_term = \\wp_get_nav_menu_object($menu_slug_name_id_or_wpterm);
$menu_id = \\is_object($menu_term) ? $menu_term->term_id : null;
然后继续上面的代码以从ID获取位置。

(wp_get_nav_menu_object() 也将接受ID或WP_Term, 所以你可以扔掉你所有的东西WP_Term 获取ID。)

SO网友:James Barrett

wp\\u get\\u nav\\u menu\\u object($菜单);

当给定菜单id、slug或名称时,返回nav菜单对象。这对于检索指定给自定义菜单的名称特别有用。

http://codex.wordpress.org/Function_Reference/wp_get_nav_menu_object

结束

相关推荐

Mega Menu Walker

我正在尝试创建一个超大菜单漫游器。不幸的是,walkers完全没有掌握我的编码知识。我真的需要一些帮助才能让它工作。以下是我需要的功能:包裹第二层<ul> 在里面<section>. [COMPLETE]</当用户在<li> 在第二级<ul>, 做那个<li> 开始一个新的<ul>. 如果是第一次<li> 在列表中,不要做任何事情,以防止形成空的无序列表。[COMPLETE]</当用户在<li> 在