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

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

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

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

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

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

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

Спасибо, м.

Ответы [ 4 ]

19 голосов
/ 09 ноября 2010

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

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

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

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

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

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

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

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

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

17 голосов
/ 25 марта 2010

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

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

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

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

1 голос
/ 15 июня 2010

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

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

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

0 голосов
/ 05 сентября 2016

В 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 (это может быть график).

...