Un’applicazione multilingue non consiste solo nel tradurre le etichette dell’interfaccia. Se offre anche articoli, schede prodotto o altre risorse editoriali, deve rappresentare la lingua di ciascun contenuto, il modo in cui le sue versioni sono collegate e cosa significa che una traduzione è pronta per la pubblicazione. Un modello impreciso finisce per mostrare testi non aggiornati, link senza destinazione o bozze a utenti che non dovrebbero vederle.
Per pianificare la gestione dei contenuti multilingue in PHP, è opportuno separare le decisioni relative all’interfaccia, ai dati e al flusso editoriale. L’implementazione può basarsi su file di traduzione per l’interfaccia e sul database per i contenuti variabili, ma questa suddivisione deve rispondere al dominio e alle esigenze di chi si occupa della redazione.
Separare la lingua dell’interfaccia, la lingua originale e la traduzione

La lingua dell’interfaccia determina etichette, messaggi di convalida, formati di data e altri testi propri del prodotto. In un’applicazione PHP può essere gestita tramite cataloghi di traduzione, per esempio file organizzati per locale, e selezionata in base alla preferenza dell’utente o a una configurazione di sessione. Non va confusa con la lingua dei contenuti consultati.
La lingua originale, invece, identifica la lingua in cui è stata creata una risorsa editoriale. Ogni traduzione è una versione associata a quella risorsa e ha una propria lingua. Un utente può navigare nell’interfaccia in italiano e aprire una pagina il cui contenuto originale è in inglese; l’applicazione deve decidere esplicitamente se questo è consentito e come comunicarlo.
Salva codici lingua normalizzati e applica una politica coerente per le varianti regionali, quando necessario. Non dare per scontato che lingua e paese siano intercambiabili: una variante regionale può influire sul testo, ma anche sui formati, sulla disponibilità o sui requisiti commerciali. Definisci quali locali sono supportati dal prodotto e quali vengono usati per risolvere una preferenza incompleta.
Scegliere un modello di dati che rappresenti il dominio
Esistono tre pattern comuni, ciascuno con compromessi diversi:
- Campi per lingua: colonne come
title_itetitle_ensono semplici da gestire quando le lingue sono poche, l’insieme dei campi è stabile e le query sono dirette. Perdono flessibilità quando si aggiungono lingue e fanno dipendere ogni modifica dello schema dal catalogo delle lingue. - Record indipendenti: ogni versione viene salvata come risorsa separata. Può essere adatto se le versioni hanno cicli di vita o strutture davvero indipendenti, ma richiede un altro metodo affidabile per raggrupparle. Non usare un titolo simile o un URL come collegamento implicito.
- Tabella delle traduzioni correlata: una risorsa comune è associata a una riga per lingua, per esempio tramite
content_idelocale. Questo facilita l’aggiunta di lingue e la consultazione delle versioni disponibili. Sono necessari vincoli che impediscano di duplicare la traduzione della stessa lingua per una risorsa.
La tabella correlata è spesso adatta quando le versioni condividono identità e struttura, ma non è una regola universale. Se alcuni campi non vengono tradotti, per esempio un riferimento interno, possono rimanere nell’entità comune; i campi editoriali localizzati appartengono alla traduzione. Chiarisci anche se una traduzione può avere un URL, metadati di ricerca o una data di pubblicazione propri.
Nel database, definisci chiavi esterne, unicità per risorsa e lingua e il comportamento in caso di eliminazione dei dati. La logica applicativa in PHP deve inoltre verificare che la lingua sia supportata e che la risorsa correlata esista. I vincoli del database proteggono dalle scritture concorrenti e dagli errori che una semplice convalida preventiva non può evitare.
Collegare le versioni senza richiedere che siano tutte presenti
Non tutte le risorse esisteranno in tutte le lingue e non tutte le traduzioni verranno completate nello stesso momento. Modella questa realtà: l’assenza di una riga non dovrebbe essere interpretata come un errore di integrità se la traduzione è facoltativa. Al contrario, uno stato editoriale deve indicare cosa succede quando una riga esiste, ma non può ancora essere pubblicata.
Evita di duplicare in ogni traduzione informazioni che appartengono alla risorsa condivisa, a meno che il dominio non richieda variazioni. Se le traduzioni possono essere scollegate, trasferite o conservate come archivio, definisci queste operazioni e i relativi permessi. Per identificare il gruppo di versioni, usa una relazione stabile, non corrispondenze di testo, slug o data.
Quando una traduzione cambia, registra a quale versione dell’originale fa riferimento, se il team ha bisogno di individuare contenuti potenzialmente non aggiornati. Questo indicatore non dimostra di per sé che la traduzione sia errata; consente di dare priorità a una revisione. Per alcuni prodotti sarà sufficiente un contrassegno di revisione in sospeso, mentre altri avranno bisogno di una cronologia delle versioni e di una traccia di audit.
Definire gli stati editoriali per lingua
Lo stato di pubblicazione deve appartenere a ciascuna traduzione se ogni lingua può essere redatta, revisionata e pubblicata in modo indipendente. Una risorsa può essere pubblicata in una lingua e rimanere in bozza in un’altra. Un unico booleano di pubblicazione a livello di risorsa non rappresenta questa differenza.
Progetta un flusso essenziale ed esplicito, per esempio bozza, in revisione e pubblicato. Definisci chi può cambiare ciascuno stato, quali campi sono obbligatori e se una revisione richiede un’approvazione. La data di pubblicazione, la persona responsabile e la cronologia delle modifiche possono essere necessarie per gestire il processo; evita di aggiungere stati che non corrispondono ad azioni reali del team.
Le query pubbliche devono filtrare per stato e lingua, senza fare affidamento sul fatto che l’interfaccia editoriale nasconda le righe non pubblicate. In PHP, concentra queste regole in un livello di accesso al dominio o in query riutilizzabili e verifica che controller, API e task in background le rispettino. Anche le operazioni di modifica e pubblicazione devono verificare i permessi relativi alla lingua e alla risorsa specifiche.
Gestire assenze, URL e ricerca in modo coerente
Se manca una traduzione, sono possibili diverse politiche. L’applicazione può nascondere la risorsa in quella lingua, segnalare che esiste solo in un’altra oppure mostrare un fallback. Scegli in base al tipo di contenuto e all’effetto sull’esperienza; un fallback non deve essere presentato come se fosse una traduzione. Se viene mostrato contenuto in un’altra lingua, indicalo chiaramente e consenti di tornare alla versione richiesta.
Applica regole diverse all’interfaccia e ai contenuti. Il fatto che le etichette di navigazione ricorrano a un altro catalogo come fallback non implica che gli articoli debbano essere sostituiti automaticamente con la loro versione originale. Il fallback editoriale deve essere limitato alle lingue consentite e ai contenuti pubblicabili, e non deve restituire bozze.
Gli URL devono identificare una versione reale o seguire una regola di reindirizzamento documentata. Quando si cambia lingua, cerca la traduzione della stessa risorsa; se non esiste, offri un’alternativa esplicita anziché creare un percorso che sembri valido. Per la SEO, evita di pubblicare pagine vuote o duplicate a causa di fallback invisibili. La ricerca deve indicizzare solo le versioni idonee e usare la lingua corrispondente per filtrare e presentare i risultati.
Lista di controllo prima della pubblicazione

- L’interfaccia, la lingua originale e la lingua di ogni traduzione sono concetti distinti nel modello?
- Si impedisce di salvare due traduzioni della stessa risorsa nella stessa lingua?
- Una traduzione può essere assente senza creare uno stato incoerente?
- Il team può distinguere bozza, revisione e pubblicazione per lingua?
- I percorsi pubblici e i link per cambiare lingua verificano che esista una versione visibile?
- Il fallback è definito in base al caso d’uso, viene comunicato all’utente e non espone mai bozze?
- La ricerca filtra per lingua e stato e smette di indicizzare una versione ritirata?
- Sono stati testati permessi, modifica concorrente, eliminazione, contenuti incompleti e cambi di lingua?
Testa anche il ritiro di una traduzione già collegata, l’aggiornamento dell’originale dopo la pubblicazione di una versione e la richiesta diretta di un URL non disponibile. In ogni caso, verifica la risposta, la navigazione e la visibilità nei risultati di ricerca. L’obiettivo non è obbligare tutte le lingue a procedere allo stesso ritmo, ma fare in modo che ogni versione abbia un’identità, uno stato verificabile e un comportamento prevedibile per redattori e utenti.



