Як реалізувати переклади в CSV-пакет шаблонів дизайну? Як працює echo $ this -> __ ("Текст")?


29

У мене така настройка пакета дизайну:

design/frontend/package_name/theme_name/locale/

під яким я маю

de_DE, І en_GBт.д., в відповідно з яким я відповідні translate.csvфайли з різними рядками:"Key", "Translation"

Я намагаюся реалізувати різні рядки в своїй темі, використовуючи echo $this->__('Text')

Однак, схоже, це не працює (я бачу лише рядок, що ('Text')відображається всередині ). Я думаю, що мені не вистачає принципового розуміння того, коли Magento витягує рядки з CSV для перекладу. Чи можете мені хтось пояснити, як змусити ці файли csv працювати?


Яку версію Magento ви використовуєте?
philwinkle

Я використовую Magento v: 1.7.0.2
waffl

Ви називаєте це за межами звичайного файлу шаблону magento? Можливо, вам потрібно зателефонувати до класу помічників і зробити його на зразок <? Php echo Mage :: helper ('core') -> __ ('Text'); ?> Також спробуйте ввімкнути "Перекласти Inline" на Frontend в Системі> Конфігурація> Розробник
SaveTheMage

Відповіді:


84

TL; DR

Якщо вас не цікавлять деталі того, як працює переклад, пропустіть вміст до пункту
Що перевірити, чи не працює ваш переклад нижче, особливо до підрозділу «
Рішення конфлікту перекладу модуля» .

Огляд перекладу Magento

Magento надає пріоритет джерелам перекладів (від найвищих до найнижчих):

  1. БД ( core_translateтаблиця)
  2. Тема translate.csvфайлу
  3. ці app/locale/*/*.csvфайли

Як будується масив перекладу?

Модульний переклад

Спочатку всі файли з них app/locale/*/*.csv, на які посилаються активні etc/config.xmlфайли модулів , розбираються. Ось докладний процес:
Припустімо, що Magento знаходить такий config.xmlрозділ:

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

І в цьому файлі вказаний наступний переклад для мови, налаштованої для поточного перегляду магазину:

"AAA","BBB"

За цих обставин Magento створює такі записи в масиві перекладів:

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

Друге значення - це переклад застосування модуля . Назва префіксованого модуля взято з конфігураційного вузла XML, що містить декларацію файлу перекладу.

Якщо ж переклад знову встановлюються з допомогою другого файлу модуля , наприклад , в Some_Module.csvперекладі є "AAA","CCC", це буде НЕ перезаписувати на "AAA"установку. Натомість він додасть лише нову запис із назвою другого модуля "Some_Module::AAA" => "CCC".

Якщо режим розробника включений, він буде навіть скинути на "AAA"запис , якщо він знаходить другий запис з тим же ключем в іншому модулі перекладі. Це полегшує виявлення конфліктів перекладу модулів під час розробки.

Переклади тем

По-друге, переклади, завантажені з першого translate.csvфайлу в резервній програмі теми для поточного локалу, просто замінюють наявні записи в масиві перекладів.
Таким чином, продовжуючи попередній приклад, translate.csvзапис "AAA","DDD"призведе до таких даних перекладу:

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

Звичайно, записи в translate.csvновій клавіші перекладу просто додаються до масиву.

Переклади баз даних

Переклади з core_translateтаблиці в основному об'єднуються в масив перекладу так само, як і тематичні переклади.
Існуючі ключі від модуля або перекладу тем перезаписуються записами бази даних, додаються нові.

Пошук перекладу

Коли __()метод викликається, Magento спочатку шукає переклад масиву, що відповідає поточному модулю.
Поточний модуль визначається назвою класу, за яким __()викликається клас. Наприклад, у блоках відповідальний метод виглядає так:

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

Методи у Helpers and Controllers працюють відповідно.

Приклади сценарії пошуку

Для прикладу, скажімо $this->__('AAA'), називається у файлі шаблону. Якщо асоційований блок має тип Mage_Core_Block_Template, Magento спочатку перевірить Mage_Core::AAAзапис. Якщо він не знайде його, він повернеться до перекладу для ключа AAA.
У прикладі сценарію це призведе до перекладу DDDtranslate.csvфайлу).

