프로그래밍 방식으로 탐색 메뉴 및 메뉴 항목 추가


41

API 함수를 통해 새 탐색 메뉴 를 정의 하고 현재 테마에서 해당 메뉴 를 선택한 다음 몇 개의 페이지를 메뉴 항목으로 삽입하려고합니다. 이것은 예를 들어 테마 활성화에서 수행됩니다.

탐색 메뉴 및 항목을 수동으로 설정 한 후 데이터베이스 삽입 및 업데이트의 약간의 역 엔지니어링 리버스 엔지니어링 프로세스를 통해 다음 단계를 구성했습니다. 여기서 'footer-nav'는 탐색 메뉴의 슬러그 ID입니다. m 만들기 :

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

이것은 작동하는 것처럼 보이지만 :

  • 강력하고 우아한 방법입니까?
  • 한 줄의 코드 로이 모든 것을 할 수있는 확실한 것이 빠져 있습니까?

답변:


42

나는 당신을 오해하고 있지만, 왜 사용하지 wp_create_nav_menu()않습니까?

예를 들어, 이것은 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 );
    }

이 기능에 대해 몰랐습니다. 예, 위 코드를 훨씬 짧게 만들 것입니다. API 함수가 종종이 경우와 같이 너무 낮은 수준이라는 것을 알았으므로 Codex를 넘어 실제 코드로 뛰어 들어야한다고 생각합니다. 감사!
julien_c

이 문제가 해결되면 @julien_c로 방문하십시오.
mor7ifer

나는 실제로 그것을 실제 생활에서 실제로 테스트하고 싶기 때문에 내가 원하는 일을 확신합니다. 완료하자마자 해결 된 것으로 표시합니다.
julien_c

3
코덱스에없는 이와 같은 유용한 기능을 볼 수 있다면 (yay wiki) = p
Tom J Nowell

내 경우에 효과가 있는지 확인하는 데 시간이 오래 걸렸습니다. 답변이 접수되었습니다! 또한 사용자 정의 링크 메뉴 항목을 정의하고 있으며, 페이지 링크 를 정의하기 위해 아래에 답변을 추가했습니다 (예 : URL 변경에보다 강함).
julien_c

12

ZaMoose의 답변에 대한 보완책으로, 다음 은 " Custom "이 아닌 " 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'));

예를 들어 페이지 슬러그 만 알고 있다고 가정합니다.


9

허용되는 답변에 몇 가지 문제가 있습니다. 잘못되지는 않지만 동일한 질문이 있었지만 동일한 작업을 원했기 때문에 일부 사람들에게 더 나은 결과를 줄 수있는 내 자신의 코드를 아래에 게시합니다. 코드가 적은 것.

첫째, 위의 코드는 "URL"유형 탐색 항목을 생성하지만 일부 사람들에게는 적합하지만 URL이 아닌 PAGES에 링크하고 싶습니다. 이것은 WordPress 탐색의 중요한 기능이며 클라이언트가 움직일 수 없기 때문에 URL을 사용하지 않기 때문입니다. 탐색 항목 유형.

또한, 게시 된 코드는 플랫 형 하위 배열 만 처리합니다. 새로운 탐색 항목을 재귀 적으로 선언하고 반환 된 메타 데이터 (주로 루프에서 생성 된 후 ID)를 저장하는 함수와 자식을 허용하는 매개 변수를 만들었습니다.

그냥 편집 $nav_items_to_add하면 나머지는 재귀 적으로 처리됩니다. 각 배열에는 3 개의 필수 키가 있습니다. 먼저, 배열 키는 슬러그이므로 slug 'shop' => array( ... )가있는 페이지에 원하는 것입니다 shop. ['title']탐색 항목이 프런트 엔드에 표시되는 방식입니다. path는 워드 프레스 페이지 계층 내에서 페이지의 경로이므로 페이지가 최상위 부모 인 경우 슬러그와 동일 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')
        );
    }

    }

2

프로그래밍 방식으로 메뉴 항목을 추가합니다. wp_nav_menu_items필터에 연결하면 됩니다. 테마 functions.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;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.