Come sviluppare una navigazione dinamica e mantenibile
In questo articolo vedremo com’é possibilie realizzare una navigazione che sia in grado di evidenziare la pagina corrente nelle voci del menù come in questo esempio. Come puoi vedere, lo stile della voce del menù applicato alla pagina visualizzata é diverso dalle altre voci.
Per ottenere questo risultato in un modo elegante e soprattutto mantenibile dovremo costruire la navigazione “dinamicamente”, ovvero attraverso la programmazione e nella fattispesce con PHP. Anche se i passaggi sono spiegati in modo approfondito, sono comunque necessarie delle conoscenze medie di questo linguaggio per poter seguire e comprendere appieno l’argomento trattato dall’articolo.
Prepariamo le pagine (X)HTML
Iniziamo a preparare le pagine. Nulla di complesso, un elemento per la navigazione a sinistra ed uno per i contenuti a destra.
Iniziamo con la pagina index.php:
<div id="content"> <h1>Pagina home</h1> </div>
Come detto nulla di speciale. Ora puoi salvare questa pagina anche come profile.php, contact.php, newsletter.php, avendo cura di modificare il titolo contenuto nei tag h1.
Il foglio di stile
Passiamo ora al foglio di stile (da me nominato style.css) che come puoi vedere l’ho già collegato al documento nell’head delle pagine appena realizzate.
body{ font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 14px; } #navigation{ width: 200px; padding: 20px; float: left; padding-top: 100px; } a:link,a:visited{ text-decoration: none; } li{ list-style-type: none; margin-bottom: 5px; } li.active{ color:gray; list-style-type: disc; }
Anche il foglio di stile é piuttosto semplice. Negli elementi della lista eliminiamo il marcatore per poi mostrarlo invece negli elementi con classe active. Questa classe é quella che attribuiremo alla voce di menù relativa alla pagina visualizzata.
Rendere la navigazione mantenibile
Visto che, come detto precedentemente, la navigazione verrà creata tramite script PHP, é importante tenere fuori dal codice elementi che potrebbero necessitare di aggiunte o modifiche. Questo piccolo sforzo sull’altare della mantenibilità ci potrebbe rendere molto felici in futuro.
Crea dunque il file navigation.txt nel quale scrivere le voci del menù ed il relativo link separati dal segno “:”.
home:index.php profilo:profile.php contatti:contact.php newsletter:newsletter.php
Sviluppare la funzione “Navigation()”
Crea ora il file funtions.php. Ho scelto questo nome in quanto potremmo utilizzarlo non solo per generare la navigazione, ma anche per portarci appresso una serie di altre funzioni da utilizzare nelle nostre pagine.
Iniziamo a sviluppare la funzione. Quello che dovremo fare é:
- Stabilire in che pagina ci troviamo (index.php, contact.php,…);
- Leggere il contenuto del file navigation.txt ed elaborarlo in modo da disporre delle voci e dei relativi link;
- Verificare se il link corrisponde al nome della pagina visualizzata, nel qual caso dovremo aggiungere la classe active;
Ma prima di tutto é necessario che vi spieghi cos’é un array in quanto ci sarà molto utile.
L’array é un tipo di variabile che contiene una collezione di valori associati ad una chiave. Detto così può sembrare molto complesso, dunque farò subito un esempio pratico.
Dichiariamo l’array $colori
$colori = array("rosso","verde","giallo");
Ora, la variabile
$colori[0]
restituirà rosso (il primo elemento di un array ha chiave 0), mentre
$colori[2]
restituirà giallo (come dire che la chiave “2” ha valore “giallo”)
Un array può essere anche di tipo associativo:
$persona = array("nome" => "Maurizio", "cognome" => "Tarchini");
In questo caso la chiave non é più numerica ma inserita esplicitamente, dunque:
$persona['nome']
restituirà il nome Maurizio.
Mi fermo qui. In realtà un array può raggiungere un livello di complessità enorme; posso ad esempio inserire come valore di un array un altro array. Si parlerà in questo caso di array multidimensionali. Potremmo inoltre dire che ci sono altri modi di valorizzare e manipolare gli array, ma ora non ci interessa.
Iniziamo ora a dichiarare la funzione Navigation() ed a procurarci il nome della pagina attiva.
<!--?php <br ?-->function Navigation() { $activePage = basename($_SERVER['PHP_SELF']);
$_SERVER é una array associativo creato automaticamente, sempre e ovunque disponibile (tecnicamente si dice un array superglobale) che contiene diverse indicazioni riguardanti il server. La chiave PHP_SELF restituisce il percorso/nomeFile della pagina visualizzata.
Tramite la funzione basename() “depuriamo” il risultato dal percorso ottenedo così quello che vogliamo: il nome della pagina visualizzata che inseriremo nella variabile $activePage.
Dovremo ora leggere ed elaborare il contenuto del file navigation.txt. La via migliore é utilizzare la funzione file().
$rows = file('navigation.txt');
Questa funzione legge il contenuto del file che passiamo come argomento e restituisce un array basato sulle righe di questo documento (ogni riga un valore).
Ad esempio $rows[0] conterrà home:index.php
A questo punto quello che dobbiamo fare é:
- Per ogni valore dell’array $rows “spezzare” la stringa sul segno “:” in modo da ottenere il nome da visualizzare nel menù e il link al quale dovrà puntare;
- Verificare se il nome della pagina corrisponde alla pagina visualizzata (se sì aggiungere la classe active, se no stampare il link);
Per fare questo utilizzeremo un ciclo foreach, si tratta di un ciclo appositamente studiato per “sfogliare” gli array.
echo '</pre> <ul> <ul>';</ul> </ul> <ul> <ul>foreach($rows as $row)</ul> </ul> <ul> <ul>{</ul> </ul> <ul> <ul>}</ul> </ul> <ul>
Prima di iniziare questo ciclo stampo il tag di apertura della lista.
In sintesi la sintassi di foreach significa questo:
“Esegui il codice contenuto nelle parentesi graffe (che non abbiamo ancora scritto) tante volte quanti sono i valori dell’array $rows. Ad ogni ciclo fai assumere alla variabile $row uno dei valori dell’array $rows.”
Dunque al primo passaggio $row sarà uguale a $rows[0], al secondo passaggio $row sarà uguale a $rows[1], e così via.
Adesso dovremo “spezzare” sul “:” la stringa (nome:link). Utilizzeremo la funzione explode() che serve proprio a questo. Infatti explode() prende due argomenti: il separatore (nel nostro caso il “:“) e la stringa. Restituisce un array i cui valori sono le parti di stringa spezzati.
Ad esempio al primo passaggio la situazione sarà questa:
$result = explode(":" , "home:index.php");
Quindi $result[0] conterrà home e $result[1] conterrà index.php
Dunque il nostro ciclo sarà così:
$nav = explode(":", $row); $page = trim($nav[0]); $link = trim($nav[1]); if($link == $activePage) { echo '</pre> <ul> <li>' . $page . '</li> </ul> <pre> '; } else { echo '</pre> <ul> <li><a href="' . $link . '">' . $page . '</a></li> </ul> <pre> '; } } echo ' ';
Valorizzo $page con il primo valore della riga e $link con il secondo. Applico la funzione trim() per eliminare eventuali spazi vuoti prima e dopo.
E finalmente andiamo a verificare se si tratta della pagina attualmente visualizzata tramite la struttura di controllo if/else.
Se lo é stamperò il tag <li> con classe active, altrimenti lo stamperò “liscio” ma avendo cura di dichiarare il link.
Una volta terminato il ciclo (quindi una volta stampata tutta la navigazione), chiuderemo il tag ul.
Ed ecco la funzione completa:
<!--?php <br ?-->function Navigation() { $activePage = basename($_SERVER['PHP_SELF']); $rows = file('navigation.txt'); echo '</pre> <ul> <ul>';</ul> </ul> <ul> <ul>foreach($rows as $row)</ul> </ul> <ul> <ul>{</ul> </ul> <ul> <ul>$nav = explode(":", $row);</ul> </ul> <ul> <ul>$page = trim($nav[0]);</ul> </ul> <ul> <ul>$link = trim($nav[1]);</ul> </ul> <ul> <ul>if($link == $activePage)</ul> </ul> <ul> <ul>{</ul> </ul> <ul> <ul>echo '</ul> </ul> <ul> <ul> <li class="active">' . $page . '</li> </ul> </ul> <ul> <ul>';</ul> </ul> <ul> <ul>}</ul> </ul> <ul> <ul>else</ul> </ul> <ul> <ul>{</ul> </ul> <ul> <ul>echo ' <li><a href="' . $link . '">' . $page . '</a></li> </ul> </ul> <ul> <ul>';</ul> </ul> <ul> <ul>}</ul> </ul> <ul> <ul>}</ul> </ul> <ul>echo '</ul> <pre> '; } ?>
Ora non resta che includere il file functions.php in tutte le pagine ed invocare la funzione Navigation(), in questo modo:
Download
Conclusione
In questo articolo abbiamo visto una semplice possibilità per rendere la nostra navigazione dinamica aggiungendo un effetto active al menù. Abbiamo inoltre implementato un metodo basilare per separare i valori della navigazione dal codice che la produce aumentando la mantenibilità. Infatti, se hai necessità di aggiungere una voce al menù, non dovrai fare altro che aprire il file navigation.txt ed aggiungere la voce nella posizione desiderata. Aggiungere, rimuovere, spostare saranno operazioni molto semplici e veloci. Unico aspetto al quale prestare un minimo di attenzione: dopo l’ultima riga del file navigation.php non dovranno esserci delle interruzioni di riga in quanto potrebbero essere interpretati come una voce di navigazione vuota.
26 commenti
Trackback e pingback
-
Tweets that mention Come sviluppare una navigazione dinamica e mantenibile | Your Inspiration Web -- Topsy.com
[...] This post was mentioned on Twitter by laura and mtx_maurizio, Antonino Scarfì. Antonino Scarfì said: RT @YIW Come sviluppare… -
[standarLib applicazione pratica] 4. La navigazione « PHP LEARN
[...] la tecnica che ho descritto in questo articolo che consiste nel creare un file di testo contenente le associazioni…
Bell’articolo… un buon stimolo per muoversi secondo quanto hai scritto nell’altro articolo!
Io faccio sempre una cosa del genere, però invece di utilizzare un file txt esterno, scrivo direttamente l’array in un file come config.php, dove li tengo tutte le varie configurazioni del sito… quando mi ritrovo a dover modificare il menu, in un secondo aggiungo una voce, oppure sposto di posizione le voci e il gioco è fatto :D
Ciao Antonio.
In passato facevo anche io qualcosa di simile.
Poi con il tempo tendo sempre di più a tenere il codice “pulito” da cose che non hanno a che vedere direttamente con il codice.
Non c’è che dire, un articolo molto interessante e chiarissimo.
Per forza di cose durante lo stage che sto facendo mi trovo ogni tanto ad avere a che fare col php, e questi consigli mi torneranno senz’altro utili.
Mi state aprendo un mondo ragazzi, grazie mille!
Ciao QKappa e grazie.
Sono molto contento se questo articolo ti sarà utile!
Non ho mai usato file txt dai quali prendere informazioni in quella maniera… penso proprio che ci “giocherò” parecchio :)
E’ un modo semplice per separare certe informazioni dal codice :-)
L’ho provata proprio adesso in un lavoro in corso: è di una comodità pazzesca.
Ora dovrò fare attenzione a non abusarne :)
Non preoccuparti, abusane quanto vuoi. Magari un giorno mostro anche un trucco per integrare la possibilità di avere menù child.
home:index.php
Membri:members.php>profilo:profile.php+login:login.php
L’ho appena utilizzato per fare una demo semi dinamica ad un cliente :)
Mi serviva un menù al volo e senza impazzirmi.
grazie per la dritta.
Il 10% del tuo onorario andrà benissimo :-)
essendo dipendente dove parlarne con il capo :) e poi quando e se si farà una cosa definitiva tutto questo va a morire e si passa al CMS.
ciao
Quanto codice inutile…
Ciao passante e benvenuto su YIW.
20 righe di codice non credo siano “quanto codice”.
Sull’inutile dovresti spiegarti meglio, altrimenti ad essere inutile è il tuo commento :-)
se devo appoggiarmi ad un file per delle variabili, preferisco scriverlo in sintassi ini e parsarlo con la funzione parse_ini_file, che restituisce un array associativo con tutte le opzioni specificate nel file.
è comunque interessante leggere soluzioni differenti… :)
Certamente. E’ un’ottima soluzione anche questa!
complimenti per l’articolo :)
Grazie Rocco!
Buona sera,
ho letto con piacere questo articolo, il quale mi ha fatto nascere l’esigenza di avere una specie di paginazione in una pagina web.
Ovvero: e se i link non fossero noti a priori? Come si dovrebbe fare?
Magari sarebbe interessante vederlo in suo prossimo tutorial.
Alla prossima.
Argomento interessante, mi stavo solo chiedendo se, invece di usare un file di testo semplice o un file con formato .ini – escludendo in questo specifico esempio l’utilizzo di database MySQL – non potrebbe essere maggiormente interessante utilizzare un file in formato XML?
io ho sempre usato un file config.php dove utilizzo i define e senza ricorrere a file esterni.
Ciao Maurizio,
complimenti per l’articolo! L’ho trovato talmente interessante che l’ho provato per un mio progetto.. l’unica pecca che non funziona per i link con parametro GET a seguito :(
Più precisamente, io ho nel file (punto)txt
home:home.php
nuovo:nuovo.php
rosso:visualizzacolore.php?colore=r
blu:visualizzacolore.php?colore=b
giallo:visualizzacolore.php?colore=y
nel mio caso home e nuovo funzionano.. ma rosso, blu e giallo li vede come tutti uguali perchè $activePage è sempre “visualizzacolore.php” e nell’istruzione condizionale salta sempre nel ramo else per ogni $link confrontato.
Esiste una funzione al posto di basename che mantiene anche le variabili GET ?
Grazie in anticipo per l’attenzione.
Saluti Angelo
Puoi utilizzare
$_SERVER[“QUERY_STRING”]
Che contiene appunto la querystring accodata all’url
Grazie per la risposta.. ora mi documento su questa funzione.
Saluti
Ottima guida!