Опыт создания мультиязычного сайта с нуля или "Пропатчи ядро и кинь в топку Localizer"

Главные вкладки

Аватар пользователя angelwise angelwise 3 декабря 2007 в 16:28

Скажу сразу, опыт малый да и с Drupal-ом пару дней как вожусь (и не надо морщиться, сам знаю, что чайник...), поэтому пишу обо всем в стиле "IMHO - как есть"...

И так, начнем.
Развернул Денвер, установил Drupal. Установил модули, которые решил применить в создании сайта. Т.к. сразу планировалось, что буду делать мультиязычный сайт (ru and en), то долго выбирал соответствующиймодуль. В итоге, посмотрев, что более свежим является Localizer - взял его. Чтоб были красивые URL, сразу активировал "чистые ссылки" (Clean URL) и модуль PATH из ядра.

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

И так по порядку, на одном примере:

  1. - В Primary Links создал пункт меню "О копании".
  2. - Создал меню "O компании", где добавил пару пунктов (например "контакты", "обратная связь")
  3. - Создал страницу "О компании", присвоил ей альтернативный адрес "about", и повесил на соответствующие пункты меню.
  4. - В закладке "Translations" (появляется для каждой страницы) сделал перевод. При этом удивился, что систем параметры меню - "по умолчанию", альтернативный адрес пуст... Перед сохранением попытался восстановить справедливость и указал альтернативный адрес about, на что система ругнулась... убрал... ура! сохранилось! (на присваемые системой номера node я пока не обращал внимание)
  5. - В настройке блока с меню "O компании" установил видимость для соответствующих страниц, исходя из адресов для русской локали и...

Вот тут и увидел, что в случае русской локали - все нормально, однако в случае английской - нужный мне блок, в нужном мне месте, - не появляется. Стал разбираться. Выключил "чистые ссылки", отменил альтернативные имена и начал смотреть.

Оказывается, что при переводе страницы, результатом служит два разных адреса, для разных локалей: node/1 и node/2 соответственно. А я то поначалу думал, что будет все выглядеть например так: site.com/ru/node/1 и site.com/en/node/1 или что-то в этом роде. Сразу скажу, что настройка Localaizer/By hostname выключена, чтоб не мучаться с разными внутренними ссылками. Да и что за мультиязычность, которая решается путем разных хостов? Нам ведь не мультисайтинг нужен!

Вывод - красивого мультиязычного сайта не получится, все придется делать с симптомами гемор...я...

Так к чему я это все подвожу! К тому, что не каждую задачу можно решить дополнительными модулями. А именно те, которые по логике должны решаться ядром, а не его расширением. Вот и функциональность мультиязычности должна присутствовать сразу в ядре. Такая функциональность не помешает для создания одноязычного сайта, но и легко позволит иметь мультиязычный контент с едиными индентификаторами (в нашем случае node/1).

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

Имея представление, что вся работа CMS строится на БД, то и плясать надо от туда.

Вся работа с контентом крутится вокруг двух таблиц: node и node_revisions. Сруктура таблиц такова:
NODE

nid vid type title uid status created changed comment promote moderate sticky
1 1 page O компании 1 1 1196625136 1196671388 0 0 0 0
2 2 page About Us 1 1 1196671240 1196671270 0 0 0 0

NODE_REVISIONS

nid vid uid title body teaser log timestamp format
1 1 1 O компании Основным направлением комп... Основным направлением комп...   1196671388 3
2 2 1 About Us The main purpose of our company is marketing of sy... The main purpose of our company is marketing of sy...   1196671270 3

Во-первых, сразу видим, что присутствует избыточность данных. А именно: поле Title присутствует в обоих таблицах.
Во-вторых, имея в распоряжении ядра таблицу Locales_meta

locale name enabled isdefault plurals formula
en English 1 0 0  
ru Russian 1 1 3  

можно сразу реализовать мультиязычность контента следующим образом: в таблицу node_revisions добавить поле locale и соответственно индексировать. При выводе результатов в условия запроса добавлять значение текущего Locale.

