以编程方式添加导航菜单和菜单项

时间:2012-03-07 作者:julien_c

通过API函数,我想定义一个新的Navigation menu, 在当前主题中选择它,然后插入几页作为菜单项。例如,这是在主题激活时完成的。

在手动设置导航菜单和项目后,通过一个(相当痛苦的)反向工程数据库插入和更新过程,我拼凑了以下步骤,其中“footer nav”是我正在创建的导航菜单的slug ID:

if (!term_exists(\'footer-nav\', \'nav_menu\')) {

    $menu = wp_insert_term(\'Footer nav\', \'nav_menu\', array(\'slug\' => \'footer-nav\'));

    // Select this menu in the current theme
    update_option(\'theme_mods_\'.get_current_theme(), array("nav_menu_locations" => array("primary" => $menu[\'term_id\'])));

    // Insert new page
    $page = wp_insert_post(array(\'post_title\' => \'Blog\',
                                 \'post_content\' => \'\',
                                 \'post_status\' => \'publish\',
                                 \'post_type\' => \'page\'));

    // Insert new nav_menu_item
    $nav_item = wp_insert_post(array(\'post_title\' => \'News\',
                                     \'post_content\' => \'\',
                                     \'post_status\' => \'publish\',
                                     \'post_type\' => \'nav_menu_item\'));


    add_post_meta($nav_item, \'_menu_item_type\', \'post_type\');
    add_post_meta($nav_item, \'_menu_item_menu_item_parent\', \'0\');
    add_post_meta($nav_item, \'_menu_item_object_id\', $page);
    add_post_meta($nav_item, \'_menu_item_object\', \'page\');
    add_post_meta($nav_item, \'_menu_item_target\', \'\');
    add_post_meta($nav_item, \'_menu_item_classes\', \'a:1:{i:0;s:0:"";}\');
    add_post_meta($nav_item, \'_menu_item_xfn\', \'\');
    add_post_meta($nav_item, \'_menu_item_url\', \'\');

    wp_set_object_terms($nav_item, \'footer-nav\', \'nav_menu\');
}
这似乎可行,但:

这是一种稳健而优雅的方式吗

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

我可能误解了你,但为什么不使用wp_create_nav_menu()?

E、 例如,当我检测到BP处于活动状态时,我会创建一个自定义BuddyPress菜单:

    $menuname = $lblg_themename . \' BuddyPress Menu\';
$bpmenulocation = \'lblgbpmenu\';
// Does the menu exist already?
$menu_exists = wp_get_nav_menu_object( $menuname );

// If it doesn\'t exist, let\'s create it.
if( !$menu_exists){
    $menu_id = wp_create_nav_menu($menuname);

    // Set up default BuddyPress links and add them to the menu.
    wp_update_nav_menu_item($menu_id, 0, array(
        \'menu-item-title\' =>  __(\'Home\'),
        \'menu-item-classes\' => \'home\',
        \'menu-item-url\' => home_url( \'/\' ), 
        \'menu-item-status\' => \'publish\'));

    wp_update_nav_menu_item($menu_id, 0, array(
        \'menu-item-title\' =>  __(\'Activity\'),
        \'menu-item-classes\' => \'activity\',
        \'menu-item-url\' => home_url( \'/activity/\' ), 
        \'menu-item-status\' => \'publish\'));

    wp_update_nav_menu_item($menu_id, 0, array(
        \'menu-item-title\' =>  __(\'Members\'),
        \'menu-item-classes\' => \'members\',
        \'menu-item-url\' => home_url( \'/members/\' ), 
        \'menu-item-status\' => \'publish\'));

    wp_update_nav_menu_item($menu_id, 0, array(
        \'menu-item-title\' =>  __(\'Groups\'),
        \'menu-item-classes\' => \'groups\',
        \'menu-item-url\' => home_url( \'/groups/\' ), 
        \'menu-item-status\' => \'publish\'));

    wp_update_nav_menu_item($menu_id, 0, array(
        \'menu-item-title\' =>  __(\'Forums\'),
        \'menu-item-classes\' => \'forums\',
        \'menu-item-url\' => home_url( \'/forums/\' ), 
        \'menu-item-status\' => \'publish\'));

    // Grab the theme locations and assign our newly-created menu
    // to the BuddyPress menu location.
    if( !has_nav_menu( $bpmenulocation ) ){
        $locations = get_theme_mod(\'nav_menu_locations\');
        $locations[$bpmenulocation] = $menu_id;
        set_theme_mod( \'nav_menu_locations\', $locations );
    }

SO网友:Brian

我对公认的答案有一些问题-这并不意味着它是错的,但我会在下面发布我自己的代码,我觉得对一些人来说可能会有更好的结果,因为我有同样的问题,但想用更少的代码做同样的事。

首先,上面的代码创建了“URL”类型的导航项,这对一些人来说很好,但我想链接到页面,而不是URL,因为这是WordPress导航的一个重要功能,客户端不可避免地会移动东西,所以我从不使用URL nav项目类型。

此外,发布的代码只处理子元素的平面数组。我创建了一个函数,用于递归声明新的nav项,存储它们返回的元数据(主要是在循环中创建后的ID),以及一个用于接受子项的参数。

只需编辑$nav_items_to_add 其余部分是递归处理的。每个数组中有3个必需的键。首先,数组键是slug,所以\'shop\' => array( ... ) 这是你想要的一页shop. [\'title\']是导航项目在前端标记的方式。path 是WordPress页面层次结构中页面的路径,因此如果页面是顶级父级,并且如果shop 是的孩子home 那就是\'path\' => \'home/shop\'.

最后一个可选的数组键是[\'parent\'] 可以将数组中的另一个键声明为当前键的父键。需要注意的是,这些项是递归添加的,因此在创建子项之前,父项必须存在。这意味着父nav项的声明应该在其子项之前进行。

    $locations = get_nav_menu_locations();

    if (isset($locations[\'primary_navigation\'])) {
        $menu_id = $locations[\'primary_navigation\'];

        $new_menu_obj = array();

        $nav_items_to_add = array(
                \'shop\' => array(
                    \'title\' => \'Shop\',
                    \'path\' => \'shop\',
                    ),
                \'shop_l2\' => array(
                    \'title\' => \'Shop\',
                    \'path\' => \'shop\',
                    \'parent\' => \'shop\',
                    ),
                \'cart\' => array(
                    \'title\' => \'Cart\',
                    \'path\' => \'shop/cart\',
                    \'parent\' => \'shop\',
                    ),
                \'checkout\' => array(
                    \'title\' => \'Checkout\',
                    \'path\' => \'shop/checkout\',
                    \'parent\' => \'shop\',
                    ),
                \'my-account\' => array(
                    \'title\' => \'My Account\',
                    \'path\' => \'shop/my-account\',
                    \'parent\' => \'shop\',
                    ),
                \'lost-password\' => array(
                    \'title\' => \'Lost Password\',
                    \'path\' => \'shop/my-account/lost-password\',
                    \'parent\' => \'my-account\',
                    ),
                \'edit-address\' => array(
                    \'title\' => \'Edit My Address\',
                    \'path\' => \'shop/my-account/edit-address\',
                    \'parent\' => \'my-account\',
                    ),
            );

    foreach ( $nav_items_to_add as $slug => $nav_item ) {
        $new_menu_obj[$slug] = array();
        if ( array_key_exists( \'parent\', $nav_item ) )
            $new_menu_obj[$slug][\'parent\'] = $nav_item[\'parent\'];
        $new_menu_obj[$slug][\'id\'] = wp_update_nav_menu_item($menu_id, 0,  array(
                \'menu-item-title\' => $nav_item[\'title\'],
                \'menu-item-object\' => \'page\',
                \'menu-item-parent-id\' => $new_menu_obj[ $nav_item[\'parent\'] ][\'id\'],
                \'menu-item-object-id\' => get_page_by_path( $nav_item[\'path\'] )->ID,
                \'menu-item-type\' => \'post_type\',
                \'menu-item-status\' => \'publish\')
        );
    }

    }

SO网友:julien_c

作为ZaMoose的anwser的补充,以下是您如何创建“Page-键入“菜单项(非a)”Custom“一个):

wp_update_nav_menu_item($menu_id, 0, array(\'menu-item-title\' => \'About\',
                                           \'menu-item-object\' => \'page\',
                                           \'menu-item-object-id\' => get_page_by_path(\'about\')->ID,
                                           \'menu-item-type\' => \'post_type\',
                                           \'menu-item-status\' => \'publish\'));
例如,假设您只知道页面slug。

SO网友:Aamer Shahzad

以编程方式添加菜单项。您可以连接到wp_nav_menu_items 滤器在主题函数中放置下面的代码。php在主菜单中添加登录/注销菜单项。”“Primary”是已注册菜单的名称/id。

/**
 * Add login logout menu item in the main menu.
 * ===========================================
 */

add_filter( \'wp_nav_menu_items\', \'lunchbox_add_loginout_link\', 10, 2 );
function lunchbox_add_loginout_link( $items, $args ) {
    /**
     * If menu primary menu is set & user is logged in.
     */
    if ( is_user_logged_in() && $args->theme_location == \'primary\' ) {
        $items .= \'<li><a href="\'. wp_logout_url() .\'">Log Out</a></li>\';
    }
    /**
     * Else display login menu item.
     */
    elseif ( !is_user_logged_in() && $args->theme_location == \'primary\' ) {
        $items .= \'<li><a href="\'. site_url(\'wp-login.php\') .\'">Log In</a></li>\';
    }
    return $items;
}

结束

相关推荐

WooCommerce dynamic menus

我有一个基本的WordPress网站,设置了Suffusion主题和WooCommerce插件。这在大多数情况下都很有效,但是当我让人们点击/悬停在“Shop”菜单图标上时,我希望它能够动态地下拉我定义的产品类别。我如何做到这一点?我肯定有关于这个主题的文档,但我不确定要查找什么。我主要是一名系统管理员。