Pull to refresh

Comments 35

Как осуществляется синхронизация данных? Структуру и контент каждого сайта надо создавать независимо? Как Вы делаете, чтобы не забыть продублировать, скажем, статью на обоих сайтах — чтобы они оставались «синхронизированны»?
а зачем что-то синхронизировать? всё в одной СУБД — это в принципе один сайт; просто система знает откуда брать контент. Со стороны администратора это выглядит вот так


Причуда мультиязычности — этот текст на чистом английском в базе будет помечен как 'de', т.к. предназначен для морды на немецком.
так и есть — это для перевода была закопипасчено
UFO just landed and posted this here
собираю проф. мнения :)
вы собственный фреймворк используете?

В таком случае расскажу как у нас:

в конфиге — перечисляю языки и язык по-умолчанию.

В модели (используем MVC), у конкретного поля указываем аттрибут multilanguage = true.
Это значит, что в базе создается несколько полей {#имяполя}_{#язык}

А куда язык прикрутить — для фреймворка без разницы (сессия, урл, поддомен)

Пример?
---app.cfg----

# Language settings ##
######################
default_language = en
languages = en,it


---model----

$this->insert_field(array(
«column» => «title»,
«type» => «varchar»,
«value» => "",
«multilingual» => 1,
));


хелпер для шаблона edit для отрисовки поля: {%article_title_input%}. Он содержит подшаблон и печатает «язык: инпут»

Для view шаблона — {%article_title%}. Модель берет значение из языка по-умолчанию.

Статический контент — это переменные шаблона {%str_label_article_title%}.
И файлы-переводчики.


news_list = News
recent_news_list = Recent news
filter_by = Filter by
article_text = Text
event_text = Text
special_offer_text = Text
installation_text = Text
en = English
it = Italian
ge = Romanian
hu = Hungarian


Немножко сумбурно, но надеюсь, yfgbcпонятно.

да, у меня свой framework — работает в принципе точно так же :) welcome!
тяжело придумать более удобную систему, не потеряв гибкости ;)

Кстати, симфони, например, предлагает создавать отдельную таблицу с именем {#Modelname}I18n

Мультиязычное поле (в нашем примере это «title») исчезает с основной таблицы и попадает во вновь созданную уже размноженным. Естественно, связь таблиц, позволю себе немножко рельсовости — belongs_to/has_one.

Тоже выход, только непонятно зачем еще одна таблица.

Видел еще вариант, когда все мультиязычные поля содержаться в одной отдельной таблице. А в основной таблице — ссылка на элемент I18n-модели. Не очень удачный вариант, но тоже имеет право на жизнь.
это уже явно перебор, ровно как и 5й уровень нормализации данных в БД. я всегда за идеальное сочетание гибкость/удобство — даже в ущерб «теории» :)
хорошая вещь, просто надо писать синхронно… а это не всегда удобно.
Если же нет, то этот вариант ничем не отличается от варианта с «несколькими сайтами», в смысле у каждого языка своя структура
 что произошло в моем случае. Предо мной встал вопрос
1) или сохранить структуру, но писать пришлось бы синхронно, а делался сайт с 5 языками
2) или писать каждый язык отдельно, но при этом у каждого языка была своя структура

выбрал я вариант второй, т.к. заказчика первый не устроил
правильно ли я понял, что у вас по сути — пять отдельных сайтов?
Самый кошерный способ — xml, подгрузка xml-файла с контентом на нужном языке, а структура файла остается неизменной. Тут уже реальное разделение и логики и содержания, никто никому не мешает.
не подскажете, как именно, на каком этапе вы подгружаете хмл и его структуру?
Что будет с такой системой, если структура разделов в разных языковых версиях различается?
Многоязычные приложения

PHP и GetText — профессиональная работа: php.russofile.ru/ru/authors/multilangual/php_gettext_prof/
Хранение динамических данных: php.russofile.ru/ru/authors/multilangual/dynamic/
Мне понравилась идея разбивать таблицы, так что одна будет содержать поля, которые не зависят от языка, а другая — текстовые.

> 1 таблица (table1)
> news_id
> news_start
> news_stop
> news_visible
> 2 таблица (table2)
> news_id – уникальный номер новости из первой таблицы
> news_lang – уникальный двухбуквенный идентификатор языковых данных
> news_subject – тема (заголовок) новости
> news_short – короткая новость на языке с кодом из news_lang
> news_full – полная новость на языке с кодом из news_lang

В своей статье ты определил, что текстовый контент новости уникален для каждого языка. Т.е. между языками он не пересекается. Поэтому чутье подсказывает, что нужно создавать table2_ru, table2_en и т.д. — индексы меньше, поиск быстрее. Но ты предлагаешь переводы хранить в одной таблице. Каков в этом практический смысл?

я предлагаю так:

system_languages:lang,name (en-English,ru-Русский,de-Deutsch) -->

news:news_id,created,published,publisher,url,foo,bar
news_content:news_id,lang,subject,teaser,content

