Программно добавьте Навигационное меню и пункты меню

Через API-функции я хочу определить новое Навигационное меню, выбрать его в текущей теме и затем вставить несколько Страниц как пункты меню. Это должно быть сделано, например, на активации темы.

Посредством (умеренно болезненного) процесса инженерного анализа базы данных вставляет и обновления после ручной установки Навигационного меню и объектов, я соединил следующие шаги, где 'военно-морской нижним колонтитулом' идентификатор краткого заголовка Навигационного меню, которое я создаю:

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

Это, кажется, работает, но:

  • действительно ли это - устойчивый и изящный способ сделать его?
  • я пропускаю что-то полностью очевидное, это сделало бы все это в одной строке кода?
44
09.03.2012, 21:48
3 ответа

Я мог бы неправильно понимать Вас, но почему бы не использовать wp_create_nav_menu()?

Например, это - то, что я делаю для создания пользовательского меню BuddyPress, когда я обнаруживаю BP как активную:

    $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 );
    }
44
19.02.2020, 21:54
  • 1
    я не знал об этой функции. Да, я предполагаю, что это сделает вышеупомянутый код намного короче. Я предполагаю, что должен переместиться вне Кодекса и погружения в фактический код, поскольку я нахожу, что API-функции часто, как в этом случае, слишком низкий уровень.Спасибо! –  julien_c 07.03.2012, 16:18
  • 2
    @julien_c, если это решено, отмечает его как таковой, чтобы позволить тем, кто приезжает после Вас для пользы из опыта здесь. –  mor7ifer 07.03.2012, 17:07
  • 3
    , я просто хочу на самом деле протестировать его в реальной жизни, таким образом, я уверен, что он делает то, что я хочу. Я не забуду отмечать его, как решено, как только я сделан! огромное спасибо –  julien_c 07.03.2012, 17:51
  • 4
    Если Вы видите полезные функции как они, которые не находятся в кодексе, это - хорошая идея добавить их (yay Wiki) =p –  Tom J Nowell♦ 09.03.2012, 21:51
  • 5
    Извините мне потребовалось такое долгое время, чтобы проверить, что это работало в моем случае. Ответ принят! Кроме того, Вы определяете пункты меню настраиваемых ссылок, я добавил ответ ниже для определения ссылок страницы (который будет более устойчивым к изменениям URL, например). –  julien_c 15.05.2012, 14:06

Как дополнение к anwser ZaMoose, вот то, как Вы создали бы пункт меню "Page-type" (не "Пользовательский"):

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'));

Принятие Вас только знает краткий заголовок страницы, например.

13
19.02.2020, 21:54

У меня есть несколько проблем с принятым ответом - который не делает его неправильно, но я отправлю свой собственный код, ниже которого я чувствую, мог бы иметь лучший результат для некоторых людей, так как я имел тот же вопрос, но хотел сделать то же самое с меньшим количеством кода.

Во-первых, вышеупомянутый код создает элементы навигации типа "URL", который хорошо для некоторых людей, но я хочу связаться со СТРАНИЦАМИ, не URL, потому что это - важная функция навигации WordPress и клиентов неизбежные вещи перемещения вокруг, так я никогда не использую URL военно-морской тип изделия.

Кроме того, только плоская антенная решетка детей обрабатывается отправленным кодом. Я создал функцию для того, чтобы рекурсивно объявить новые военно-морские объекты, храня их возвращенные метаданные (главным образом идентификатор, будучи созданным в цикле), и параметр для принятия детей.

Просто редактирование $nav_items_to_add и остальное обрабатывается рекурсивно. Существует 3 необходимых ключа в каждом массиве. Во-первых, ключ массива является кратким заголовком, таким образом, 'shop' => array( ... ) то, что Вы хотите для страницы с кратким заголовком shop. ['title']способ, которым военно-морской объект будет маркирован на фронтэнде. path путь к странице в иерархии страницы WordPress, таким образом, это идентично краткому заголовку, если страница является родителем верхнего уровня, и если shop был ребенок home затем это было бы 'path' => 'home/shop'.

Последний дополнительный ключ массива ['parent'] где можно объявить другой ключ в массиве как родитель текущего. Важно отметить, что объекты добавляются рекурсивно, таким образом, родитель должен существовать, прежде чем Вы попытаетесь создать ребенка. Это означает, что объявление должно произойти для родительского военно-морского объекта, прежде чем это будут дети.

    $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')
        );
    }

    }
10
19.02.2020, 21:54