Примеры:
- запрос доступных страниц на том или ином языке может выглядеть следующим образом:
SELECT t1. *
FROM node t1
WHERE t1.nid = t1.nid
AND NOT EXISTS (SELECT 1
FROM node_revisions t2
WHERE t2.nid = t1.nid
AND t2.locale = :locale
)

- запрос страницы по определенному node на том или ином языке может выглядеть следующим образом:
SELECT t1 . * , t2 . *
FROM node t1, node_revisions t2
WHERE t2.nid = t1.nid
AND t2.locale = :locale

ну т.д.

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

Теперь обращение к ГУРУ в PHP и Drupal:
- Если Вы увидели какие мои ошибки в использовании модуля Localizer, прошу на них указать.
- Выскажите свое мнение по вопросу реальности (без флуда) создания соответствующего Patch к ядру системы, который может в последующем и войти в само ядро.
- Может кто не побоится написать такой Patch? Я уверен, что многие во всем не англоязычном мире будут ва признательны.

PS: Почему не Я? Потому, что я абсолютный НУЛЬ в PHP? НО! могу помочь с формированием и отладкой запросов к базе данных...

Вот и все, что хотел рассказать миру. Это мой первый в жизни пост в рамках какого либо дневника, поэтому, прошу камнями не кидаться ... шутка Smile

Комментарии

Аватар пользователя angelwise angelwise 3 декабря 2007 в 18:35

Цитата с Drupal.org:

