Come Inserire Elementi Personalizzati nel Menu WordPress in Modo Programmato

23 apr 2011, 19:24:11
Visualizzazioni: 44.4K
Voti: 23

Esiste un modo per inserire programmaticamente elementi personalizzati nel menu quando il tema viene installato per la prima volta? Sto creando un tema che creerà automaticamente alcune pagine comuni durante l'installazione. Quindi, ho bisogno di sapere se posso anche aggiungerle al menu personalizzato di WordPress in modo che il cliente non debba aggiungerle manualmente.

In altre parole: come inserire/creare elementi del menu personalizzato in modo programmatico?

Fatemi sapere se qualcosa non è chiaro. Suggerimenti per la pagina appropriata del codex sono benvenuti. Grazie!


aggiornamento: ho provato il codice da qui Targeting specific menu with wp_nav_menu_items

Registrazione del menu:

function register_my_menus() {
  register_nav_menus(
    array('main-menu' => __( 'Menu Principale' ) )
  );
}

add_action( 'init', 'register_my_menus' );

Utilizzo nel template:

<?php wp_nav_menu( array( 'theme_location' => 'main-menu' ) ); ?>

Codice per aggiungere nuovi elementi:

function new_nav_menu_items($items) {
    if( $args->theme_location == 'main-menu' ){
    $homelink = '<li class="home"><a href="' . home_url( '/' ) . '">' . __('Home') . '</a></li>';
    $items = $homelink . $items;
    return $items;
    }
}
add_filter( 'wp_nav_menu_items', 'new_nav_menu_items', 10, 2 );

Quando aggiungo il codice per inserire nuovi elementi nel menu di navigazione nel file functions.php, non succede nulla nella pagina del menu nel pannello di amministrazione, ma gli elementi del menu corrente scompaiono nel sito!

0
Tutte le risposte alla domanda 4
14
25

Il problema con il tuo codice è che in realtà non sta aggiungendo i link al menu ma solo all'output del menu, da qui l'uso di un filtro (add_filter) quindi stai solo filtrando l'output del menu infatti anche se non hai un menu il tuo link verrà mostrato con il codice che stai usando. Ma per creare un link e aggiungerlo a un menu puoi usare questo codice:

$run_once = get_option('menu_check');
if (!$run_once){
    //dai un nome al tuo menu
    $name = 'menu predefinito del tema';
    //crea il menu
    $menu_id = wp_create_nav_menu($name);
    //poi ottieni l'oggetto menu dal suo nome
    $menu = get_term_by( 'name', $name, 'nav_menu' );

    //poi aggiungi il link effettivo/voce di menu e lo fai per ogni elemento che vuoi aggiungere
    wp_update_nav_menu_item($menu->term_id, 0, array(
        'menu-item-title' =>  __('Home'),
        'menu-item-classes' => 'home',
        'menu-item-url' => home_url( '/' ), 
        'menu-item-status' => 'publish'));

    //poi imposti la posizione desiderata nel tema
    $locations = get_theme_mod('nav_menu_locations');
    $locations['main-menu'] = $menu->term_id;
    set_theme_mod( 'nav_menu_locations', $locations );

    // poi aggiorni l'opzione menu_check per assicurarti che questo codice venga eseguito solo una volta
    update_option('menu_check', true);
}

Ho commentato tutto per renderlo più semplice.

Per creare una pagina figlio/sottopagina/menu di secondo livello (come preferisci chiamarlo), devi solo impostare menu-item-parent-id nel nuovo elemento, ad esempio:

//crea la voce di menu di primo livello (home)
$top_menu = wp_update_nav_menu_item($menu->term_id, 0, array( 
    'menu-item-title' =>  __('Home'),
    'menu-item-classes' => 'home',
    'menu-item-url' => home_url( '/' ), 
    'menu-item-status' => 'publish'
    'menu-item-parent-id' => 0,
    ));
//Voce di sottomenu (primo figlio)
$first_child = wp_update_nav_menu_item($menu->term_id, 0, array( 
    'menu-item-title' =>  __('First_Child'),
    'menu-item-classes' => 'home',
    'menu-item-url' => home_url( '/' ), 
    'menu-item-status' => 'publish'
    'menu-item-parent-id' => $top_menu,
    ));
//Voce di sottosottomenu (secondo figlio)
$Second_child = wp_update_nav_menu_item($menu->term_id, 0, array( 
    'menu-item-title' =>  __('Second_Child'),
    'menu-item-classes' => 'home',
    'menu-item-url' => home_url( '/' ), 
    'menu-item-status' => 'publish'
    'menu-item-parent-id' => $first_child,
    ));

puoi anche impostare la posizione via codice con menu-item-position e penso si faccia così:

  • Primo elemento - 'menu-item-position' => 1
    • Primo figlio del primo elemento - 'menu-item-position' => 1
    • Secondo figlio del primo elemento - 'menu-item-position' => 1
      • Primo figlio del secondo figlio del primo elemento - 'menu-item-position' => 1
  • Secondo elemento - 'menu-item-position' => 2
  • Terzo elemento - 'menu-item-position' => 3
  • Quarto elemento - 'menu-item-position' => 4
24 apr 2011 06:03:11
Commenti

