Wie kann ich Übersetzungen in CSVs von Designvorlagenpaketen implementieren? Wie funktioniert echo $ this -> __ ('Text')?

29

Ich habe ein Designpaket-Setup wie folgt:

design/frontend/package_name/theme_name/locale/

unter denen ich habe

de_DE, en_GBUsw., unter denen ich entsprechenden translate.csvDateien mit den verschiedenen Strings:"Key", "Translation"

Ich versuche, verschiedene Zeichenfolgen in mein Thema zu implementieren echo $this->__('Text')

Es scheint jedoch nicht zu funktionieren (ich sehe nur die Zeichenfolge in der ('Text')angezeigten). Ich glaube, mir fehlt ein grundlegendes Verständnis, wann Magento Zeichenketten aus der CSV zieht, um sie zu übersetzen. Kann jemand bitte erklären, wie man diese csv Akten erhält, um zu arbeiten?

Waffel
quelle
Welche Version von Magento verwenden Sie?
Philwinkle
Ich benutze Magento v: 1.7.0.2
Waffel
Rufen Sie dies außerhalb einer normalen Magento-Vorlagendatei auf? Möglicherweise müssen Sie die Klasse helper aufrufen und so etwas wie <? Php echo Mage :: helper ('core') -> __ ('Text') erstellen. ?> Versuchen Sie auch, "Inline übersetzen" im Frontend unter System> Konfiguration> Entwickler
SaveTheMage

Antworten:

84

TL; DR

Wenn Sie in den Details nicht interessiert sind , wie die Übersetzungsarbeiten, überspringen Sie den Inhalt bis zum
Was zu überprüfen , ob Ihre Übersetzung nicht funktioniert Abschnitt weiter unten, insbesondere den Unterabschnitt
Lösung für Module Scope Übersetzung Konflikte .

Magento-Übersetzungsübersicht

Magento priorisiert Übersetzungsquellen (von der höchsten zur niedrigsten):

  1. DB (der core_translateTisch)
  2. Die translate.csvThemendatei
  3. Die app/locale/*/*.csvDateien

Wie ist das Übersetzungsarray aufgebaut?

Modul Übersetzungen

Zuerst werden alle Dateien von app/locale/*/*.csvaktiven Modulen etc/config.xmlanalysiert , auf die verwiesen wird . Hier ist eine exemplarische Vorgehensweise:
Angenommen, Magento findet den folgenden config.xmlAbschnitt:

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

In dieser Datei wird die folgende Übersetzung für das für die aktuelle Geschäftsansicht konfigurierte Gebietsschema angegeben:

"AAA","BBB"

Unter diesen Umständen erstellt Magento die folgenden Datensätze im Übersetzungsarray:

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

Der zweite Wert ist die Modulbereichsübersetzung . Der vorangestellte Modulname wird dem XML-Konfigurationsknoten entnommen, der die Deklaration der Übersetzungsdatei enthält.

Wird dieselbe Übersetzung erneut von einer zweiten Moduldatei angegeben , z. B. in Some_Module.csvder Übersetzung "AAA","CCC", wird die Einstellung NICHT ÜBERSCHRIEBEN"AAA" . Stattdessen wird nur ein neuer Datensatz mit dem zweiten Modulnamen hinzugefügt "Some_Module::AAA" => "CCC".

Wenn der Entwicklermodus aktiviert ist, wird der Datensatz sogar gelöscht"AAA" , wenn in einer anderen Modulübersetzung ein zweiter Datensatz mit demselben Schlüssel gefunden wird. Dies erleichtert das Erkennen von Modulübersetzungskonflikten während der Entwicklung.

Themenübersetzungen

Zweitens translate.csversetzen die aus der ersten Datei im Theme-Fallback für das aktuelle Gebietsschema geladenen Übersetzungen einfach vorhandene Datensätze im Übersetzungsarray.
Wenn Sie also das vorherige Beispiel fortsetzen, würde ein translate.csvDatensatz "AAA","DDD"zu den folgenden Übersetzungsdaten führen:

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

