Yii: многоязычный сайт - лучшие практики
Я нахожу Yii отличную фреймворк, и пример веб-сайта, созданного с помощью оболочки yiic, - это хороший момент для начала... однако, к сожалению, он не охватывает тему многоязычных веб-сайтов. Документы охватывают тему перевода коротких сообщений, но не сохраняют многоязычный контент...
Я собираюсь начать работу на веб-сайте, который должен быть по крайней мере на двух языках, и мне интересно, что является лучшим способом сохранить контент для этого...
Проблема в том, что контент неоднократно смешивается с общими элементами (например, встроенными видеофайлами).
Мне нужно избегать дублирования этих долей... до сих пор у меня был массив массивов, содержащих тексты (обычно не более 1-2 коротких абзацев), тогда файл представления просто отображал текст из массива.
Теперь я бы хотел не хранить его в массивах (что требует некоторого внимания при двойных кавычках) и неудобно вообще...).
Итак, что является лучшим способом сохранить эти короткие абзацы? Должен ли я хранить их в DB как (id | msg_id | language | content), а затем выбирать их с помощью msg_id и языка? Это все еще требует от меня создания некоторого msg_id и встраивания их в файл вида...
Есть ли рекомендованная парадигма, для которой Yii имеет некоторые решения?
Спасибо,
м.
Ответы
Ответ 1
Приложение Yii по умолчанию использует метод yii:: t() для перевода текстовых сообщений, и для источников сообщений есть 3 разных типа:
Если я не понимаю, вы используете классические массивы для переводов. Я рекомендую вам использовать 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 (это может быть расписание).