2010-03-23 12 views
23

Trovo Yii great framework e il sito Web di esempio creato con yiic shell è un buon punto di partenza ... tuttavia non copre l'argomento dei siti Web multilingue, purtroppo . Il documento copre il tema della traduzione di brevi messaggi, ma non mantiene il contenuto multilingue ...Yii: sito Web multilingue: best practice

Sto per iniziare a lavorare su un sito web che deve essere in almeno due lingue, e mi chiedo qual è il modo migliore per mantenere il contenuto per questo ... Il problema è che il contenuto è ampiamente mixato con elementi comuni (come file video incorporati).

Ho bisogno di evitare la duplicazione di quei comuni ... finora avevo una matrice di matrici contenenti testi (di solito non più di 1-2 brevi paragrafi), quindi il file di visualizzazione stava semplicemente rendendo il testo da una matrice .

Ora mi piacerebbe evitare di tenerlo negli array (che richiede una certa attenzione quando si inseriscono le doppie virgolette "" ed è scomodo in generale ...).

Quindi, qual è il modo migliore per mantenere quei brevi paragrafi? Devo tenerli in DB come (id | msg_id | lingua | contenuto) e quindi selezionarli tramite msg_id & lingua? Ciò richiede ancora che io crei alcuni msg_id e li incorpori nel file di visualizzazione ...

Esiste qualche paradigma consigliato per cui Yii ha alcune soluzioni?

Grazie, m.

metodo

risposta

17

applicazione A Yii di default usa Yii :: t() per la traduzione dei messaggi di testo e ci sono 3 tipi diversi di fonti di messaggi:

  1. CPhpMessageSource: Le traduzioni sono memorizzati come coppie chiave-valore in un PHP array.
  2. CGettextMessageSource: le traduzioni sono memorizzate come file GNU Gettext. (File PO)
  3. CDbMessageSource: le traduzioni dei messaggi vengono archiviate nelle tabelle del database.

Se non fraintendo, si stanno utilizzando gli array classici per le traduzioni. Ti consiglio di utilizzare i file GetText e PO con Yii per le operazioni di traduzione.

È possibile trovare molte informazioni sulla traduzione e i18n con yii in questo official documentation page.

+0

Problemi con GetText IMO sono difficili da mantenere e da tenere aggiornati anche in caso di problemi di natura atomica. Il mio metodo preferito è il database in modo da poter aggiornare i messaggi al volo. Se hai davvero bisogno di velocità, GetText è più veloce altrimenti DB è la strada da percorrere. – Atherion

+0

NOTA: si consiglia di non utilizzare GettextMessageSource senza cache.La pura prestazione gettext di PHP è molto più lenta dell'array php (yii2 utilizza gli array php) perché legge ripetutamente i file, tuttavia l'utilizzo dell'estensione php gettext (vs codice puro di phon gettext) è più veloce dell'array php ma l'utilizzo di php ext richiede il riavvio del server per ogni cambiamento. http://mel.melaxis.com/devblog/2006/04/10/benchmarking-php-localization-is-gettext-fast-enough/ – Alix

1

Beh, penso che ciò che è interessato qui è come tradurre testi/messaggi statici sulla pagina e Yii lo risolve abbastanza bene usando Yii: t() e la risposta di Edigu è per questo.

Ho controllato il post su FlexicaCMS sulla traduzione di contenuti dinamici nel database, e in definitiva quello sarà il prossimo dopo aver risolto il problema di testo/messaggio statico, e questo è un approccio veramente buono che usa il comportamento di Yii. Non sono sicuro che gli autori di FlexicaCMS siano troppo ambiziosi nel supportare la traduzione in questo modo, poiché renderebbero la traduzione dei contenuti una cosa senza preoccupazioni - davvero grandiosa.

Una cosa che non menzionano è l'url della pagina tradotta. Ad esempio your.site.com/fr/translated_article_title.html. Voglio dire che l'url deve avere/language_id/part in modo che possa aiutare con SEO.