Natürlich werden Datensätze translate.csvmit neuen Übersetzungsschlüsseln einfach zum Array hinzugefügt.

Datenbank-Übersetzungen

Übersetzungen aus der core_translateTabelle werden im Grunde genommen genau wie die Themenübersetzungen in das Übersetzungsarray eingebunden.
Vorhandene Schlüssel aus dem Modul oder Themenübersetzungen werden durch Datenbankeinträge überschrieben, neue hinzugefügt.

Übersetzungssuche

Wenn die __()Methode aufgerufen wird, sucht Magento zuerst nach einer Übersetzung in einem Array, die dem aktuellen Modul entspricht.
Das aktuelle Modul wird durch den Klassennamen bestimmt, unter dem die __()Klasse aufgerufen wird. In Blöcken sieht die verantwortliche Methode beispielsweise so aus:

// 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;
}

Die Methoden in Helfern und Controllern funktionieren entsprechend.

Beispielszenarien für die Suche

Zum Beispiel heißt $this->__('AAA')das in einer Vorlagendatei. Wenn der zugehörige Block den Typ hat Mage_Core_Block_Template, sucht Magento zuerst nach einem Mage_Core::AAADatensatz. Wenn es es nicht findet, greift es auf die Übersetzung für den Schlüssel zurück AAA.
Im Beispielszenario führt dies zur Übersetzung DDD(aus der translate.csvDatei).

In einem anderen Szenario könnte der zugehörige Block sein Mage_Catalog_Block_Product_View. In diesem Fall würde Magento zuerst nach einem Übersetzungsdatensatz Mage_Catalog::AAAsuchen und die Übersetzung finden AAA.

Tatsächlich haben die Übersetzungen des Modulbereichs eine höhere Priorität als alle generischen Übersetzungen. Welche Übersetzung verwendet wird, hängt davon ab, aus welchem ​​Modul die Klasse die __()Methode aufruft .

Was ist zu überprüfen, wenn Ihre Übersetzung nicht funktioniert?

Wenn Ihre Übersetzung aus einer translate.csvDatei nicht verwendet wird, folgen Sie dieser Checkliste:

  1. Ist der Übersetzungscache deaktiviert / aktualisiert? (Lösung: Cache leeren)
  2. Befindet sich die translate.csvDatei wirklich im Theme-Fallback für den aktuellen Store? (Lösung: Themenkonfiguration korrigieren)
  3. Gibt es in der core_translateTabelle einen widersprüchlichen Datensatz für die Übersetzung ? (Lösung: Entfernen Sie den Konfliktdatensatz aus. core_translate)
  4. Wenn nicht alle vorherigen Punkte die Ursache sind, muss eine widersprüchliche Übersetzung aus einem anderen Modul vorliegen. (Lösung: siehe unten)

Lösung für Module Scope Translation-Konflikte

Wenn Sie feststellen, dass der letzte Fall zutrifft, fügen Sie die Übersetzung einfach ein zweites Mal translate.csv mit dem Modulumfang des Moduls hinzu, das die Übersetzung durchführt.
In dem Beispiel, wenn Sie wollten schon immer AAAso übersetzt werden DDDüber das Thema Übersetzung, könnten Sie tun dies in Ihrem translate.csv:

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

In der Praxis füge ich den Modulumfang nur dann der Übersetzung hinzu, wenn ein Konflikt vorliegt, dh wenn eine Übersetzung nicht funktioniert.

Zusätzliche Bemerkungen

Inline-Übersetzung

Die Inline-Übersetzungsfunktion von Magento fügt der core_translateTabelle auch die benutzerdefinierten Übersetzungen hinzu, die das Modulbereichspräfix verwenden.

Rückwärtskompatibilität

Die Priorität der Themenübersetzungen war früher höher als die der Datenbankübersetzungen bis Magento Version 1.3 oder so.

