Come Inserire Elementi Personalizzati nel Menu WordPress in Modo Programmato
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!

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

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!

@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!

@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: 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: Ecco http://pastebin.com/Px16q43a. Ho usato Pastebin.

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?

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

@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!

@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/.

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).

C'è un bug in WordPress 3.4.2:
È 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.