В іншому сценарії асоційований блок може бути Mage_Catalog_Block_Product_View. У цьому випадку Magento спочатку перевірить, чи є запис перекладу Mage_Catalog::AAA, і знайде переклад AAA.

Таким чином, фактично переклади модульної області мають більший пріоритет, ніж будь-які загальні переклади. Який переклад використовується, залежить від того, який модуль класу викликає __()метод.

Що перевірити, чи не працює ваш переклад

Якщо ваш переклад з translate.csvфайлу не використовується, дотримуйтесь цього контрольного списку:

  1. Чи кеш перекладу вимкнено / оновлено? (Рішення: очистити кеш)
  2. Чи translate.csvсправді файл знаходиться в резервній програмі для поточного магазину? (Рішення: виправити конфігурацію теми)
  3. Чи є в core_translateтаблиці суперечливий запис для перекладу ? (Рішення: видалити суперечливий запис із core_translate)
  4. Якщо всі попередні пункти не є причиною, повинен бути суперечливий переклад з іншого модуля. (Рішення: див. Нижче)

Рішення конфлікту перекладу модуля

Якщо ви знайшли остаточний випадок, правда, просто додати перекладу вдруге до вашого translate.csv з модулем обсягу модуля , що виконує переклад.
У прикладі, якщо ви завжди хотіли, AAAщоб переклад був перекладений як DDDчерез переклад теми, ви можете зробити це у своєму translate.csv:

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

На практиці я додаю область модуля до перекладу лише у випадку конфлікту, тобто якщо переклад не працює.

додаткові нотатки

Вбудований переклад

Функція вбудованого перекладу Magento також додає власні переклади до core_translateтаблиці, використовуючи префікс області модуля.

Зворотна сумісність

Пріоритет тематичних перекладів раніше був вище, ніж переклад бази даних до Magento версії 1.3 або більше.

Переклад XML

Magento іноді оцінювати translate=""аргументи на config.xml, system.xmlі компоновках XML для перекладу значень дочірнього вузла.
Клас помічника може бути визначений у цих випадках, використовуючи module=""аргумент, щоб вказати модуль для області перекладу.
Якщо moduleв XML не вказано жодного аргументу, core/dataдля перекладу значень дочірнього вузла використовується помічник.

Детальна інформація

Зізнаюсь, я ознайомився з деякими деталями процесу перекладу Магенто в цій публікації, але тільки тому, що мені не хочеться надто багато інформації.

  • Деякі технічні деталі під час створення масиву перекладу
  • Можливість використання додаткових файлів перекладу для модулів
  • Зберігати область перегляду для core_translateзаписів
  • Плюси і мінуси використання різних методів перекладу

Будь ласка, задайте окреме запитання, якщо потрібна додаткова інформація.


1
Гаразд, я неймовірно шкодую всіх, але хтось інший увімкнув сховища, не сказавши мені ... Напевно, в той момент, коли я почав працювати над перекладами. Зітхнути. Ця інформація була неймовірно корисною для мого розуміння процесу перекладу в Magento. Велике спасибі, це безумовно відповідає на всі запитання, які я мав про те, як __()функція працює.
waffl

Досить хороший огляд архітектури перекладу Магенто
1414

@Vinai, відмінна відповідь. Це дійсно допомогло мені вирішити проблему перекладу я відправив питання на тут . Дивно, що Mage_Tax суперечив перекладам моєї теми, що, здається, суперечить тому, як Magento має на меті визначити пріоритет перекладів
Холлі

14

Джерела перекладу

Переклади об'єднуються з різних джерел: переклади модулів із відповідних XML-файлів, переклади тем із translate.csvпоточної теми та вбудовані переклади з бази даних.

Переклади можуть бути суто специфічними для модуля (дійсні лише в межах модуля). Це завжди стосується вбудованих перекладів і, можливо, для тематичних перекладів. Для цього вам потрібно визначити їх з префіксом модуля в translate.csv:

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