XML-Übersetzung

Magento bewertet manchmal translate=""Argumente config.xml, system.xmlund Layout - XML - Kind - Knotenwerte zu übersetzen.
In diesen Fällen kann eine Hilfsklasse angegeben werden, indem das module=""Argument verwendet wird, um das Modul für den Übersetzungsbereich anzugeben.
Wenn moduleim XML kein Argument angegeben ist, wird der core/dataHelper zum Übersetzen der Werte des untergeordneten Knotens verwendet.

Weitere Informationen

Ich gebe zu, ich habe in diesem Beitrag einige Details des Magento-Übersetzungsprozesses beschönigt, aber nur, weil ich nicht zu viele Informationen haben möchte.

  • Einige technische Details, während das Übersetzungsarray erstellt wird
  • Die Möglichkeit, zusätzliche Übersetzungsdateien für Module zu verwenden
  • Speicheranzeigebereich für core_translateDatensätze
  • Vor- und Nachteile der verschiedenen Übersetzungsmethoden

Bitte stellen Sie eine separate Frage, wenn Sie weitere Informationen benötigen.

Vinai
quelle
1
OK, es tut mir unglaublich leid, aber jemand anderes hat die Caches eingeschaltet, ohne es mir zu sagen ... Wahrscheinlich in dem Moment, als ich anfing, an den Übersetzungen zu arbeiten. Seufzer. Diese Information war unglaublich hilfreich für mein Verständnis des Übersetzungsprozesses in Magento. Vielen, vielen Dank, dies beantwortet definitiv alle Fragen, die ich zur __()Funktionsweise der Funktion hatte.
Waffel
Eine ziemlich gute Übersicht über die Übersetzungsarchitektur von Magento finden Sie auch hier: gist.github.com/antonmakarenko/7538216
thdoan
@ Vinai, ausgezeichnete Antwort. Es hat mir sehr geholfen, ein Übersetzungsproblem zu lösen, auf das ich eine Frage gestellt habe . Überraschenderweise widersprach Mage_Tax den Übersetzungen meines Themas, was im Widerspruch dazu zu stehen scheint, wie Magento Übersetzungen priorisieren soll
Holly,
14

Übersetzungsquellen

Übersetzungen werden aus verschiedenen Quellen zusammengeführt: Modulübersetzungen aus den jeweiligen XML-Dateien, Themenübersetzungen aus translate.csvdem aktuellen Thema und Inline-Übersetzungen aus der Datenbank.

Übersetzungen können streng modulspezifisch sein (nur innerhalb eines Moduls gültig), das gilt immer für Inline-Übersetzungen und optional für Themenübersetzungen. Um dies zu erreichen, müssen Sie sie mit dem Modulpräfix in der translate.csv definieren:

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

Übersetzungen von Modulen (wie Mage_Catalog.csv) sind nur dann streng modulspezifisch, wenn der DEVELOPER MODE eingeschaltet ist. Andernfalls wird die Übersetzung des ersten geladenen Moduls global für alle Module verwendet, die keine eigene Übersetzung für den Text haben.

Ich habe ein Flussdiagramm zusammengestellt, das zeigt, wie jeder Text aus den verschiedenen Quellen im Übersetzungsarray zusammengeführt wird:

Translation Merge data ist das Übersetzungsarray

Evil Edge-Fall

Wenn die übersetzte Zeichenfolge der nicht übersetzten Zeichenfolge entspricht, wird die Übersetzung ignoriert. Das klingt auf den ersten Blick nach nützlicher Optimierung, aber auf diese Weise können Sie einen String nicht einfach unverändert in einem Modul übersetzen und in einem anderen Modul ändern, da die geänderte Übersetzung die einzige ist und global wird.

Übersetzungssuche

Für welches Modul die Übersetzung nachgeschlagen wird, hängt vom Modul der Klasse ab, auf der die Methode __()aufgerufen wurde. Dann lautet die Suche im Übersetzungsarray wie folgt:

