it-swarm.dev

Aggiungere un menu di voci e menu di livello

Attraverso le funzioni API, voglio definire un nuovo Menu di navigazione , selezionarlo nel tema corrente, quindi inserire alcune pagine come voci di menu. Questo deve essere fatto ad esempio su un tema di attivazione.

Attraverso un (moderatamente doloroso) processo di reverse engineering degli inserimenti e degli aggiornamenti del database dopo aver impostato manualmente il menu di navigazione e gli elementi, ho messo insieme i seguenti passaggi, dove 'footer-nav' è l'ID slug del menu di navigazione I ' m creando:

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

Questo sembra funzionare, ma:

  • è un modo robusto ed elegante di farlo?
  • mi manca qualcosa di totalmente ovvio che farebbe tutto questo in una riga di codice?
39
julien_c

Potrei fraintendermi, ma perché non usare wp_create_nav_menu()?

Ad esempio, questo è quello che faccio per creare un menu personalizzato BuddyPress quando rilevo BP come attivo:

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

Come complemento alla copia di ZaMoose, ecco come si creerebbe una voce di menu " Pagina - type" (non una " 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'));

Supponendo che tu conosca solo la lumaca della pagina, per esempio.

12
julien_c

Ho alcuni problemi con la risposta accettata, che non rendono sbagliato, ma pubblicherò il mio codice al di sotto del quale ritengo che potrebbe avere un risultato migliore per alcune persone poiché avevo la stessa domanda ma volevo fare lo stesso cosa con meno codice.

Innanzitutto, il codice sopra crea elementi di navigazione di tipo "URL", che va bene per alcune persone ma voglio collegarmi alle PAGINE, non agli URL perché questa è una caratteristica importante delle navigazioni di WordPress e i client inevitabilmente spostano le cose così non uso mai l'URL tipo di oggetto nav.

Inoltre, solo una serie di bambini è gestita dal codice pubblicato. Ho creato una funzione per dichiarare in modo ricorsivo i nuovi elementi di navigazione, archiviare i loro metadati restituiti (principalmente ID dopo essere stati creati nel ciclo) e un parametro per accettare i bambini.

Basta modificare $nav_items_to_add e il resto viene gestito in modo ricorsivo. Ci sono 3 chiavi richieste in ogni array. Innanzitutto, la chiave dell'array è lo slug, quindi 'shop' => array( ... ) è ciò che si desidera per una pagina con lo slug shop. ['title']è il modo in cui l'elemento di navigazione sarà etichettato sul front-end. path è il percorso della pagina all'interno della gerarchia di pagine di WordPress, quindi questo è identico allo slug se la pagina è un genitore di primo livello, e se shop fosse figlio di home allora sarebbe 'path' => 'home/shop'.

L'ultima chiave di array opzionale è ['parent'] in cui è possibile dichiarare un'altra chiave nell'array come principale di quella corrente. È importante notare che gli oggetti sono aggiunti in modo ricorsivo, quindi il genitore deve esistere prima di provare a creare un figlio. Ciò significa che la dichiarazione deve essere eseguita per l'elemento di navigazione principale prima che siano figli.

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

    }
9
Brian

Per aggiungere una voce di menu a livello di codice. puoi collegarti al filtro wp_nav_menu_items. posiziona sotto il codice nel tuo theme functions.php per aggiungere la voce di menu login/logout nel menu principale. 'Primario' è il nome/id del menu registrato.

/**
 * 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;
}
2
Aamer Shahzad