"The interface strings of Drupal 6.0 are not frozen yet. We improved on a lot of help texts and interface elements in this beta version. A notice will be sent to the translators mailing list, when the interface is close to being ready for translation. Until that time, there is no point in starting to translate, so we are not providing translation templates." (http://drupal.org/drupal-6.0-beta3)

Здесь больше говорится о строках интерфейса. Подозреваю, что речь идет о некоторых модулях настройки, типа этого admin/user/settings, где нет поддержки локали и для универсальности в текст письма надо вставлять два языка, что не приемлемо если сайт будет на трех.

О том, что в ядре будет сидеть аналог Localizer-а - я что-то такого намека тут не вижу.

Наверно много времени у них ушло на устранение багов и написание "бантиков" типа drag-and-drop для одного модуля... и без этого не плохо живется. А вот чего-то типа workflow с поддержкой web-services в ядре не слышно.

Может я и ошибаюсь, но времени потестить шестерку пока нет... Sad

Аватар пользователя axel axel 3 декабря 2007 в 21:01

В D6 модуль localizer входят в стандартные модули и использует node для хранения ссылок на язык:
<?php
+-----------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------------+------+-----+---------+----------------+
| nid | int(10) unsigned | NO | PRI | NULL | auto_increment |
| vid | int(10) unsigned | NO | UNI | 0 | |
| type | varchar(32) | NO | MUL | | |
| language | varchar(12) | NO | | | |
| title | varchar(255) | NO | MUL | | |
| uid | int(11) | NO | MUL | 0 | |
| status | int(11) | NO | MUL | 1 | |
| created | int(11) | NO | MUL | 0 | |
| changed | int(11) | NO | MUL | 0 | |
| comment | int(11) | NO | | 0 | |
| promote | int(11) | NO | MUL | 0 | |
| moderate | int(11) | NO | MUL | 0 | |
| sticky | int(11) | NO | | 0 | |
| tnid | int(10) unsigned | NO | MUL | 0 | |
| translate | int(11) | NO | MUL | 0 | |
+-----------+------------------+------+-----+---------+----------------+
?>

По title в node и node_revisions замечу, что достаточно конечно хранения только в таблице ревизий, но для эффективности выборок (выборки вида id, title для нодов очень часты) сдублировали в node. Да, конечно это нарушает правила нормализации, но иногда ими приходится поступаться ради эффективности.

Аватар пользователя VladSavitsky VladSavitsky 3 декабря 2007 в 17:36

Молодец! Вот это настоящий хакер в хорошем смысле этого слова - не успокоится пока не разберётся как работает! Патч делать не помогу - пока мне мультиязычность не интересна, но статья мне понравилась...

Аватар пользователя restyler restyler 3 декабря 2007 в 21:40

d5 в этом плане мультиязычности крив, что localizer, что i18n
Ладно ноды, но вот все остальное.. Localizer требует патчей к модам ядра типа blocks, taxonomy, menu
i18n требует дублирования терминов в таксономии, по термину для каждого языка. Ужоснах, что я еще могу сказать.
короче ждем d6.
Сейчас делаю на localizer'е проект, все перепатчил перехакал.. баги кое-где лезут, таки.

Аватар пользователя Libra Libra 4 декабря 2007 в 0:48

Уже довольно давно использую Localizer - никаких патчей сейчас этот модуль не требует, все решено достаточно красиво. Единственное, что после недавнего обновления на dev-версию перестала работать локализация блоков - просто еще руки не дошли разобраться... А так очень даже приятные впечатления, но обратно же - каждому свое. У модулей localizer и i18n просто разная идеология. Шестерку еще не смотрел...

Аватар пользователя restyler restyler 4 декабря 2007 в 9:34

"довольно давно" не требовал, еще летом.
Теперь вот - требует, без патчей блоки и перевод таксономии не пашут.

Аватар пользователя angelwise angelwise 4 декабря 2007 в 20:05

А примерчики можно? Чисто посмотреть, коррелируют ли они с поставленными задачами...

А то без примерчика и возразить нечего...

Аватар пользователя Виктор В. Виктор В. (не проверено) 4 декабря 2007 в 13:16

Любую проблему можно решить несколькими способами. Да и мнения у всех разные. Например, я считаю извращением по одному адресу типа node/1 отдавать РАЗНЫЕ документы, не зависимо от того нужна ли локализация или не нужна. А если человек wget'ом сайт качает что ему будет отдаваться? Smile

Аватар пользователя angelwise angelwise 4 декабря 2007 в 20:03

Скажите, а для каких целей нужно скачивать сайты? Мы их разве для этого делаем?

Со времени приобщения к интернету ни я ниразу не подумал, чтоб скачать сайт целиком, да и среди большого числа знакомых никто этим и не мается. Все достаточно, что сайт лежит там где лежит.

Аватар пользователя Виктор В. Виктор В. (не проверено) 5 декабря 2007 в 9:21

Скажите, а для каких целей нужно скачивать сайты? Мы их разве для этого делаем?
А почему обязательно сайты? Может я хочу конкретную доку себе выкачать или раздел с доками для offline чтения!
Для чего ВЫ делаете сайты, я не знаю. У других людей цели могут быть другими, которые не совпадают с вашими.
Но вы не поняли о чём я хотел сказать! Каждый документ на сайте должен иметь УНИКАЛЬНЫЙ адрес! Т.е. если я набираю на URL, например http://kaka.baka.ru/kaka, то хочу получить документ КАКА, а не БЯКА, вне зависимости от того русский я или англичанин или вообще парагваец.

Аватар пользователя angelwise angelwise 5 декабря 2007 в 19:49

Вот и я о том же, что для уникальности пути к страницам на разных языках, в нем должно быть присутствовать указание на этот самый язык. Причем указание должно подставляться автоматически. А вот документ, как объект, должен иметь единый идентификатор. Указание языка - это всего лишь свойство документа. Ибо, по своему составу и назначению документ един, что на русском, что на английском и т.д. языках.

Аватар пользователя run run 16 декабря 2007 в 11:37

Да, посмотрим на Drupal6. Но это часть проблемы, а как сделать чтоб при переключении языка переключалась также и тема?

Аватар пользователя 237us 237us 24 января 2009 в 23:57

Добрый вечер, Господа, как можно справиться с проблемой в 5-м друпале - переключать блоки вместе со всем отсальным контентом? У меня стоит localaizer, поставить в месте с ним i18n неполучаеться, возможно есть какое то решение? Сайт 3-х язычный.
Раз уж о них тут упамянулось, спрошу, возможно ктонибудь сталкивался с подобной ситуацией при установки "Чистых ссылок" - http://drupal.ru/node/23652
Возможно их нужно подключать при установке сайта, перед формированием контента? И как грамотно перейти и стоит ли на 6-й с 5-го друпала?
Заранее спасибо.