Вопрос

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

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

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

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

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

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

Спасибо, м.

Это было полезно?

Решение

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

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

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

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

Другие советы

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, чтобы предоставить переводчикам простой способ перевода и в то же время предоставлять информацию о версиях, возврат к более старым версиям, проверку качества переводчиков и т. д.

Другой скрипт, также модифицированный на основе yiic, затем берет информацию из БД и компилирует ее в массивы PHP.По сути, СОЕДИНЕНИЕ двух таблиц для каждого языка, а затем создание массива с использованием «Message». «key» и «MessageTranslation». «value» в качестве (чего еще?) ключа => значения...сохранение в файл с именем «Сообщение». «Категория» в папке, указанной языком.

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

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

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

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

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

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

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

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

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

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

protected function loadMessages($category, $language);

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top