19

Gettext è utile per la sua facilità di traduzione, ma l'implementazione PHP predefinita non è thread-safe.Pertanto, Yii utilizza il proprio disimballatore, aumentando drasticamente i tempi di elaborazione rispetto agli array php.

Dal momento che stavo creando un sito ad alto volume di transazioni, il risultato in termini di prestazioni non era accettabile. Inoltre, utilizzando APC, è possibile memorizzare nella cache la traduzione PHP aumentando ulteriormente le prestazioni.

Il mio approccio era quindi utilizzare gli array PHP ma mantenere le traduzioni in un DB per facilitare la traduzione, generando i file necessari quando le traduzioni vengono cambiate.

Il DB è simile a questo:

TABLE Message   // stores source language, updated by script 
id INT UNSIGNED 
category VARCHAR(20)   // first argument to Yii::t() 
key TEXT      // second argument to Yii::t() 
occurences TINYINT UNSIGNED // number of times found in sources 

TABLE MessageTranslation // stores target language, translated by human 
id INT UNSIGNED 
language VARCHAR(3)   // ISO 639-1 or 639-3, as used by Yii 
messageId INT UNSIGNED  // foreign key on Message table 
value TEXT 
version VARCHAR(15) 
creationTime TIMESTAMP DEFAULT NOW() 
lastModifiedTime TIMESTAMP DEFAULT NULL 
lastModifiedUserId INT UNSIGNED 

Ho poi modificato il comando lo strumento CLI yiic 'messaggio' per fare uscire le stringhe raccolti nel DB.

http://www.yiiframework.com/wiki/41/how-to-extend-yiic-shell-commands/

volta nel DB, un semplice CMS può essere configurato per fornire i traduttori un modo semplice per tradurre e allo stesso tempo fornire informazioni sulla versione, tornando alle versioni precedenti, il controllo della qualità dei traduttori, ecc ..

Un altro script, anch'esso modificato da yiic, prende quindi le informazioni del DB e le compila negli array PHP. Fondamentalmente un JOIN delle due tabelle per ogni lingua, quindi costruisci un array usando "Message". "Key" e "MessageTranslation". "Value" as (what else?) Key => value ... saving to file named from " Messaggio "." Categoria "nella cartella specificata dalla lingua.

I file generati vengono caricati normalmente da Yii CPhpMessageSource.

Per le immagini, è stato semplice inserirle in cartelle con la lingua corretta e ottenere il linguaggio dell'app durante il collegamento.

<img src="/images/<?php echo Yii::app()->language; ?>/help_button.png"> 

Nota che nella vita reale, ho scritto un metodo di supporto poco per togliere il paese dalla stringa di lingua, 'en_US' dovrebbe essere 'it'.

0

In Yii1 e Yii2 yii \ i18n \ GettextMessageSource non utilizza comunque il motore di cache Yii perfect (guarda la sorgente) per migliorare il carico dei file PO o MO. Non è consigliabile caricare i file utilizzando PHP codice puro (tra cui Yii \ i18n \ GettextMessageSource) (è così lento rispetto php array di IDX): http://mel.melaxis.com/devblog/2006/04/10/benchmarking-php-localization-is-gettext-fast-enough/

Tuttavia php gettext ext per i file MO si trova a pochi più veloce di php traduzione array perché utilizza la cache ma il punto negativo è: ogni modifica in MO richiede il riavvio del server.

Penso che la soluzione migliore sarebbe estendere yii \ i18n \ GettextMessageSource nella propria libreria di codici e aggiungere la capacità cache a GettextMessageSource per migliorare le prestazioni e utilizzare la versione estesa come componente.

protected function loadMessages($category, $language); 

Basta non controllare MO data di modifica in ogni carico da confrontare con la cache, invece cancellare la cache quando i file MO o PO sono cambiate (può essere un programma).