Vi è mai capitato di dover gestire un sito in due o più lingue? No? Allora siete stati fortunati, perché con l’apertura all’estero (e in particolare per i siti di e-commerce) sempre più siti anche di “piccola taglia” vi chiedono di affiancare alla lingua italiana almeno quella inglese.
Quando progettate un sito web, di qualsiasi tipo, dovreste già pensarlo come se fosse un multilingua: spesso, infatti, il cliente vi chiederà soltanto in seguito l’aggiunta di una seconda o terza lingua. Se non avete previsto in anticipo l’aggiunta, risolvere il problema potrebbe richiedervi di stravolgere molte delle query che estraggono dati dal database.
In questo articolo vi propongo un sistema per gestire un sito web con un numero indefinito di lingue. Non è l’unico metodo possibile e può essere perfezionato, ma dopo vari miglioramenti lo ritengo un approccio affidabile di base e che permette di agire agevolmente sui testi modificando pochi file.
Il linguaggio utilizzato è il php con database di tipo mysql, ma è possibile seguire lo stesso procedimento per qualsiasi altro linguaggio.
All’interno dello script, liberamente scaricabile, troverete il codice essenziale che mostra la gestione in multilingua di una pagina: dovrete adattarlo voi al vostro sito.
Inoltre troverete i dump delle tabelle essenziali del database.
La tabella della lingua
Prima di tutto creiamo nel database la tabella “lingue” (trovate il dump da importare chiamato “lingue.sql”, dove sono già predisposte l’italiano e l’inglese).
La tabella da importare sarà questa:
1 2 3 4 5 6 7 8 9 10 11 12 |
CREATE TABLE IF NOT EXISTS `lingue` ( `id` int(11) NOT NULL AUTO_INCREMENT, `nome` varchar(255) NOT NULL, `estensione` varchar(2) NOT NULL, `predefinita` tinyint(1) NOT NULL DEFAULT '0', `nascosto` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ; INSERT INTO `lingue` (`id`, `nome`, `estensione`, `predefinita`, `nascosto`) VALUES (1, 'Italiano', 'it', 1, 0), (2, 'Inglese', 'en', 0, 0); |
Il campo “predefinita” indica quale lingua da settare per default. Presumibilmente è l’italiano, per cui dovrete inserire il valore 1 associato all’italiano (come da esempio). Il campo “nascosto” è in più, nel senso che potrà tornarvi utile nel caso in cui decidiate per qualche motivo di sopprimere una lingua (basta impostare il relativo record a 1).
Consiglio: fate in modo che l’estensione sia sempre di due caratteri, potrebbe tornarvi utile nel caso in cui dobbiamo effettuare controlli particolari sulla lunghezza del valore get.
La scelta della lingua
Dal lato del sito, l’utente avrà un semplice link da cliccare (uno per ogni lingua). Al click, sarà passata la variabile $_GET[“lingua”] con il valore relativo alla lingua scelta. Questo valore (cioè il parametro get) si dovrà portare in ogni pagina del sito.
Nello script ho messo semplicemente due link senza nessuna grafica:
1 2 3 |
<a href="?lingua=it">italiano</a> <br /><br /> <a href="?lingua=en">inglese</a> |
Come recuperiamo la lingua voluta? Lo vedete nel codice seguente. Come potete notare, nel caso in cui esista il parametro $_GET[“lingua”] sarà preso quest’ultimo come simbolo per la lingua (it, en, ecc.).
Se invece il get sarà mancante (per esempio, appena si apre l’home del sito), sarà presa la lingua di default dal database.
Il valore sarà immagazzinato nella costante LANG, che per sua natura è globale e non modificabile.
1 2 3 4 5 6 7 8 9 |
//setto la lingua corrente //se esiste il get, prendo quella, altrimenti la recupero dal database (prendo la lingua predefinita) if(isset($_GET["lingua"])) define('LANG', $_GET["lingua"]); else{ $query=mysql_query("SELECT * FROM lingue WHERE predefinita=1 AND nascosto=0 LIMIT 0,1", DB); $row=mysql_fetch_array($query); define('LANG', $row['estensione']); } |
I testi statici
A questo punto abbiamo recuperato l’estensione della lingua corrente, racchiusa nella costante LANG.
Vediamo innanzitutto come sistemare un testo statico. Mettiamo, per esempio, che abbiate due testi da stampare a video; normalmente, anche in puro html, il codice sarebbe il testo stesso cioè:
1 2 3 |
Questa è la prima prova in italiano
<br /><br />
Questa è la seconda prova in italiano
|
Nel nostro caso, se l’utente sceglie la lingua inglese dovremo trasformare all’occorrenza queste due stringhe in:
1 2 3 |
Questa è la prima prova in inglese
<br /><br />
Questa è la seconda prova in inglese
|
Come fare per rendere dinamica la stampa? Il sistema migliore è di creare un file per ogni lingua e di importare il file adatto a seconda del valore di LANG.
Nello script trovate una cartella chiamata “languages”, che conterrà all’interno dei file di nome identico ma con il suffisso finale che cambia in base alla lingua (“lingua_it.php” e “lingua_en.php”).
Per importare il giusto file, subito dopo aver definito LANG andremo a includere:
1 |
include("languages/lingua_".LANG.".php"); |
All’interno di ognuno di questi file troveremo uno switch che, in base al case passato, ritornerà la stringa relativa. Il codice dovrebbe bastare a capire; comunque sotto spenderò due parole per spiegarlo nel dettaglio:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
//contenuto nel file "lingua_it.php" function lingua($identificativo){ switch($identificativo){ case "prova1": return "Questa è la prima prova in italiano"; break; case "prova2": return "Questa è la seconda prova in italiano"; break; } } //contenuto nel file "lingua_en.php" function lingua($identificativo){ switch($identificativo){ case "prova1": return "Questa è la prima prova in inglese"; break; case "prova2": return "Questa è la seconda prova in inglese"; break; } } //stampa a video echo lingua("prova1"); |
Lo stesso switch lo troviamo nei due file (“lingua_it.php” e “lingua_en.php”), ma naturalmente sarà presente solo quello del file incluso a inizio pagina, stabilito dal valore di LANG.
Questo significa che se siamo in lingua italiana, sarà estratto il valore corrispondente al case “prova1” del file “lingua_it.php”; se siamo in lingua inglese, sarà estratto quello di “lingua_en.php”.
Conclusioni
Una volta capito il concetto, il codice risulta molto semplice. Un sito strutturato in questo modo permette una modifica semplice e veloce, e soprattutto di adattare il portale a qualsiasi lingua (basta creare un’ulteriore file di lingua, es: “lingua_fr.php” per il francese, e di popolarlo con gli stessi case degli altri file di lingua).
Il mio consiglio è di mettere sotto questa forma qualsiasi tipo di testo statico nel sito: questo perché, in futuro, potreste aver bisogno di tradurlo o di modificarlo e per farlo vi basterà accedere ai file delle lingue.
Riconosco che in grandi siti potrebbe richiedere un bel po’ di tempo, per cui starà a voi valutare se è il caso di farlo a mano. In genere, comunque, è nei portali più grandi che troverete diverse lingue da gestire.
In questo articolo abbiamo visto un sistema per tradurre in multilingua solo il testo statico. Nel prossimo articolo ci occuperemo della parte dinamica, cioè di tradurre i testi estratti da database.
(1) http://amegliagiovani.blogspot.it/2010/09/giornata-europea-delle-lingue.html
Ottima soluzione proposta per la traduzione dei testi statici, cercavo qualcosa di diverso dalla soluzione di allocare array o costanti.
Grazie Angelo.
Questo è uno dei sistemi possibili. L’importante, come dici tu, è evitare di allocare inutilmente variabili che andrebbero a rallentare l’esecuzione del sito.
Caro Manuel grazie per questo tutorial funzionante al 1000% e lo potuto adattare senza problemi al mio programma di fatturazione.
Ti scrivo per chiederti se è possibile lasciare tutto così come è ma gestire la lingua in un modo diverso.
Ti spiego brevemente sono residente a Merano Alto-Adige e qui c’è la realtà del bilinguismo a volte anzi sempre… capita che quando faccio dei programmi l’utente finale che interagisce con l’applicazione può essere di madrelingua Italiana oppure Tedesca.
Pensavo di gestire la lingua in questo modo: in base all’utente che utilizza l’applicazione vorrei dargli la possibilità, in fase di registrazione utente, di far scegliere a lui se voler visualizzare il programma completamente in Tedesco oppure in Italiano.
Pensi che sia possibile ovviamente con il tuo aiuto riuscire a gestire il cambio lingua in questo modo? Lascerei come lingua ovviamente di default l’Italiano ma sempre nel possibile vorrei applicare l’opzione di dare all’utente la possibilità di scegliere quale lingua usare.
Se lascio così come tu hai spiegato magnificamente funziona già quello che ti sto chiedendo, ma funziona solo se è un singolo utente oppure più utenti che utilizzano l’applicazione in mono lingua e quindi tutti visualizzeranno il programma in una sola lingua. La realtà invece e che vi sono più utenti che utilizzano l’applicazione e sono di madre lingua diverse ossia Italiano – Tedesco.
Grazie anticipatamente sperando nella fattibilità…
Ciao Giuseppe,
nessun problema, quello che devi fare è gestire la costante LANG in modo che gli sia assegnata la sigla “de” del tedesco.
Quando l’utente si registra, nel suo record in database puoi creare un campo “lingua_predefinita” a cui assegni la sigla della lingua che ha scelto. Ogni volta che l’utente accede, fai estrarre questa sigla e la assegni alla costante LANG.
E si pare che funzioni…. ultimo piacere se gentilmente mi confermi che quello che ho fatto sia corretto.
if(isset($_GET[“lingua”]))
define(‘LANG’, $_GET[“lingua”]);
else{
$query=mysqli_query($con,”SELECT * FROM utenti”);
$row=mysqli_fetch_array($query);
define(‘LANG’, $row[‘lingua_predefinita’]);
}
E’ questo che intendi vero? grazie per la dritta…
Cavoli come non detto mi sono accorto ora che in questo modo prende sempre la prima lingua dell’utente. Se ho un utente con lingua_predefinita de lo script mi va a prendere sempre l’italiano perché il primo utente registrato ha nel campo lingua_predefinita it.
Dovrei intervenire sicuramente qui
$query=mysqli_query($con,”SELECT * FROM utenti”);
Ma non so come associare l’utente che ha appena fatto accesso al programma
Pensavo a questo
if(isset($_GET[‘id’]))
{
$id=$_GET[‘id’];
if(isset($_GET[“lingua”]))
define(‘LANG’, $_GET[“lingua”]);
else{
$query=mysqli_query($con,”SELECT * FROM utenti WHERE id=’$id’”);
$row=mysqli_fetch_array($query);
define(‘LANG’, $row[‘lingua_predefinita’]);
}
Ma non funziona… suggerimenti ??
La soluzione è il recupero dell’id utente, come hai fatto nel tuo ultimo commento: è l’unico modo per dirgli di prendere il campo “lingua_predefinita” dell’utente connesso.
Se non funziona, evidentemente l’id che recuperi non è corretto. Qua bisogna vedere come lo salvi: quando l’utente si logga devi salvare l’id da qualche parte in modo da poterlo recuperare facilmente. Per esempio lo puoi salvare in $_SESSION[‘id_utente’] (le sessioni sono sempre visibili), oppure in una costante.
Consiglio: ho visto che nell’esempio che hai fatto hai recuperato l’id utente dal GET. Per la sicurezza non mettere mai in chiaro l’id utente nell’url. Salvalo appunto in costanti o variabili di sessione.
Ciao Manuel, grazie mille per l’ottima guida.
Una domanda: supponendo che abbia un menu che mi faccia navigare tra le pagine interne del sito, una volta che scelgo la lingua attraverso un apposito switcher, come faccio a creare il collegamento in modo tale che si venga rimandati nella pagina collegata con la lingua corrente?
Esempio, scelgo la lingua inglese, voce menu “Contact”, al click devo andare nella pagina contatti in inglese (lingua corrente).
Spero di essere stato chiaro. Grazie,
Fabio
Ciao Fabio,
la lingua viene sempre stabilita dal $_GET[‘lingua’]. I link non fanno eccezioni, quindi nel tuo caso avrai una pagina ben distinta per ogni lingua.
Per esempio, poniamo il caso che la tua pagina Contatti sia caricata quando trova il get “page=contact”. Per distinguere in quale lingua deve caricare i contenuti, devi aggiungere anche il get “lingua”:
http://www.sito.it?page=contact&lingua=en
In pratica devi affiancare a tutti i tuoi link (dove serve) il get “lingua”, assegnandogli il valore relativo alla lingua corrente. Se hai seguito il ragionamento nel mio articolo, da codice puoi assegnargli il valore della lingua corrente in modo dinamico con la costante LANG:
http://www.sito.it?page=contact&lingua=
Ciao Manuel,
funziona alla perfezione. Grazie per la guida e per le tue risorse, che sono veramente molto preziose.
Continuo a seguirti con interesse.
Fabio
Grazie a te per la visita al sito 🙂