Переклади з модулів (на зразок Mage_Catalog.csv) мають суворо конкретний модуль, якщо увімкнено РЕЖИМ РОЗВИТКУ. В іншому випадку переклад першого завантаженого модуля використовується глобально для всіх модулів, які не мають власного перекладу тексту.

Я зібрав блок-схему, яка показує, як кожен текст з різних джерел об'єднується в масив перекладу:

Злиття перекладу data - це масив перекладу

Справа зла

Якщо перекладена рядок дорівнює неперекладеному рядку, переклад ігнорується. Це здається корисною оптимізацією на перший погляд, але таким чином ви не можете легко перекласти рядок без змін в одному модулі та зміненому в інший модуль, оскільки змінений переклад буде єдиним і стане глобальним.

Пошук перекладу

На який модуль шукається переклад, залежить від модуля класу, на якому __()був викликаний метод . Потім пошук у масиві перекладу здійснюється наступним чином:

Пошук перекладу data - це масив перекладу

Визначення сфери

Існують можливості зміни модуля для одного класу, що особливо корисно для блоків та помічників. Найкраща практика - завжди чітко встановлювати ім'я модуля при переписуванні основного класу. Як це працює, залежить від помічників, блоків та контролерів (станом на Magento CE 1.9.1)

Приклад для блоку:

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

Для блоків ви також можете встановити module_nameпараметр у макеті XML:

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

Приклад для помічника:

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

Для контролерів інтерфейсу ви можете встановити властивість _realModuleName, для контролерів адміністратора, _usedModuleName(так для послідовності)

Інші методи перекладу

У XML-файлах (config.xml, system.xml, макет) ви можете вказати, чи потрібно переводити вузли з translateатрибутом. Вам також слід додати moduleатрибут, щоб вказати область, але тут має бути псевдонім помічника , а не ім'я модуля, як зазначено вище.

<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>

У JavaScript ви можете використовувати Translatorоб'єкт, який доступний у всьому світі:

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

але ви повинні зробити переклади, які ви хочете використовувати в JavaScript, доступними для об’єкта перекладача. Це робиться через jstranslator.xmlфайли в etcкаталогах модулів.

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

loadingможе бути будь-яким рядком, але має бути унікальним у всьому світі. translateІ moduleатрибути використовуються як в інших файлах XML. Значення messageта його переклад додається об’єкту JS Translator.

Вирішення проблем

Навіть якщо ви знаєте всі складні правила, іноді важко зрозуміти, чому якийсь переклад працює так, як він є (або не працює). Щоб полегшити це, я розробив модуль "Підказки перекладу", який показує, звідки беруться переклади:

Отримайте його тут: https://github.com/schmengler/TranslationHints

Знімок екрана: Підказки з перекладу


На основі моїх публікацій у блозі та слайдів на тему:


2
Я сподіваюся, що я не спам, згадуючи, що мій безкоштовний модуль Yireo EmailOverride дозволить також розміщувати власні файли модулів CSV в темі. Не просто translate.csv.
Jisse Reitsma

6

Ви очистили кеш?

Чи встановлена ​​ваша система локальним файлом, який ви тестуєте?

Чи може Magento знайти потрібний файл, коли він завантажує переклад теми (якийсь тимчасовий var_dump; вихід; заяви повинні допомогти.

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

Чи може _getTranslatedStringметод знайти те, що шукає у масиві даних?

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

Жоден із кешів не є активним, я не впевнений, чи мою систему встановлено на локалі, але переклади працюють у певних файлах шаблонів відповідно (змінюючи магазин). Наприклад, рядок у моєму translate.csvперекладі належним чином у, /app/design/frontend/package_name/default/template/catalog/product/view.phtmlале не в/app/design/frontend/package_name/default/template/page/html/topmenu.phtml
waffl

Ви мали рацію, хтось увімкнув кеш, не сказавши мені. На жаль, вибачтесь і дякую за інформацію!
waffl

3
@waffl Не потрібно вибачатися - я думаю, що кожен розробник Magento робить це хоча б раз на тиждень.
Алан Шторм
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.