Queste sono le funzioni che stavo cercando :) il codex non le includeva :( Un'altra domanda: come posso aggiungere un elemento figlio alla voce Home. Ti farò sapere appena arrivo al mio pc. Grazie!

Sisir Sisir
24 apr 2011 20:42:31

@Sisir: ho aggiornato con un esempio su come creare pagine figlie

Bainternet Bainternet
25 apr 2011 03:12:57

@Bainternet: ho ricevuto questo errore quando ho eseguito il codice per la prima volta Fatal error: Cannot use object of type stdClass as array in C:\wamp\www\citystir\wp-admin\menu.php on line 25. Ma il menu viene creato e quando la pagina viene aggiornata tutto funziona, però non viene mostrato nulla nella sezione Aspetto -> Posizioni menu del tema. Ci siamo quasi :) Grazie!

Sisir Sisir
28 apr 2011 22:36:24

@Bainternet: Immagino che il codice stia generando un errore quando cerca di eseguire la riga $locations = get_theme_mod('nav_menu_locations'); Quindi, il codice prima di questa riga (tutta l'inserzione dei menu viene eseguita) viene processato mentre il codice dopo (che imposta la posizione del tema desiderata) non viene eseguito.

Sisir Sisir
28 apr 2011 22:48:38

@Sisir: il codice funziona perfettamente, qual è il nome della posizione del tuo tema e mostrami il codice esatto che stai usando, vedrò se posso aiutarti.

Bainternet Bainternet
29 apr 2011 03:26:01

@Bainternet: Ecco http://pastebin.com/Px16q43a. Ho usato Pastebin.

Sisir Sisir
29 apr 2011 19:35:00

@Sisir: qual è il nome della tua posizione del menu?

Bainternet Bainternet
29 apr 2011 21:46:52

ho usato questo codice nel menu di navigazione wp_nav_menu( array( 'theme_location' => 'main-menu' ) ); quindi immagino che il nome della posizione del tema sia main-menu, giusto?

Sisir Sisir
30 apr 2011 10:54:09

sì, ma devi comunque registrare questa posizione del tema usando register_nav_menu( $location, $description ); prima di provare ad assegnare un menu a quella posizione.

Bainternet Bainternet
30 apr 2011 15:04:16

@Bainternet: Grazie! Il nome della posizione del tema ora è visibile. Ma l'errore era ancora presente finché non l'ho inserito in una funzione e poi aggiunto la funzione nella pagina delle opzioni del tema. Ora verrà eseguito solo quando si clicca il pulsante. Sembra che in questo modo l'errore sia sparito. Tutto funziona bene ora. Grazie per tutto il tuo aiuto. Spero che tu riesca sempre a rispondere alle mie domande ;)

Sisir Sisir
1 mag 2011 14:19:45

Felice che tu l'abbia risolto.

Bainternet Bainternet
1 mag 2011 17:00:05

@Bainternet: Ciao, devo disturbarti ancora :) Con la funzione wp_update_nav_menu_item() le voci del menu vengono aggiunte come link personalizzati. C'è un modo per aggiungere voci di menu di tipo post o pagina? Il problema è che ora, quando aggiorno il mio permalink, i link personalizzati non si aggiornano. Ma se fosse una voce di menu di tipo pagina, si aggiornerebbe automaticamente. Penso di essere stato chiaro. Grazie!

Sisir Sisir
23 mag 2011 23:50:13

@Bainternet: Ciao, l'attributo menu-item-position deve essere incrementale dall'elemento superiore del menu fino a quello inferiore, indipendentemente dal fatto che ci siano o meno sotto-elementi. Ho trovato questa informazione qui: http://www.acousticwebdesign.net/wordpress/how-to-create-wordpress-3-navigation-menus-in-your-theme-or-plugin-code/.

Clawsy Clawsy
12 mag 2016 09:46:10

Anche dopo 9 anni, informazioni ancora utili!

Beee Beee
6 dic 2020 02:54:57
Mostra i restanti 9 commenti
1
12

Il tuo codice originale era molto vicino all'obiettivo e penso seriamente che questa soluzione lunga di @Bainternet (senza offesa) sia eccessiva, quindi dai un'occhiata a questa invece:

function new_nav_menu_items($items, $args) {
    if( $args->theme_location == 'primary' ){
        $homelink = '<li class="home"><a href="' . home_url( '/' ) . '">' . __('Home') . '</a></li>';
        $items = $homelink . $items;
    }
    return $items;
}
add_filter( 'wp_nav_menu_items', 'new_nav_menu_items', 10, 2 );

Il tuo unico problema era che non restituivi $items dopo che la funzione aveva verificato il menu corretto, e ti mancava il secondo argomento di callback necessario per effettuare il controllo ($args).

1 ago 2012 13:43:05
Commenti

Come imposteresti la posizione dell'elemento del menu utilizzando questo metodo?

User User
4 nov 2014 03:05:11
0

C'è un bug in WordPress 3.4.2:

https://github.com/WordPress/WordPress/commit/ae96b842f9f55ecfb22da705a4902b9d25580259#wp-includes/nav-menu.php

È necessario creare manualmente la relazione del termine:

$menu = wp_get_nav_menu_object('top menu');
$id = wp_update_nav_menu_item($menu->term_id, 0, $data);

if ($menu->term_id && (!is_object_in_term($id, 'nav_menu', (int)$menu->term_id))) {
    wp_set_post_terms($id, array((int)$this->id), 'nav_menu');
}

Vedi https://gist.github.com/4148529 per un esempio della classe Menu per la creazione semplice di menu.

26 nov 2012 16:29:38
0

Per informazione, l'utente corrente deve avere i permessi per aggiungere termini. I miei menu_items erano stati creati ma non aggiunti nella tabella wp_terms_relationship prima che io aggiungessi una chiamata a wp_set_current_user(1);

2 ago 2013 16:43:18