Работа с многоязычным меню

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

Аватар пользователя roman-yrv roman-yrv 11 апреля 2013 в 18:29

Добрый день.

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

1. Если на сайте используется несколько языков и для каждого языка будет развернутое меню, то с этим меню просто будет неудобно работать (см. рис.)
На рисунке ниже у меня два языка и не такое уж развернутое меню. А если языков будет несколько, и по каждому языку будет более развернутая структура ?

Существует ли какой-нибудь модуль, который бы позволил фильтровать элементы меню, расположенные на рисунке, по языкам ?

2. Решил попробовать настроить перевод узлов через Entity Translate + Title, а меню - через локализацию.
То есть, в этом случае для двух языков будет одна нода, два набора переводимых полей и один пункт меню с локализациями.
Причем, заголовок пункта меню первоначально вводится на русском языке, а потом локализуется уже на английский и т.д.
Получается как бы удобно, но вот с локализацией пунктов меню происходят какие-то проблемы - когда редактируешь английский перевод страницы, то вместо локализованного названия пункта меню отображается русское название, которое используется для русской версии страницы.
Поизучав код, пришлел к выводу, что функция t() в данном случае работает не совсем корректно - SQL-запрос внутри функции locale() вообще не сможет получить англоязычный перевод пункта меню.
Потому что там в SQL-запросе стоит условие

WHERE s.textgroup = 'default'

А в случае меню textgroup будет равно menu.
Вопрос - стоит ли вообще настраивать перевод нод через Entity Translation ?
И есть ли решение проблемы с локализацией меню в данном случае, кроме как писать свою функцию для получения перевода фразы, заменяющую t() ?

3. При использовании Entity Translation при редактировании английский версии страницы возникает такая не очень хорошая вещь, как автоматический перевод элементов формы редактирования ноды (см. рис.)

Существует ли решение данной проблемы ?
А то если редактор сайта английские слова с горем пополам поймет, то как ему редактировать, к примеру, китайский или арабский вариант страницы ?

4. В настройках типа ноды можно задать родительский пункт меню по умолчанию, если возникнет необходимость при создании ноды добавить пункт меню (см. рис.)

Есть ли решение, которое бы задавало пункт меню по умолчанию не просто для типа ноды, а для типа ноды + языка ввода ?
То есть, если я ввожу данные об одном клиенте на русском языке и добавляю пункт меню, то его родительский элемент меню - "Клиенты".
А вот если я ввожу перевод этой страницы на английский язык, то чтобы этот пункт меню добавлялся уже к родительскому англоязычному пункту "Clients".

Лично я вижу решение только руками - где-то, например, в мультиязычных переменных хранить mlid родительских пунктов, а на этапе формирования формы ввода ноды переопределять родительский пункт меню, если создаваемая нода на другом языке.
Есть ли решение данной задачи в виде модуля ?

ВложениеРазмер
Иконка изображения menu-multilanguage.png14.76 КБ
Иконка изображения nie-multilang.png23.35 КБ
Иконка изображения menu-parent.png16.16 КБ

Комментарии

Аватар пользователя kodo kodo 12 апреля 2013 в 7:23

В двух словах:
1. Поставьте язык по-умолчанию - Английский - и с него перевод на русский, а не наоборот
2. Для управления поставьте Admin Language

Аватар пользователя roman-yrv roman-yrv 12 апреля 2013 в 8:42

Admin Language у меня установлен.

Насчет языка по умолчанию - клиент ведь, как правило, работает таким образом.
Сначала вводит данные на русском языке. Там же вводит название пункта меню.
А потом уже добавляет переводы со своими пунктами меню на тех же языках.

Тем более, что структура таблиц locale_source и locale_target вполне позволяет изначально задать фразу на русском, а локализации задавать на английском и т.д.

А насчет того, чтобы элементы меню фильтровать по языкам - нашел модуль, который позволяет это делать - i18n_menu_overview

Аватар пользователя kodo kodo 12 апреля 2013 в 18:22

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

Аватар пользователя roman-yrv roman-yrv 12 апреля 2013 в 19:15

kodo wrote:
Я просто по опыту знаю, что если оставлять основным языком не английский в мультиязычном сайте, то постоянно будут вылазить траблы. Почти уверен, что следующий вопрос будет по переводу таксономии.

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

kodo wrote:

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

Или нервы вытрепает по этому поводу. Smile

kodo wrote:

И по скриншотам не понятно зачем вводить "два меню" если достаточно их перевести (конечно при наличии одинаковых ссылок)?