И тут у меня появляется гибгость как при поиске так и при отдаче данных, например отдавать контент на языке А если его нет на языке Б :) идея понятна?
почти то же самое написал :)) относительно поиска — индексирование это отдельная тема и да, в индексе я бы тоже указывал из какого языка оно создавалось
А из базы контент выгребается сразу на двух языках: языке юзера и языке по умолчанию? Т.е. так:
SELECT *
FROM news N
INNER JOIN news_contents NC ON N.news_id = NC.news_id
WHERE NC.news_lang IN (?clientUILang, ?defaultLang)
Смысл в том, что считать большим объёмом данных. Экономить на спичках создавая себе геморрой не стоит. к тому же ты усложняешь в разы выборки своей идее, от чего я и предлагал избавиться.
я действительно не понял, поэтому прошу привести пример таких выборок.
Ну как вы например собирайетесь джойнить сразу две языковые таблицы? Вам не кажется что это будет сильнее напрягать сервер нежели одно но чуть большая таблица?
Вы упорно не приводите примеров и я продолжаю непонимать. ㋡

Возможно вот где проблема. Для выборки мультиязычных данных может применяться еще одно правило: «отдавать контент на языке Ⓐ, а если его нет, — на языке оригинала», где язык оригинала это тот, на котором была изначально написана контентина. Тогда версии на всех остальных языках это переводы. А перевод уже _зависят_ от оригинального текста. Наличие такой зависимости влияет на структуру БД.

Для реализации этой идеи на основе Вашего примера, в таблицу news нужно добавить поле news_orig_lang (язык, на котором была изначально написана новость).

news:
news_id, news_orig_lang, news_start, …
news_content:
news_id, news_lang, news_subject, …

Тогда запрос вида: вытащить «перевод» и оригинал будет выглядить так:
SELECT * news_id N
INNER JOIN news_contents NC ON N.news_id = NC.news_id AND NC.lang = N.news_orig_lang
LEFT JOIN news_contents NCtr ON N.news_id = NCtr.news_id AND NCtr.lang = ?userUILang

т.е. через INNER JOIN цепляется язык оригинала, а через LEFT JOIN — перевод.
Именно так мы в нашем проекте и делали.
Только «news_orig_lang» одинаков для всего проекта (ну IRL так обычно и бывает), в нашем случае это был английский. Его мы сразу задаем мускульной константой SET LANG = 'en'
Отдельный минус — вагон и маленькая тележка ифов внутри селекта, то б получить только переведенные данные.
Иначе говоря, описанная вами структура имела бы вид:
SELECT
IF (nc.news_subject != '', nc.news_subject, nc_en.news_subject),

FROM news n
JOIN news_content nc_en ON nc_en.news_id=n.news_id AND nc_en.lang=@LANG_ID
LEFT JOIN news_content nc ON nc.news_id=n.news_id AND nc.lang=?userUILang

Запросы получаются довольно большие, но работает все это весьма шустро.
Зачем придумывать такой велосипед жестокий, да еще и в запросе делать кучу ифов? Когда можно запросить сразу две записи — дефолтную и на нужном языке? И тупо отфильтровать по null?
Как запросить и как отфильтровать? Средствами PHP что ли?
Пример запроса можно, который даст нам готовые к выводу данные?
Все примеры есть в статье, каких еще вы от меня примеров хотите?
Не надо туда ничего добавлять — прочитайте уже внимательно статью.
кстати, можно задать еще один вопрос про статью? ;)

в части «Общий контент» Вы предложили формат и набор процедур для сохранения мультиязычных данных в общем поле БД. Почему не используете стандартные serialize()/unserialize()? На первый взгляд это было бы проще.
Ну они больше места занимают всяким мусором и потом как-то не хочется хранить в базе данные в по сути неизвестном формате, без гарантии что его не поменяют. Вообще я на самом деле не советовал ТАК хранить данные, просто как пример приводил.
Принцип работы таков:
  • — каждый язык на отдельном домене, например: site.ru, site.ua, site.com
  • — движок у всех сайтов один — все лежит в одном DOCUMENT_ROOT (все домены — алиасы для основного)
  • — по домену определяем язык
  • — для выбранного языка используем свой локализированный конфиг
  • — подгружаем свои CSS (если, скажем, есть заголовки-картинки с текстом)
  • — подключаемся к БД и пользуем таблицы с префиксом языка ru_, en_ ua_, либо вообще к другой БД
  • — включаем свой google analytics
  • — ЧПУ для каждого сайта можно делать свой, так как структура сайта и контент независимы у каждой версии
  • — Все картинки лежат в том же DOCUMENT_ROOT


Преимущества такого подхода:
— Каждая языковая версия может кардинально отличаться по структуре. Пример: Компания — официальный дилер фирм на территории Украины, которые имеют свои представительства в России, Польше, Беларуси и т.п. Кроме того, Компания — производитель продукции, которой интересуются не только жители Украины, но и зарубежья. Соответственно для сайта на укр. языке нужно показывать весь каталог товаров (дилерские в т.ч.). На сайте в зоне .ru, который рассчитан на Россию, нужно продвигать только собственную продукцию, потому как дилерская не интересна. Сайт на английском языке — сайт, скажем для инвесторов, который должен быть только с общей информацией о Компании, чтобы дать возможность ознакомиться с производственными мощностями.
— Не будет «многоязычности» на локализированом сайте: когда весь сайт на русском, а некоторые товары либо блоки на английском, потому что не дописаны.
— Возможность четко распределить обязанности по поддержке каждой языковой версии сайта на отдельных людей в Компании.
— Если поломают структуру на одной версии — на другой все будет в порядке.

Минусы подхода:
— Если сайты не сильно различаются на разных версиях — производится дублирование контента (картинки для товаров загружаются по нескольку раз)
— Добавить еще один язык не сможет Компания сама — необходимо участие разработчика.

Может еще какие-то минусы видите? Прошу комментировать.
Sign up to leave a comment.

Articles