Pull to refresh

Реализация и универсализация i18n в CMS/CMF

Reading time4 min
Views3.9K

Предисловие


Столкнулся с насущной проблемой, которая автоматически становится задачей:
Как реализовать универсальный механизм перевода контента сайта, который удовлетворял бы потребности как маленьких сайтов, так и больших порталов?


Хотелось бы услышать мнение компетентных хабрапользователей, которые сталкивались с данной или подобной задачей.



Итак, поставим задачу:
Нужно реализовать мультиязычный сайт, который будет удобно редактировать и переводить. Сайт состоит из n-го числа статических страниц. Количество языков не определено, может быть 2, может быть 20.

Ориентировочная структура таблицы следующая:
id - идентификатор страницы (не переводится);
title - заголовок страницы (переводится);
description - краткое описание страницы (переводится);
full_text - полный текст страницы (переводится).

Аргументы:
  • Есть инструмент — самопальный CMF, который обучен автоматической генерации админки, генерации вывода контента (все генераторы построены на структуре базы) и многим другим приятными удобствами для облегчения рутинного труда.
  • Есть идеи по реализации выложенные ниже.

Результат:
  • Удобный административный интерфейс для перевода контента сайта.
  • Тривиальный сайт со статическими страницами на большом количестве языков.


Перейдем к идеям


Я не думал над названиями идей, но буду субъективно характеризовать. Так и будем их идентифицировать.

1. Плохая, понятная и общедоступная:
Не париться с универсализацией и создавать в этой же таблице поля с постфиксами определяющий каждый язык, т.е. выйдет так:
id
title_ru
description_ru
full_text_ru
title_en
description_en
full_text_en

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

2. Понятная, правильная и нормальная:
Более универсальна чем предыдущая. Добавляем в эту таблицу только одно поле:
id
title
description
full_text
culture <-

Где culture — идентификатор языка текущей страницы.
Минус в том, что когда пользователь находится на определенной странице, то сайт не может точно знать, где находится перевод на конкретную страницу. При большом количестве языков, языковые версии сайта, могут быть абсолютно разными. Редактирование простое: выбрал язык на котором хочешь редактировать, и там управляешься с добавлением новых страниц.

3. Понятная, правильная, нормальная и улучшеная:
К предыдущей структуре добавляем еще одно поле:
id
title
description
full_text
culture
parent_page_id <-

Где parent_page_id — идентификатор оригинала страницы.
Тогда у нас минус предыдущей структуры убирается. Но добавляется зависимость от языка оригинала. Редактирование такое-же как у предыдущей модели, добавляется один селект с большим количеством страниц на оригинальном языке.

4. Интересная, правильная, но более сложная:
Структура таблицы page:
id
и другие поля, которые не нуждаются в переводе, например идентификатор раздела в который положена эта страница

Добавляем таблицу page_i18n:
id
page_id - идентификатор страницы из таблицы page
title
description
full_text
culture - язык страницы

Соответственно для вывода придется использовать выборку из двух таблиц.
Редактировать такую структуру не сложно. Можно выбирать даже направление перевода. Можно перевести конкретную страницу. Найти на каких страницах нет перевода. Есть полная связка страниц на сайте.

5. Интересная и сложная, вики-перевод:
Идея механизма перевода взята из launchpad.net
Хороша для больших проектов где есть много переводчиков.

Так же как в прошлом варианте.
Структура таблицы page:
id
и другие поля, которые не нуждаются в переводе, например идентификатор раздела в который положена эта страница

Добавляем таблицу page_i18n_cache:
id
page_id - идентификатор страницы из таблицы page
title
description
full_text
culture - язык страницы
и другие поля, которые не нуждаются в переводе, например идентификатор раздела в который положена эта страница

Создаем таблицу i18n_translate:
id
page_id - идентификатор страницы из таблицы page
field - название поля из таблицы page_i18n_cache, например title
translate - перевод этого поля
user_id - пользователь который сделал перевод
publish - является ли эта версия опубликованной
culture - язык страницы
возможны и другие поля, для запоминания данных о переводе, например дата перевода, кто модерировал перевод и т. д.

  1. В данном случае имеем безупречную независимость от оригинала, т.е. можем выбрать языком оригинала любой язык.
  2. «Кэшированую» схему, т.е. для выборки конкретной страницы, нам нужно сделать одну выборку и не сливаясь с другими таблицами. В кэшированой таблице находятся только опубликованные версии перевода.
  3. Интерфейс перевода простой: пользователь видит строку оригинала, переведенные другими пользователями строки и поля для ввода своего варианта.


Итог


Я абстрактно описал те 5 моделей к которым пришел. В интернете нашел информацию только по первым двум вариантам.
Очень интересно услышать ваше мнение, как правильно реализовать данный механизм перевода. Интересна информация о интерфейсах перевода (конкретно для коммерческих проектов).

Спасибо за внимание!
Tags:
Hubs:
+24
Comments125

Articles

Change theme settings