Подтвердить что ты не робот

Yii: многоязычный сайт - лучшие практики

Я нахожу Yii отличную фреймворк, и пример веб-сайта, созданного с помощью оболочки yiic, - это хороший момент для начала... однако, к сожалению, он не охватывает тему многоязычных веб-сайтов. Документы охватывают тему перевода коротких сообщений, но не сохраняют многоязычный контент...

Я собираюсь начать работу на веб-сайте, который должен быть по крайней мере на двух языках, и мне интересно, что является лучшим способом сохранить контент для этого... Проблема в том, что контент неоднократно смешивается с общими элементами (например, встроенными видеофайлами).

Мне нужно избегать дублирования этих долей... до сих пор у меня был массив массивов, содержащих тексты (обычно не более 1-2 коротких абзацев), тогда файл представления просто отображал текст из массива.

Теперь я бы хотел не хранить его в массивах (что требует некоторого внимания при двойных кавычках) и неудобно вообще...).

Итак, что является лучшим способом сохранить эти короткие абзацы? Должен ли я хранить их в DB как (id | msg_id | language | content), а затем выбирать их с помощью msg_id и языка? Это все еще требует от меня создания некоторого msg_id и встраивания их в файл вида...

Есть ли рекомендованная парадигма, для которой Yii имеет некоторые решения?

Спасибо, м.

4b9b3361

Ответ 1

Приложение Yii по умолчанию использует метод yii:: t() для перевода текстовых сообщений, и для источников сообщений есть 3 разных типа:

  • CPhpMessageSource: переводы хранятся в виде пар ключ-значение в массиве PHP.
  • CGettextMessageSource: Переводы хранятся в виде файлов GNU Gettext. (Файлы PO)
  • CDbMessageSource: переводы сообщений хранятся в таблицах базы данных.

Если я не понимаю, вы используете классические массивы для переводов. Я рекомендую вам использовать GetText и PO файлы с Yii для операций перевода.

Вы можете найти много информации о переводе и i18n с помощью yii на этой официальной странице документации .

Ответ 2

Gettext хорош для удобства перевода, но реализация PHP по умолчанию не является потокобезопасной. Поэтому Yii использует собственный распаковщик, значительно увеличивая время обработки по сравнению с массивами php.

Поскольку я настраивал сайт с высоким объемом и высокой транзакцией, поражение производительности было неприемлемым. Кроме того, с помощью APC мы могли бы кэшировать PHP-перевод, увеличивая производительность.

Таким образом, мой подход состоял в том, чтобы использовать массивы PHP, но для перевода переводов в БД для удобства перевода, создания необходимых файлов при изменении переводов.

БД похожа на это:

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

Затем я изменил команду yiic 'message' команды CLI для вывода собранных строк в БД.

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

Как только в БД может быть настроена простая CMS, чтобы обеспечить переводчикам простой способ перевода и в то же время предоставлять информацию о версиях, возвращаясь к более старым версиям, проверяя качество переводчиков и т.д.

Другой script, также модифицированный из yiic, затем берет информацию о БД и компилирует ее в массивы PHP. В основном JOIN двух таблиц для каждого языка, затем создайте массив, используя "Message". "Key" и "MessageTranslation". "Value" as (что еще?) Key = > value... сохранение в файл с именем из ' Message '.' Category 'в папке, указанной языком.

Сгенерированные файлы загружаются как обычно Yii CPhpMessageSource.

Для изображений это было так же просто, как разместить их в папках с правильным языком и получить язык приложения при компоновке.

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

Обратите внимание, что в реальной жизни я написал небольшой вспомогательный метод, чтобы удалить страну из языковой строки, "en_us" должен быть "en".

Ответ 3

Ну, я думаю, что здесь речь идет о том, как перевести статический текст/сообщения на страницу, и Yii очень хорошо ее решает, используя Yii: t() и ответ Edigu для этого.

Я проверяю сообщение в FlexicaCMS о переводе динамического содержимого в базу данных, и в конечном итоге это будет следующим после решения статической проблемы с текстом/сообщением, и это действительно хороший подход с использованием поведения Yii. Не уверен, что авторы FlexicaCMS слишком амбициозны в том, чтобы поддерживать перевод таким образом, поскольку это сделает перевод контента бесполезной вещью - действительно здорово.

Одна вещь, о которой они не упоминают, - это URL переведенной страницы. Например, your.site.com/fr/translated_article_title.html. Я имею в виду, что url должен иметь /language _id/part, поэтому он может помочь с SEO.

Ответ 4

В Yii1 и Yii2 yii\i18n\GettextMessageSource в любом случае не использует идеальный механизм кеша Yii (посмотрите на источник), чтобы увеличить загрузку файлов PO или MO. Не рекомендуется загружать эти файлы с помощью чистого кода php (включая yii\i18n\GettextMessageSource) (он настолько медленнее, чем php-массив idx): http://mel.melaxis.com/devblog/2006/04/10/benchmarking-php-localization-is-gettext-fast-enough/

Однако php gettext ext для файлов MO - это несколько быстрее, чем перевод php-массива, потому что он использует кеш, но отрицательная точка: каждое изменение в MO требует перезапуска сервера.

Я думаю, что лучшим решением будет расширение yii\i18n\GettextMessageSource в вашей собственной библиотеке кодов и добавление способности кеша к GettextMessageSource для повышения его производительности и использования вашей расширенной версии в качестве компонента.

protected function loadMessages($category, $language);

Просто не проверяйте дату изменения MO в каждой загрузке для сравнения с кешем, а затем очищайте кеш при изменении файлов MO или PO (это может быть расписание).