Aggiungere a livello di programmazione un menu di navigazione e voci di menu


42

Tramite le funzioni API, desidero definire un nuovo menu di navigazione , selezionarlo nel tema corrente, quindi inserire alcune pagine come voci di menu. Questo deve essere fatto ad esempio con l'attivazione di un tema.

Attraverso un processo (moderatamente doloroso) di reverse engineering, il database inserisce e aggiorna dopo aver impostato manualmente il menu e gli elementi di navigazione, ho messo insieme i seguenti passaggi, in cui "footer-nav" è l'ID slug del menu di navigazione I " sto 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 per farlo?
  • mi sto perdendo qualcosa di totalmente ovvio che farebbe tutto questo in una riga di codice?

Risposte:


43

Potrei fraintenderti, ma perché non usarlo wp_create_nav_menu()?

Ad esempio, questo è ciò che faccio per creare un menu BuddyPress personalizzato 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 );
    }

Non sapevo di questa funzione. Sì, suppongo che renderà il codice sopra molto più breve. Immagino che dovrei andare oltre il Codice e immergermi nel codice reale, poiché trovo che le funzioni API siano spesso, come in questo caso, di livello troppo basso. Grazie!
julien_c

@julien_c se questo viene risolto, contrassegnalo come tale per consentire a coloro che vengono dopo di te di beneficiare della tua esperienza qui.
mor7ifer

Voglio solo testarlo nella vita reale, quindi sono sicuro che fa quello che voglio. Ricorderò di averlo contrassegnato come risolto non appena avrò finito!
julien_c

3
Se vedi funzioni utili come queste che non sono nel codice, è una buona idea aggiungerle (yay wiki) = p
Tom J Nowell

Mi dispiace che ci sia voluto così tanto tempo per verificare che funzionasse nel mio caso. Risposta accettata! Inoltre, stai definendo voci di menu di collegamenti personalizzati , ho aggiunto una risposta di seguito per definire i collegamenti di pagina (che saranno più robusti per le modifiche all'URL, ad esempio).
julien_c,

12

Come complemento alla risposta di ZaMoose, ecco come creare una voce di menu "Tipo di pagina " (non una " Personalizzata "):

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 di pagina, per esempio.


9

Ho alcuni problemi con la risposta accettata - questo non lo rende sbagliato, ma posterò il mio codice sotto il 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", il che va bene per alcune persone ma voglio collegarmi a PAGINE, non a URL perché questa è una caratteristica importante delle navigazioni di WordPress e i client inevitabilmente spostano le cose in modo da non usare mai l'URL tipo di elemento di navigazione.

Inoltre, solo una matrice piatta di bambini viene gestita dal codice pubblicato. Ho creato una funzione per dichiarare ricorsivamente i nuovi elementi di navigazione, archiviando i loro metadati restituiti (principalmente ID dopo essere stati creati nel ciclo) e un parametro per accettare i figli.

Modifica $nav_items_to_adde il resto viene gestito in modo ricorsivo. Vi sono 3 chiavi richieste in ciascun array. Innanzitutto, la chiave dell'array è lo slug, quindi 'shop' => array( ... )è quello che vuoi per una pagina con lo slug shop. ['title']è il modo in cui l'elemento di navigazione verrà etichettato sulla parte frontale. pathè il percorso della pagina all'interno della gerarchia di pagine di WordPress, quindi questo è identico alla lumaca se la pagina è un genitore di livello superiore e se shopfosse una figlia di homeallora lo sarebbe 'path' => 'home/shop'.

L'ultima chiave dell'array opzionale è ['parent']dove puoi dichiarare un'altra chiave dell'array come genitore di quella corrente. È importante notare che gli elementi vengono aggiunti in modo ricorsivo, quindi il genitore deve esistere prima di provare a creare un figlio. Ciò significa che la dichiarazione dovrebbe avvenire per l'elemento di navigazione principale prima che sia figlio.

    $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

Per aggiungere una voce di menu a livello di codice. puoi agganciare al wp_nav_menu_itemsfiltro. inserisci sotto il codice nel tuo tema Functions.php per aggiungere la voce di menu di 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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.