Le funzioni wp_list_pages e wp_page_menu di WordPress

Un confronto tra le due soluzioni disponibili per creare un menu di navigazione.

Su WordPress esistono due funzioni php essenziali per la gestione dei menu di navigazione: wp_list_pages e wp_page_menu. Che abbiate un semplice blog o un sito più complesso, in ogni caso avrete quasi sempre bisogno di un menu di navigazione, anche solo per includere i link alla homepage, alla pagina about ed a quella dei contatti.

Le due funzioni hanno alcune differenze: wp_page_menu è stata introdotta dalla versione 2.7 e va ad estendere wp_list_pages, che comunque fa ancora egregiamente il suo dovere. Recentemente mi sono imbattuto in queste funzioni per un aggiornamento al tema Stardust, ed ho deciso di condividere quello che ho scoperto.

La funzione wp_list_pages

Se lavorate con WordPress, conoscerete bene questo template tag, esistente ormai da anni:

<?php wp_list_pages(); ?>

Il suo punto di forza sono le possibilità di personalizzazione.

Escludere una pagina dal menu

Una delle opzioni più usate è quella che consente di nascondere dal menu alcune pagine. Per farlo è sufficiente usare il parametro exclude (in questo caso elimina dall’elenco le pagine con ID 1 e 7:

<?php wp_list_pages('exclude=1,7'); ?>

Mostrare solo le pagine di primo livello

Un altro parametro molto utile è depth, che permette di nascondere tutte le sottopagine e controllare la profondità del menu:

<?php wp_list_pages('depth=1'); ?>

In questo caso, depth=1 mostra solo le pagine di primo livello.

Nascondere il titolo

Se invece non avete bisogno del titolo prima dell’elenco delle pagine, ad esempio perché il menu non è nella sidebar ma disposto in orizzontale, potete usare il parametro title_li:

<?php wp_list_pages('title_li='); ?>

La funzione wp_list_pages offre ottime possibilità di personalizzazione, e spesso è più che sufficiente. Per tutti i dettagli vi consiglio di consultare anche la pagina ufficiale su WordPress.org, dove sono illustrati i parametri utilizzabili ed i rispettivi valori.

La funzione wp_page_menu

Dalla versione 2.7 di WordPress è stato introdotta la funzione wp_page_menu, che aumenta le possibilità a disposizione degli sviluppatori. La differenza principale con wp_list_pages è nel codice che viene generato, e nella possibilità di mostrare un link alla homepage.

Usando la funzione

<?php wp_page_menu(); ?>

Questo sarà l’HTML creato:

<div class=”menu”>
  <ul>
    <li class=”current_page_item”><a href=”…” title=”…”>Pagina attiva</a></li>
    <li class=”page_item”><a href=”…” title=”…”>Pagina</a></li>
    …
  </ul>
</div>

Non c’è quindi bisogno di aggiungere codice HTML intorno alla funzione php, tutto il necessario viene generato automaticamente.

Cambiare la classe associata al menu

Per cambiare la classe del menu, è sufficiente usare il parametro menu_class:

<?php wp_page_menu('menu_class=navigation'); ?>

Mostrare un link alla home nel menu

La novità principale però riguarda il parametro per includere automaticamente un link alla homepage:

<?php wp_page_menu('show_home=1'); ?>

Utilizzando wp_list_pages questo era possibile solo inserendo manualmente nel template un link alla home, ma è una soluzione poco elegante. Inoltre possono esserci problemi quando la prima pagina del blog è una pagina statica: il link alla homepage apparirebbe duplicato.

Con wp_page_menu questo non accade: con un parametro è possibile gestire tutto senza problemi.

Altri parametri

Una caratteristica non è specificata sulla documentazione ufficiale, ma è fondamentale: la funzione wp_page_menu supporta tutti i parametri di wp_list_pages, essendo un’estensione di quest’ultima.

Se ad esempio volete creare un menu con classe “nav”, mostrando anche la homepage e solo un livello di profondità, questa è la funzione:

<?php wp_page_menu('menu_class=nav&show_home=1&depth=1'); ?>

Potete approfondire il discorso sulla pagina di wordpress.org dedicata alla funzione, ricordandovi quindi anche di wp_list_pages.

Quale funzione utilizzare?

La presenza di due funzioni simili potrebbe confondere le idee, ed in effetti viene da chiedersi quale sia l’utilità del conservarle entrambe. La risposta è da cercare nella retrocompatibilità per le vecchie versioni di WordPress.

Se però dovete sviluppare un nuovo tema e non avete problemi di questo tipo, il mio consiglio è di sfruttare fin da subito wp_page_menu. I vantaggi non sono incredibili ma ci sono: i vostri visitatori non noteranno niente di diverso, ma voi avrete un codice più facile da mantenere.

Vuoi far crescere il tuo progetto online?

Tommaso Baldovino

UX/UI Designer, professionista del web con più di 15 anni di esperienza su WordPress. Sono disponibile a seguire nuovi progetti dall'ideazione alla realizzazione finale. Scrivo ogni 2 settimane la mia newsletter.

50 commenti su “Le funzioni wp_list_pages e wp_page_menu di WordPress”

  1. molto interessante come cosa, questo fa parte sempre dei miei TODO cioè trovare il tempo di mettermi a studiare seriamente WP

    ciao

  2. Interessante soprattutto il link alla Home, non conoscevo il comando.
    Conosci per caso qualche modo “semplice” per richiamare all’occorrenza le thumbnail delle pagine nell’elenco?

    Io per ora ho risolto modificando il file wp-includes/classes.php con una funzione che ho trovato in giro per la rete, ma è parecchio contorto…

    Ciao
    Zave

  3. @Zave: forse si può fare qualcosa sfruttando il parametro link_before, aggiunto proprio dalla versione 2.7 di WordPress, che ti permette di inserire del codice prima del link. Devi però provvedere tu a recuperare le immagini che ti interessano e ad inserirle nel menu.

  4. bhe, è comunque interessante, stasera mi documento un po’ =)
    comunque non risolve il mio problema, se vuoi ti passo la soluzione che ho trovato che, per quanto macchinosa, è interalmente personalizzabile.

  5. Credo che l’utilità di avere un link per la home separato dal resto delle pagine sta nel poter applicare una classe che prevede a sinistra del link un separatore per le pagine, e senza per la home. Se si usa wp_page_menu questo non è applicabile (forse, è più che altro una questione di gusto) in quanto la classe applicata ai link è la stessa per home e le altre pagine.

    Ad ogni modo utilissimo articolo, grande Tom ;)

  6. E’ possibile fare in modo che il codice generato per , ad esempio:

    Home
    AZIENDA

    contenga solo il riferimento al numero di ID e non le parole page_item page-item, ovvero:

    Home
    AZIENDA

    Grazie.

  7. @natspace: non puoi modificare le classi di default assegnate alle voci del menu, sono standard comuni a tutti i temi di WordPress ed è bene che siano sempre presenti. Puoi dare un’occhiata alle pagine ufficiali delle funzioni su wordpress.org per capire quali parametri puoi cambiare.

  8. @francesco: non c’è una risposta univoca, perché tutto dipende dal tema che stai utilizzando. In genere i menu di navigazione sono nel file header.php, ma potresti trovare delle differenze. E’ molto probabile che dopo aver inserito queste righe di php ci sia anche qualcosa da sistemare per quanto riguarda l’aspetto, tramite il CSS (style.css).

  9. Grazie per la risposta veloce. Ma ahime ti ripeto sono ignorante e non so proprio dove mettere le mani.Il thema cmq è studiopress.Ho controllato e i riferimenti al menù sono nell’header ma nn so come modifircala, anche perchè non c’e’ nessuna delle due funzioni che tu hai descritto chiaramente nell’articolo.Il mio problema è che voglio far corrispondere all’home page una pagina statica senza che questa appaia poi ne menù.Mahh,se la metto privata non mi funziona.Per i lettori di questo blog sarà sicuramente semplice,ma per me è un rompicapo. Cmq grazie per il tempo concessomi.

  10. @francesco: la soluzione migliore per il tuo problema è creare la pagina ed impostarla come home da Impostazioni – Lettura del pannello di amministrazione.

    Se ti appare comunque nel menu, devi escluderla aggiungendo un parametro sul template header.php, nel punto dove viene creato il menu. Probabilmente troverai qualcosa di molto simile a wp_list_pages();, ti basta aggiungere il parametro exclude

    wp_list_pages(‘exclude=2’)

    dove “2” è l’ID della pagina da nascondere. Il valore dell’ID lo trovi quando modifichi la pagina, nella barra degli indirizzi: …/post.php?post=2&action=edit

  11. Avevo gia fatto questo cioè in impostazioni lettura mettere la prima pagina come una pagina statica creata e va bene pero’ questa pagina mi appare nel menù, se la metto privata non funziona.Per quanto riguarda la funzione wp_list_pages non c’e’ nel mio header.Scusa, no so sefaccio bene ma vorrei farti vedere come viene creato il menù nel mio header.Se il commento diventa troppo lungo non sò magari cancellalo.Comunque grazie per il tempo e la pazienza concessami.
    ecco il codice

    get_results(‘select ID, post_title from ‘. $wpdb->posts .’ where post_status = “publish” and post_type = “page” order by ID’);

    }
    return $these_pages;
    }

    function list_all_pages(){

    $all_pages = get_the_pa_ges ();
    foreach ($all_pages as $thats_all){
    $the_page_id = $thats_all->ID;

    if (is_page($the_page_id)) {
    $addclass = ‘ class=”current_page”‘;
    } else {
    $addclass = ”;
    }
    $output .= ‘ID).'” title=”‘.$thats_all->post_title.'”>’.$thats_all->post_title.”;
    }

    return $output;
    }
    ?>

    <?php

    if (is_home()) {
    $addclass = ' class="current_page"';
    } else {
    $addclass = '';
    }
    echo "Home”;
    echo list_all_pages();?>

    In pratica io riesco nè ad ordinare le pagine e nè a nasconderle.

  12. scusa non l’aveva incollato.
    inizia così e continua nel commento di prima

  13. Ho visto adesso, il tema è molto vecchio ed infatti usa delle funzioni diverse dalle solite. Puoi provare a modificare questa riga:

    $these_pages = $wpdb->get_results(‘select ID, post_title from ‘. $wpdb->posts .’ where post_status = “publish” and post_type = “page” order by ID’);

    in questo modo:

    $these_pages = $wpdb->get_results(‘select ID, post_title from ‘. $wpdb->posts .’ where post_status = “publish” and post_type = “page” and ID != 2 order by ID’);

    dove 2 è il solito ID della pagina che ti dicevo prima.

  14. Grazie per la pazienza che stai avendo e per il tempo che mi stai concedendo ma non funziona.
    Ho cambiato la riga e se la copia senza i parametri strong ilbrowser non carica la pagina e mi dice che c’e’ un errore di sintassi. Se la copio con iparametri strong dal menu spariscono tutte le pagine esclusa la home che poi come contenuto corrisponde alla 2

  15. Ho fatto una prova, se in quella riga aggiungi “and ID != x” dove X è l’ID della pagina che vuoi eliminare funziona tutto come previsto. Magari sbagli a scrivere qualcosa, non saprei. Prova a controllare, se per caso avessi ancora problemi scrivimi direttamente tramite il modulo contatti.

  16. Ho una domanda da poco esperto.

    Devo personalizzare un tema introducendo in una sidebar a sinistra un menu con le pagine fino a 3 livelli (pagine, sottopagine e sotto-sotto-pagine) tipo:
    -pagina1
    -pagina1.sp1
    -pagina1.sp1.ssp1
    -pagina1.sp1.ssp2
    -pagina1.sp2
    -pagina1.sp3
    -pagina2
    -pagina2.sp1
    -pagina2.sp2

    Ho provato in diversi modi usando widget page, flexi widget page, e utilizzando un widget per inserire codice php puro (inserendo di conseguenza dentro le funzioni wp_list_pages o wp_nav_pages di cui parli in questo post con vari parametri).

    Le pagine e sottopagine vengono tutte stampate bene.

    Quello che non riesco a gestire bene è l’evidenziazione delle settopagine di secondo livello (so che si deve lavorare con i css su current_page_item), ma questo ancora ancora passi. Credo che si debba lavorare sulle classi .current_page_item (.current_page_ancestor forse anche perche’ nelle prove che ho fatto quando evidenziavo le sotto-sottopagine rimanevano evidenziate anche le sottopagine …)

    Il problema piu’ grosso però e’ il menu la gestione dell’apertura del menu.

    Vorrei che quando sono su
    -pagina1.sp1.ssp1

    e clicco su

    -pagina1.sp1.ssp2

    il menu (l’albero della pagina) rimanesse aperto ed invece di chiude facendo vedere solo le pagine (e non le sottopagine).

    Ho provato in tutti i modi. Qual e’ la strada giusta ?

    sul codex wordpress di wp_list_pages c’e’ del codice css che dicono essere per “accordion menu effect”
    che dovrebbe essere l’effetto a fisarmonica del menu che intendo io e lavora su display none e block delle classi del menu, ma dalle prove che ho fatto non funziona.

    Mi sapreste dare un consiglio per instradarmi ?
    Grazie

  17. salve,
    ilmenu di navigazione, composto al momento da due righe e tante colonne … non è fisso ma dinamico. C’è un modo per fare restare fisso?

    Mi spiego …a volte, invece di stare su 2 righe si mette su tre a altera il funzionamento … qualche suggerimento?

    Grazie

  18. @mimmo il problema è sul layout del tuo sito: il menu che usi è fatto per funzionare su una sola riga. E’ già tanto che funzioni su due righe senza scombinare il layout, quando va su tre è normale che si rompa qualcosa.

    La soluzione ideale sarebbe riorganizzare la navigazione, lasciando sul menu orizzontale solo le voci principali su una riga ed eliminare le altre o posizionarle nella barra laterale.

  19. Segnalo un plugin/widget che reputo molto interessante per collocare un menu verticale multilivello contenente le pagine di wordpress: si tratta di Flexi Pages Widget.

    E’ una versione arricchita del widget/plugin Pages ed in pratica da quanto ho capito (nei meccanismi interni) è un wrapper per le due funzioni di cui parli tu: wp_list_pages e wp_page_menu.

    Ha delle opzioni molto interessanti che in maniera visuale consentono di impostare i parametri delle due funzioni di cui sopra (come escludere pagine dal menu, aggiungere un link alla home etc).

    In particolare segnalo la possibilità di visualizzare quali pagine e sottopagine mostrare nel momento in cui si percorre il menu (la scelta della visualizzazione varia a seconda del livello di correlazione tra le pagine stesse) e fino a quale sottolivello mostrare menu/sottomenu.

    Non sarà perfetto per ogni possibile situazione e desiderato per un menu, ma probabilmente può essere sufficiente in molti casi.

  20. Ciao, e complienti!
    Io avrei la necessità di togliere il menu di navigazione dalla sola homepage.
    Non potendo eliminarlo dall’header.php altrimenti verrebbe tolto a tutte le pagine che richiamano l’header.php come posso escluderlo dalla pagina template che creo per la homage in questione?
    Grazie

    Dario

  21. @Dario devi fare una modifica su header.php, usando i commenti condizionali per nascondere quello che non ti serve sulla homepage. La condizione da controllare è is_home, sulla pagina ufficiale trovi anche degli esempi di utilizzo.

  22. …mmm mastico poco in materia php…
    Diciamo che io apro header.php
    come gli dico: “se sei nella home page non far vedere il menù di navigazione?”
    Il codice dove spunta il menù è il seguente:

    <a href="/”>Home

  23. E’ sufficiente inserire una cosa del genere su header.php:

    Prova e vedi se riesci a fare quello che volevi :)

  24. Caro e gentilissimo Tom, si, avevo letto il link che mi avevi dato, il mio problema è propio come scrivere in php quel
    // Quello che vuoi mostrare in homepage (tutto tranne il menù)
    oppure
    // Tutto quello che non vuoi appaia in homepage (il menù!)

    Nell’header.php il menu di navigazione si trova dentro il DIV class=”navigation” nel cui interno è riportato il seguente codice php (ometto qualche simbolo od ancora poichè sennò non viene visualizzato nel presente post):
    a href=”/”>Home /a>

    Spero il codice si capisca.

  25. Puoi benissimo usare questa sintassi:


    Quello che vuoi mostrare in homepage

    Tutto quello che non vuoi appaia in homepage

    …ed inserire il semplice codice html senza preoccuparti del php. Fai una prova, se hai ancora problemi contattami via mail, ma non saprei spiegartelo meglio di così :)

  26. Ciao complimenti per l’articolo e per i contenuti del sito…..
    Volevo farti una domanda….
    E’ possibile applicare delle classi differenti per ogni singola pagina nella funzione wp_page_menu per poter ottenere una navigazione personalizzata?
    Per esempio per poter utilizzare delle immagini al posto del testo nel menu di navigazione?
    Grazie Filippo….

  27. @Filippo: la funzione wp_page_menu ha sempre una classe fissa, che puoi impostare tra i parametri. Per modificare l’aspetto del menu a seconda della pagina però puoi sfruttare body_class ed i CSS, con dei selettori discendenti.

  28. Ho usato wp_list_pages in un template per far uscire anche le sottopagine, ma mi da fastidio che esce anche quel rettangolo vicino al cursore del mouse dove c’è scritto le stesse parole del bottone del menù. C’è un modo per non farlo uscire?

  29. ciao,
    se io volessi ad esempio avere come pagina genitore una pagina magari chiamata “prodotti” genericamente, e senza usare i drop down menù nella barra principale, ma far apparire all’interno delle thumbnail delle sottopagine ? è possibile ? magari con un plugin specifico ?

    ve lo chiedo perchè sto realizzando un sito con parecchie sottopagine , diciamo una 30ina, e a livello estetico sarebbe sicuramente più gradevole

  30. @roberto: l’aspetto del menu puoi gestirlo come preferisci dai CSS, considera che le funzioni php di cui parlo servono per ricavare un elenco di contenuti in HTML che puoi personalizzare successivamente.

    Potrebbe esserti ancora più utile la funzione wp_nav_menu(): con questa puoi sfruttare le classi CSS su ogni voce relativa ad una sottopagina.

  31. @Tom
    perdonami ti ho perso, con la funzione da te descritta potrei crearmi una pagina genitrice con sole thumb delle sottopagine ?
    ieri cercando ho trovato questo che lo fa parzialmente [child_pages width=”33%”] anche se non è esattamente ciò che cercavo

    Sempre curiosando sul web ho trovato questo sito, http://www.legnopan.com/index.php/it/component/zoo/category/pannelli.html peò realizzato con Joomla, che ha esattamente l’aspetto grafico che vorrei ottenere

    Secondo te è possibile automatizzare il tutto, o mi devo inserire immagine per immmgine e linkarla manualmente ?

    Grazie molte

  32. Ok, ho capito cosa intendi, quello che ti serve è associare ad ogni voce di menu un’immagine, poi però sta a te agire sul CSS per sistemare l’aspetto. Non ho mai fatto niente del genere tramite plugin, ma questo potrebbe tornarti utile per la prima parte del lavoro: Custom menu images.

  33. Grazie del suggerimento Tom
    forse però il metodo più veloce credo sia piuttosto che agire sul CSS lavorare direttamente da una immagine, nel caso specifico penso di crearla da photoshop e poi linkarla con image-maps.com/

  34. Ciao,ho il seguente problema : installando un tema che nella demo faceva comparire i sottomenù passando con il mouse sopra il “genitore” ,una volta installato mi sbatte tutte le pagine in vista,come posso far comparire nel menù solo la pagina “genitore” e nascondere i “figli” che poi compariranno al passaggio del mouse?

  35. @Gabriele: dipende dal tema, potrebbe bastarti andare sulla dashboard in Aspetto -> Menu ed organizzare la navigazione come preferisci. Se non vedi la voce “Menu”, il tema non supporta questa funzione e l’unica è agire sul php del tema. Prima però controlla che le tue pagine siano effettivamente organizzate come vorresti, con la giusta struttura padri-figli.

  36. Ciao, vedo che è un po’ che nessuno commenta l’articolo, ma mi sono imbattuto nel tuo blog perchè ho un problema che non so come affrontare e ho notato che sei molto disponibile e professionale: vorrei personalizzare il mio menu, ho un sito internet che si suddivide in 4 sezioni diverse, vorrei che ognuna di esse avesse il menu di navigazione diverso, va bene che abbiano lo stesso formato, ma vorrei che ogni sezione avesse il suo menu che indirizza a pagina diverse (o uguali).
    Sezione1: servizi, contatti, progetti
    sezione2: servizi, contatti, audio, file

    La homepage è statica e l’ho già creata, le 4 sezioni sono collegate correttamente ad essa tramite 4 pulsanti.
    Spero di essermi spiegato, grazie per l’attenzione

  37. Ciao Guido, in effetti questo post è diventato chilometrico grazie ai commenti, provo ad aiutarti :)

    Per ogni navigazione diversa che vuoi creare, devi generare un menu dall’admin di WordPress nella sezione apposita “Aspetto -> Menu”.
    Non so che tema stai usando, ma è molto probabile che a questo punto ci sia qualcosa da personalizzare nel codice. A te infatti serve poter aggiungere il menu corrispondente ad ogni diversa sezione, e questo puoi farlo solo se il tema prevede uno “slot/posizione” per ogni menu.

    La funzione da utilizzare è wp_nav_menu. Spiegarti in un commento come implementare il tutto è impossibile, ma puoi fare riferimento ad articoli come questi:

    http://wordpress.org/support/topic/custom-menus-on-different-pages
    http://justintadlock.com/archives/2010/06/01/goodbye-headaches-hello-menus

  38. Ciao Tom!! lo so il fai da te non porta mai a grandi risultati. Mi sono dovuto cimentare nella costruzione del mio sito con wordpress usando il tema expositio. La mia domanda è semplice, credo. Vorrei eliminare il link al nome del menu, mi serve solo da titolo per i progetti riportati sotto. tipo: LAVORI, poi sotto i diversi link.

    Se riuscissi a darmi un consiglio sarei felicissimo!!
    Grazie

  39. @sergio: se vuoi usare un tema già pronto non ti consiglio di modificarne il comportamento. Ai successivi aggiornamenti potresti vedere annullate le tue correzioni. L’unico modo per fare una modifica è usare i child themes, vedi cosa riesci a fare in base alle tue conoscenze.
    Non conosco il tema che stai usando, ma si tratta di trovare il punto dove viene inclusa la funzione del menu e aggiungere un titolo.

    Un’alternativa più immediata è quella di creare una pagina “Lavori” e rassegnarti all’idea di averla linkata.

  40. si sapevo degli aggiornamenti e di usare i child themes, ma poi diventa per me complicatissimo.
    Grazie mille per la risposta. Appena avrò due soldi lo farò fare a chi lo fa di per lavoro.
    S