Übersetzungssuche data ist das Übersetzungsarray

Bereich Definition

Es gibt die Möglichkeit, das Modul für eine Klasse zu ändern, was besonders für Blöcke und Helfer nützlich ist. Es wird empfohlen, den Modulnamen beim Umschreiben einer Kernklasse immer explizit festzulegen. Wie es funktioniert, variiert zwischen Helfern, Blöcken und Controllern (ab Magento CE 1.9.1)

Beispiel für einen Block:

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

Für Blöcke können Sie den module_nameParameter auch in Layout-XML festlegen :

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

Beispiel für einen Helfer:

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

Für Frontend-Controller können Sie die Eigenschaft _realModuleNamefür Admin-Controller festlegen _usedModuleName(yay für Konsistenz).

Andere Übersetzungsmethoden

In XML-Dateien (config.xml, system.xml, layout) können Sie angeben, ob Knoten mit dem translateAttribut übersetzt werden sollen . Sie sollten auch das moduleAttribut hinzufügen , um den Bereich anzugeben, aber hier muss der Wert der Helfer-Alias und nicht der Modulname wie oben sein.

<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 können Sie das Translatorglobal verfügbare Objekt verwenden:

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

Sie müssen jedoch die Übersetzungen, die Sie in JavaScript verwenden möchten, für das Übersetzerobjekt verfügbar machen. Dies geschieht über jstranslator.xmlDateien in den etcVerzeichnissen der Module.

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

loadingkann eine beliebige Zeichenfolge sein, muss jedoch global eindeutig sein. Die Attribute translateund modulewerden wie in anderen XML-Dateien verwendet. Der Wert von messageund seine Übersetzung werden dem JS Translator-Objekt hinzugefügt.

Fehlerbehebung

Selbst wenn Sie alle komplizierten Regeln kennen, ist es manchmal schwer zu verstehen, warum eine Übersetzung so funktioniert, wie sie ist (oder nicht). Um dies zu vereinfachen, habe ich ein Modul "Übersetzungshinweise" entwickelt, das zeigt, woher die Übersetzungen stammen:

Erhalten Sie es hier: https://github.com/schmengler/TranslationHints

Bildschirmfoto: Übersetzungshinweise


Basierend auf meinen Blogbeiträgen und Folien zum Thema:

Fabian Schmengler
quelle
2
Ich hoffe, ich spamme nicht, indem ich erwähne, dass mit meinem kostenlosen Yireo EmailOverride-Modul auch benutzerdefinierte CSV-Moduldateien in das Thema eingefügt werden können. Nicht nur translate.csv.
Jisse Reitsma,
6

Hast du deinen Cache geleert?

Ist Ihr System auf das Gebietsschema der zu testenden Datei eingestellt?

Kann Magento die gesuchte Datei finden, wenn es die Theme-Übersetzung lädt (einige temporäre var_dump; Exit; Anweisungen sollten helfen)?

#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;
}

Kann die _getTranslatedStringMethode im Datenarray finden, wonach sie sucht?

#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;
}
Alan Storm
quelle
Keiner der Caches ist aktiv, ich bin mir nicht sicher, ob mein System auf das Gebietsschema eingestellt ist, aber Übersetzungen funktionieren in bestimmten Vorlagendateien entsprechend (durch Ändern des Shops). Zum Beispiel wird eine Zeichenfolge in meinem translate.csvübersetzt richtig in , /app/design/frontend/package_name/default/template/catalog/product/view.phtmlaber nicht in/app/design/frontend/package_name/default/template/page/html/topmenu.phtml
waffl
Du hattest recht, jemand hat den Cache eingeschaltet, ohne es mir zu sagen. Ups, ich entschuldige mich und danke für die Information!
Waffel
3
@waffl Keine Notwendigkeit, sich zu entschuldigen - ich denke, jeder Magento-Entwickler macht das mindestens einmal pro Woche.
Alan Storm