Come implementare le traduzioni nel pacchetto di modelli di progettazione CSV? Come funziona echo $ this -> __ ('Text')?


29

Ho un pacchetto di progettazione configurato in questo modo:

design/frontend/package_name/theme_name/locale/

in base al quale ho

de_DE, en_GBecc., in base al quale ho i translate.csvfile corrispondenti con le varie stringhe:"Key", "Translation"

Sto cercando di implementare varie stringhe nel mio tema usando echo $this->__('Text')

Tuttavia, non sembra funzionare (vedo solo la stringa all'interno del ('Text')display). Penso che mi manca una comprensione fondamentale di quando Magento estrae le stringhe dal CSV per la traduzione. Qualcuno può spiegare come far funzionare questi file CSV?


Quale versione di Magento stai utilizzando?
Filwinkle,

Sto usando Magento v: 1.7.0.2
waffl

Lo stai chiamando al di fuori di un normale file modello magento? Forse devi chiamare la classe helper e renderla simile a <? Php echo Mage :: helper ('core') -> __ ('Text'); ?> Prova anche ad abilitare "Traduci in linea" su Frontend in Sistema> Configurazione> Sviluppatore
SaveTheMage

Risposte:


84

TL; DR

Se non sei interessato ai dettagli su come funziona la traduzione, salta il contenuto fino alla sezione
Cosa controllare se la traduzione non funziona di seguito, in particolare la sottosezione
Soluzione per conflitti di traduzione dell'ambito del modulo .

Panoramica sulla traduzione di Magento

Magento dà la priorità alle fonti di traduzione (dal più alto al più basso):

  1. DB (la core_translatetabella)
  2. Il translate.csvfile del tema
  3. I app/locale/*/*.csvfile

Come viene costruito l'array di traduzione?

Traduzioni di moduli

Innanzitutto vengono analizzati tutti i file a app/locale/*/*.csvcui si fa riferimento dai etc/config.xmlfile dei moduli attivi . Ecco una procedura dettagliata del processo:
Supponiamo che Magento trovi la seguente config.xmlsezione:

<!-- excerpt from Mage/Catalog/etc/config.xml -->
<frontend>
    <translate>
        <modules>
            <Mage_Catalog>
                <files>
                    <default>Mage_Catalog.csv</default>
                </files>
            </Mage_Catalog>
        </modules>
    </translate>
</frontend>

E in quel file, viene specificata la seguente traduzione per le impostazioni locali configurate per la vista dell'archivio corrente:

"AAA","BBB"

In queste circostanze, Magento crea i seguenti record nell'array di traduzione:

array(
    "AAA" => "BBB",
    "Mage_Catalog::AAA" => "BBB"
)

Il secondo valore è la traduzione dell'ambito del modulo . Il nome del modulo con prefisso viene preso dal nodo XML di configurazione contenente la dichiarazione del file di traduzione.

Se la stessa traduzione viene nuovamente specificata da un secondo file del modulo , ad es. Nella Some_Module.csvtraduzione "AAA","CCC", NON SOVRACCARICERÀ l' "AAA"impostazione. Invece, aggiungerà solo un nuovo record con il secondo nome del modulo "Some_Module::AAA" => "CCC".

Se la modalità sviluppatore è abilitata, sarà anche disinserire il "AAA"record se si trova un secondo record con la stessa chiave in un'altra traduzione modulo. Ciò semplifica l'individuazione dei conflitti di traduzione dei moduli durante lo sviluppo.

Traduzioni tematiche

In secondo luogo, le traduzioni caricate dal primo translate.csvfile nel fallback del tema per la locale corrente sostituiscono semplicemente i record esistenti nell'array di traduzione.
Quindi, continuando l'esempio precedente, un translate.csvrecord "AAA","DDD"porterebbe ai seguenti dati di traduzione:

array(
    "AAA" => "DDD", // This is overwritten by the translate.csv file
    "Mage_Catalog::AAA" => "BBB",
    "Some_Module::AAA" => "CCC"
)

Naturalmente i record translate.csvcon le nuove chiavi di traduzione vengono semplicemente aggiunti all'array.

Traduzioni di database

Le traduzioni dalla core_translatetabella vengono fondamentalmente unite nell'array di traduzioni proprio come le traduzioni dei temi.
Le chiavi esistenti dal modulo o le traduzioni dei temi vengono sovrascritte dai record del database, nuove vengono aggiunte.

Ricerca di traduzione

Quando __()viene chiamato il metodo, Magento cerca innanzitutto una traduzione in array corrispondente al modulo corrente.
Il modulo corrente è determinato dal nome della classe su cui __()viene chiamata la classe. Ad esempio, in blocchi il metodo responsabile è simile al seguente:

// Excerpt from Mage/Core/Block/Abstract.php
public function getModuleName()
{
    $module = $this->getData('module_name');
    if (is_null($module)) {
        $class = get_class($this);
        $module = substr($class, 0, strpos($class, '_Block'));
        $this->setData('module_name', $module);
    }
    return $module;
}

I metodi in Helpers e Controller funzionano in modo corrispondente.

Scenari di ricerca di esempio

Per un esempio, supponiamo che $this->__('AAA')venga chiamato in un file modello. Se il blocco associato ha il tipo Mage_Core_Block_Template, Magento controllerà prima un Mage_Core::AAArecord. Se non lo trova, tornerà alla traduzione della chiave AAA.
Nello scenario di esempio, ciò comporterà la traduzione DDD(dal translate.csvfile).

In uno scenario diverso potrebbe essere il blocco associato Mage_Catalog_Block_Product_View. In questo caso Magento controlla prima la presenza di un record di traduzione Mage_Catalog::AAAe trova la traduzione AAA.

Quindi, in effetti, le traduzioni dell'ambito del modulo hanno una priorità più alta rispetto a qualsiasi traduzione generica . La traduzione utilizzata dipende dal modulo utilizzato dalla classe per chiamare il __()metodo.

Cosa verificare se la traduzione non funziona

Se la tua traduzione da un translate.csvfile non viene utilizzata, segui questo elenco di controllo:

  1. La cache di traduzione è disattivata / aggiornata? (Soluzione: svuota la cache)
  2. Il translate.csvfile è davvero nel fallback del tema per l'archivio corrente? (Soluzione: correzione della configurazione del tema)
  3. Esiste un record in conflitto per la traduzione nella core_translatetabella? (Soluzione: rimuovere il record in conflitto da core_translate)
  4. Se tutti i punti precedenti non sono la causa, deve esserci una traduzione in conflitto da un modulo diverso. (Soluzione: vedi sotto)

Soluzione per conflitti di traduzione dell'ambito del modulo

Se si trova l'ultimo caso è vero, è sufficiente aggiungere la traduzione una seconda volta per la vostra translate.csv con il campo di applicazione del modulo del modulo fare la traduzione.
Nell'esempio, se hai sempre voluto AAAessere tradotto come DDDtramite la traduzione del tema, potresti farlo nel tuo translate.csv:

"AAA","DDD"
"Mage_Catalog::AAA","DDD"
"Some_Module::AAA","DDD"

In pratica, aggiungo l'ambito del modulo alla traduzione solo in caso di conflitto, ovvero se una traduzione non funziona.

Note aggiuntive

Traduzione in linea

La funzione di traduzione in linea di Magento aggiunge anche le traduzioni personalizzate alla core_translatetabella usando il prefisso dell'ambito del modulo.

Retrocompatibilità

La priorità delle traduzioni del tema era maggiore delle traduzioni del database fino a Magento versione 1.3 o giù di lì.

Traduzione XML

Magento volte valutare translate=""argomenti config.xml, system.xmle XML layout per tradurre i valori nodo figlio.
In questi casi è possibile specificare una classe helper utilizzando l' module=""argomento per specificare il modulo per l'ambito della traduzione.
Se non moduleviene specificato alcun argomento nell'XML, l' core/datahelper viene utilizzato per tradurre i valori del nodo figlio.

Ulteriori informazioni

Confesso di aver analizzato alcuni dettagli del processo di traduzione di Magento in questo post, ma solo perché non voglio troppe informazioni.

  • Alcuni dettagli tecnici durante la creazione dell'array di traduzioni
  • La possibilità di utilizzare file di traduzione aggiuntivi per i moduli
  • Archiviare l'ambito della vista per i core_translaterecord
  • Pro e contro utilizzando i diversi metodi di traduzione

Si prega di porre una domanda separata se sono necessarie ulteriori informazioni.


1
OK, mi dispiace incredibilmente per tutti, ma qualcun altro ha acceso la cache senza dirmelo ... Probabilmente dal momento in cui ho iniziato a lavorare sulle traduzioni. Sospiro. Questa informazione è stata incredibilmente utile per la mia comprensione del processo di traduzione in Magento. Molte grazie, questo sicuramente risponde a tutte le domande che ho avuto su come __()funziona la funzione.
Waffl,

Una buona panoramica dell'architettura di traduzione di Magento è disponibile anche qui: gist.github.com/antonmakarenko/7538216
thdoan,

@Vinai, ottima risposta. Mi ha davvero aiutato a risolvere un problema di traduzione in cui ho postato una domanda qui . Sorprendentemente Mage_Tax era in conflitto con le traduzioni del mio tema, il che sembra contrario al modo in cui Magento intende dare priorità alle traduzioni
Holly,

14

Fonti di traduzione

Le traduzioni vengono unite da fonti diverse: traduzioni di moduli dai rispettivi file XML, traduzioni di temi dal translate.csvtema corrente e traduzioni incorporate dal database.

Le traduzioni possono essere strettamente specifiche del modulo (valide solo all'interno di un modulo), questo è sempre il caso delle traduzioni in linea e facoltativamente per le traduzioni dei temi. Per raggiungere questo obiettivo, devi definirli con il prefisso del modulo in translate.csv:

"Mage_Catalog::Add to cart","In die Einkaufstüte legen"

Le traduzioni da moduli (come Mage_Catalog.csv) sono strettamente specifiche del modulo solo se la MODALITÀ SVILUPPATORE è attiva. Altrimenti la traduzione dal primo modulo caricato viene usata globalmente per tutti i moduli che non hanno una propria traduzione per il testo.

Ho assemblato un diagramma di flusso che mostra come ogni testo proveniente da diverse fonti viene unito nell'array di traduzione:

Unione di traduzione data è l'array di traduzione

Evil Edge Case

Se la stringa tradotta è uguale alla stringa non tradotta, la traduzione viene ignorata. A prima vista può sembrare un'ottimizzazione utile, ma in questo modo non è possibile tradurre facilmente una stringa invariata in un modulo e modificata in un altro modulo, poiché la traduzione modificata sarà l'unica e diventerà globale.

Ricerca di traduzione

Per quale modulo viene cercata la traduzione, dipende dal modulo della classe, da cui __()è stato chiamato il metodo . Quindi, la ricerca nell'array di traduzione è la seguente:

Ricerca di traduzione data è l'array di traduzione

Definizione dell'ambito

Ci sono possibilità di cambiare il modulo per una classe, che è particolarmente utile per blocchi e helper. È consigliabile impostare sempre esplicitamente il nome del modulo quando si riscrive una classe principale. Come funziona varia tra Helpers, Blocks e Contollers (a partire da Magento CE 1.9.1)

Esempio per un blocco:

class IntegerNet_AwesomeModule_Block_Catalog_Product extends Mage_Catalog_Block_Product
{
    public function getModuleName()
    {
        return 'Mage_Catalog';
    }
}

Per i blocchi, puoi anche impostare il module_nameparametro nel layout XML:

<block type="integernet_awesomemodule/catalog_product" name="test" module_name="Mage_Catalog" />

Esempio per un aiutante:

class IntegerNet_AwesomeModule_Helper_Catalog extends Mage_Catalog_Helper_Data
{
    protected $_moduleName = 'Mage_Catalog';
}

Per i controller frontend, puoi impostare la proprietà _realModuleName, per i controller admin, _usedModuleName(yay per coerenza)

Altri metodi di traduzione

Nei file XML (config.xml, system.xml, layout) è possibile specificare se i nodi devono essere tradotti con l' translateattributo. Dovresti anche aggiungere l' moduleattributo per specificare l'ambito, ma qui il valore deve essere l' alias helper , non il nome del modulo come sopra.

<one_column module="page" translate="label">
    <label>1 column</label>
    <template>page/1column.phtml</template>
    <layout_handle>page_one_column</layout_handle>
    <is_default>1</is_default>
</one_column>

In JavaScript è possibile utilizzare l' Translatoroggetto disponibile a livello globale:

Translator.translate('Please wait, loading...');

ma devi rendere le traduzioni che desideri utilizzare in JavaScript disponibili per l'oggetto traduttore. Questo viene fatto attraverso i jstranslator.xmlfile nelle etcdirectory dei moduli.

<?xml version="1.0"?>
<jstranslator>
    <loading translate="message" module="core">
        <message>Please wait, loading...</message>
    </loading>
</jstranslator>

loadingpuò essere qualsiasi stringa ma deve essere univoca a livello globale. Gli attributi translatee modulesono usati come in altri file XML. Il valore messagee la sua traduzione vengono aggiunti all'oggetto JS Translator.

Risoluzione dei problemi

Anche se conosci tutte le regole complicate, a volte è difficile capire perché alcune traduzioni funzionino (o non funzionino). Per facilitare ciò, ho sviluppato un modulo "Suggerimenti per la traduzione" che mostra da dove provengono le traduzioni:

Scarica qui: https://github.com/schmengler/TranslationHints

Immagine dello schermo: Suggerimenti per la traduzione


Sulla base dei miei post sul blog e delle diapositive sull'argomento:


2
Spero di non fare spamming menzionando che il mio modulo gratuito EmailOverride di Yireo consentirà di inserire anche i file del modulo CSV personalizzato nel tema. Non solo translate.csv.
Jisse Reitsma,

6

Hai cancellato la cache?

Il tuo sistema è impostato sulla locale del file che stai testando?

Magento può trovare il file che sta cercando quando carica la traduzione del tema (alcuni temporanei var_dump; esci; le istruzioni dovrebbero aiutare.

#File: app/code/core/Mage/Core/Model/Translate.php
protected function _loadThemeTranslation($forceReload = false)
{
    $file = Mage::getDesign()->getLocaleFileName('translate.csv');
    $this->_addData($this->_getFileData($file), false, $forceReload);
    return $this;
}

Il _getTranslatedStringmetodo può trovare ciò che sta cercando nell'array di dati?

#File: app/code/core/Mage/Core/Model/Translate.php
protected function _getTranslatedString($text, $code)
{
    $translated = '';
    if (array_key_exists($code, $this->getData())) {
        $translated = $this->_data[$code];
    }
    elseif (array_key_exists($text, $this->getData())) {
        $translated = $this->_data[$text];
    }
    else {
        $translated = $text;
    }
    return $translated;
}

Nessuna delle cache è attiva, non sono sicuro che il mio sistema sia impostato sulla locale, ma le traduzioni funzionano di conseguenza in alcuni file modello (cambiando il negozio). Ad esempio, una stringa nel mio si translate.csvtraduce correttamente in /app/design/frontend/package_name/default/template/catalog/product/view.phtmlma non in/app/design/frontend/package_name/default/template/page/html/topmenu.phtml
waffl il

Avevi ragione, qualcuno ha attivato la cache senza dirmelo. Oops, mi scuso e grazie per l'informazione!
Waffl,

3
@waffl Non c'è bisogno di scusarsi: penso che ogni sviluppatore Magento lo faccia almeno una volta alla settimana.
Alan Storm,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.