Два меню - потому что у меня на тот момент, видать, было не очень много опыта в друпалерстве и многоязычность я настроил не через Entity Translation, а путем создания для каждого языка своей ноды.
А как сделать так, чтобы у этих создаваемых нод был одинаковый адрес независимо от языка, я тогда толком разобраться не смог. То ли времени не хватило, то ли посчитал, что и так нормально.
Тем более, если нода не ключевая, типа "О компании" или "Контакты", которая одна на сайт и у которой можно руками задать ссылку для всех языков.

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

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

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

2. Сделать так, чтобы справочные тексты - названия вкладок, надписи на кнопках и т.д. на форме редактирования ноды были русскоязычными независимо от языка редактирования.

Аватар пользователя kodo kodo 13 апреля 2013 в 8:33

"roman-yrv" wrote:
А если, к примеру, сайт многоязычный, но английский там как бы и не нужен.
Например, где-нибудь в Узбекистане - есть русская версия и есть узбекская.
Или на Украине - есть русская версия, есть украинская.
Не создавать же английскую версию только потому что иначе траблы вылазят.

Не создавать Smile Английский основной, только когда он присутствует как один из языков сайта.
"roman-yrv" wrote:
Или нервы вытрепает по этому поводу. :)

Это проще, чем трепать себе нервы по траблам. Smile Правельнее решать зачаду простыми методами.
"roman-yrv" wrote:
Два меню - потому что у меня на тот момент, видать, было не очень много опыта в друпалерстве и многоязычность я настроил не через Entity Translation, а путем создания для каждого языка своей ноды.

Это метод Друпал 6 - там просто 2 меню создавалось, и показывалось в зависимости от языка. (в блоках это тоже регулируется)
"roman-yrv" wrote:
А вообще, согласен, что удобнее - делать перевод через Entity Translation, чтобы нода была одна, а пункты меню чтобы переводились, а не дублировались для разных языков.

Entity Translation я обычно применяю как раз только в том случае, когда необходимо (или проще) перевести 1 поле body из 10 - к примеру для товара. Обычные ноды проще переводить с созданием новой ноды на другом языке.
"roman-yrv" wrote:
2. Сделать так, чтобы справочные тексты - названия вкладок, надписи на кнопках и т.д. на форме редактирования ноды были русскоязычными независимо от языка редактирования.

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

Аватар пользователя roman-yrv roman-yrv 13 апреля 2013 в 10:07

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

C этом удалось разобраться, спасибо за наводку.
Добавил в список путей-исключений в Admin Languauge вот это - node/*/edit/* (там для английской версии было node/5/edit/en)

А с исправлением локализации меню все-таки попробую реализовать свою идейку с написанием своей функции для получения локализованного значения из таблицы.
Если получится - отпишусь.

Аватар пользователя kodo kodo 13 апреля 2013 в 19:02

"roman-yrv" wrote:
А с исправлением локализации меню все-таки попробую реализовать свою идейку с написанием своей функции для получения локализованного значения из таблицы.
Если получится - отпишусь.

На орге поищите, что-то должно проскакивать - думаю на эти грабли многие наступали.

Аватар пользователя roman-yrv roman-yrv 15 апреля 2013 в 12:07

Реализовал идейку с меню.
Вроде бы, работает.

В своем модуле описываю функцию, которая будет брать локализацию из таблиц locales_source и locales_target.

function yrv_t($original_text, $context, $lang)
{
  $strSQL='select lt.translation '.
          'from {locales_source} ls, {locales_target} lt  '.
          'where ls.lid=lt.lid '.
          'and ls.source=:original_text '.
          'and ls.context=:context '.
          'and lt.language=:language ';
  $result=db_query($strSQL,array(':original_text'=>$original_text, ':language' => $lang, ':context' => $context));
  foreach ($result as $record) {
    return $record->translation;
  };
  return '';
}

Далее в хуке hook_form_alter беру значение англоязычного меню с помощью этой функции.
Подразумевается, что уже установлен модуль title и перевод делается через Entity Translation.
Текущий язык получаю из языка title - не разобрался с тем, как текущий язык можно получить иначе.

function yrv_util_form_node_form_alter(&$form, &$form_state, $form_id)
{
  $lang=$form['title_field']['#language'];
 
  if ($lang!='ru')
  {
    // Если данная редакция ноды - не русский язык, то название элемента меню брать из локализации.
    $mlid=$form['menu']['link']['mlid']['#value'];
    $cur_menu_title=$form['menu']['link']['link_title']['#default_value'];
    $form['menu']['link']['link_title']['#default_value']=yrv_t($cur_menu_title, 'item:'.$mlid.':title', $lang);
  }
}