wp_get_nav_menu_items() non funziona con lo slug
Secondo la documentazione, il parametro 1 di wp_get_nav_menu_items()
accetta
(string) (Obbligatorio) Nome del menu, ID o slug.
Ecco come registro i miei menu
register_nav_menus(
array(
'primary' => 'Navigazione principale',
'secondary' => 'Navigazione secondaria',
)
);
Ecco come ho provato a caricarne uno
var_dump( wp_get_nav_menu_items('primary') ); // bool(false)
var_dump( wp_get_nav_menu_items('navigazione-principale') ); // bool(false)
var_dump( wp_get_nav_menu_items('Navigazione principale') ); // bool(false)
var_dump( wp_get_nav_menu_items(51) ); // array([...]) (corretto)
Quindi, la funzione restituisce il menu solo quando uso l'ID. Preferirei usare lo slug poiché il mio sito è multilingua e non voglio dover usare ID diversi a seconda della lingua.
Sto facendo qualcosa di sbagliato o è un bug del core? Ho provato questo tema TwentySixteen con il mio plugin multilingua disabilitato (Polylang).

Dato che nessuno ha veramente spiegato perché la funzione non funziona nel modo in cui pensavi, cercherò di spiegarlo in dettaglio, dato che sono caduto nella stessa trappola.
Questo è il punto in cui la documentazione non è molto chiara su ciò a cui si riferisce lo "slug". La maggior parte delle persone presumerebbe che sia lo slug del menu registrato, ma non è corretto. In realtà, è lo slug del termine per la tassonomia nav_menu.
Analizziamo il codice sorgente per vedere come il core di WordPress interpreta lo slug del menu.
function wp_get_nav_menu_items( $menu, $args = array() ) {
$menu = wp_get_nav_menu_object( $menu );
....
La prima riga mostra che utilizza una funzione chiamata wp_get_nav_menu_object() per recuperare il menu. Passa $menu
come primo parametro a questa funzione. Poiché questo è ciò che usiamo per il nostro slug, dovremo analizzare il sorgente di wp_get_nav_menu_object()
.
function wp_get_nav_menu_object( $menu ) {
$menu_obj = false;
if ( is_object( $menu ) ) {
$menu_obj = $menu;
}
if ( $menu && ! $menu_obj ) {
$menu_obj = get_term( $menu, 'nav_menu' );
if ( ! $menu_obj ) {
$menu_obj = get_term_by( 'slug', $menu, 'nav_menu' );
}
if ( ! $menu_obj ) {
$menu_obj = get_term_by( 'name', $menu, 'nav_menu' );
}
}
....
Possiamo vedere che questa funzione utilizza get_term_by
per recuperare l'oggetto $menu_obj
. Questo è da dove otteniamo il nostro menu.
Quando crei un menu nell'area amministrativa di WordPress, viene creato un nuovo termine. I termini hanno slug basati sul loro nome. Quindi, se hai un menu chiamato "Il Mio Fantastico Menu", WordPress genererà uno slug chiamato "il-mio-fantastico-menu". Potresti aver registrato il menu come "primary", ma non è questo lo slug a cui si riferiscono queste funzioni. È in realtà lo slug del termine del menu.
Per chiarire, supponiamo che tu abbia registrato un menu così:
register_nav_menu('primary', 'il mio menu principale');
primary
non è lo slug. il-mio-menu-principale
non è lo slug.
Poiché abbiamo creato un menu chiamato "Il Mio Fantastico Menu" (come esempio), e lo slug è 'il-mio-fantastico-menu', puoi recuperarlo così:
$awesome_menu = wp_get_nav_menu_items( 'il-mio-fantastico-menu' );
Puoi verificare tu stesso quale sia lo slug controllando il database nella tabella wp_terms (o qualsiasi sia il tuo prefisso) e cercare il nome del tuo menu lì.
Dato che stai utilizzando un sito multilingue o addirittura un multisite, questo metodo non sarà il migliore. Poiché il nome e lo slug potrebbero essere diversi.
Quindi il metodo migliore è ottenere tutte le posizioni dei menu con get_nav_menu_locations()
, che restituirà un array associativo in cui la chiave è lo slug del menu registrato e il valore è l'id del termine del menu selezionato per quella posizione.
Con l'id del termine, possiamo ottenere le informazioni di quel termine e quindi restituire lo slug corretto richiesto dalla funzione.
Di seguito è riportata una funzione che utilizza wp_get_nav_items()
ma a cui passerai lo slug del menu registrato. Nel tuo caso sarebbe 'primary'.
Soluzione Codice
// un nome di funzione piuttosto lungo, ma va bene lo stesso
function get_menu_items_by_registered_slug($menu_slug) {
$menu_items = array();
if ( ( $locations = get_nav_menu_locations() ) && isset( $locations[ $menu_slug ] ) ) {
$menu = get_term( $locations[ $menu_slug ] );
$menu_items = wp_get_nav_menu_items($menu->term_id);
}
return $menu_items;
}

Piccola modifica alla risposta accettata
Dopo aver rimosso un menu dalla posizione dei menu, $locations[ $menu_slug ]
restituisce 0
, quindi è bene aggiungere questo controllo:
function get_menu_items_by_registered_slug($menu_slug) {
$menu_items = array();
if ( ($locations = get_nav_menu_locations()) && isset($locations[$menu_slug]) && $locations[$menu_slug] != 0 ) {
$menu = get_term( $locations[ $menu_slug ] );
$menu_items = wp_get_nav_menu_items($menu->term_id);
}
return $menu_items;
}

Prova questo:
$menu_name = 'primary';
if ( ( $locations = get_nav_menu_locations() ) && isset( $locations[ $menu_name ] ) ) {
$menu = wp_get_nav_menu_object( $locations[ $menu_name ] );
$menu_items = wp_get_nav_menu_items($menu->term_id);
// Il tuo codice di output
}

Non sembra funzionare per me. get_nav_menu_locations()
restituisce un array con un singolo elemento ('primary' => 51
), ma wp_get_nav_menu_items()
restituisce false quando si utilizza uno slug.

custom_menu('primary');
function custom_menu( $theme_location ) {
if ( ($theme_location) && ($locations = get_nav_menu_locations()) && isset($locations[$theme_location]) ) {
$menu = get_term( $locations[$theme_location], 'nav_menu' );
$menu_items = wp_get_nav_menu_items($menu->term_id);
//il tuo codice per il menu.
}
