Во время работы над modx-test.com (который потом вырос в https://modhost.pro) придумал и реализовал прикольную мультиязычность.
Никаких копирований файлов, поддоменов и прочих заморочек. 1 простой плагин, который делает всю работу.
Нам нужно 2 контекста, по умолчанию в основном контексте ставим русский язык. В настройках контекстов указаны следующие параметры:web- cultureKey - ru
en- cultureKey - en
В системных настройках отключаем проверку дупликатов url во всех контекстах. Url соответствующих страниц должны быть одинаковыми - так гораздо проще. Иначе, надо будет наворачивать сниппет, выдающий ссылку на другую языковую версию.
А вот и сам плагин, реагирует на событие OnHandleRequest:
<?php
if ($modx->event->name != "OnHandleRequest" || $modx->context->key == 'mgr') {return;}
if (isset($_GET['lang']) && $_GET['lang'] != $_SESSION['lang']) {
if ($_GET['lang'] == 'en') {
$_SESSION['lang'] = 'en';
}
else {
$_SESSION['lang'] = 'ru';
}
}
if ($_SESSION['lang'] == 'en') {
$modx->switchContext('en');
}
То есть, при указании параметра ?lang=en или ?lang=ru любой ссылке - контекст сайта переключается, а вместе с ним и язык - и это запоминается в сессию, то есть ссылка больше не нужна.
Прощай геморрой с настройками!
Бонус в виде сниппета для вывода ссылки на переключение:
<?php
$link = $modx->makeUrl($modx->resource->id, '', '', 'full');
if ($modx->getOption('cultureKey') == 'en') {
return "<a href=\"$link?lang=ru\">Русский</a>";
}
else {
return "<a href=\"$link?lang=en\">English</a>";
}
Поисковики такой сайт индексируют нормально - ведь на каждой странице есть ссылка на другую языковую версию, и урл отличается. То есть в индексе страницы с разным ?lang=(en|ru) и с разным содержимым.
Всем доброго дня!
Кто подскажет, где посмотреть все возможные значения (двусимвольные сокращения языка) для cultureKey.
В настоящий момент делаю сайт с мультиязычностю Finnish, English, Russian, French, Spanish, Arabic, соответственно, двусимвольные сокращения fi,web,ru,fr,es,ar как для cultureKey так и для настроек плагина babel. Планируется добавления языков которые в babel отсутствуют, и что бы их добавить туда нужно знать общепринятое сокращение. (например один из таких языков иврит)
Добрый день.
Делаю всё как тут написано. Отображается ссылочка на английскую версию сайта, при нажатии на неё в адрес, добавляется ?lang=en и ничего не происходит. Подскажите в чем проблема, пожалуйста. Я так понимаю, что просто не переключаются контексты, правильно?
Всем доброго времени суток!
В данной реализации, на нерусской версии сайта даты будут выводиться на русском языке. Поэтому в последнее условие необходимо добавить принудительную установку локали:
В зависимости от языка или кодировки строчку setlocale(LC_TIME, 'en_US.UTF8'); надо изменить. Точно так же можно написать и для нескольких языков.
Да, верно.
Еще можно выводить даты через сниппет dateAgo - он берёт названия месяцев из лексикона.
Здравствуйте! Подскажите пожалуйста, как переделать ваше решение мультиязычности без контекстов? Т.е.: Создаются ТВ для каждого языка, и у каждого документа прописываются названия, контент и тд на каждом языке. Пробовала ваш вариант плагина, только вместо $modx->switchContext('en'); пробовала $modx->setPlaceholder('cultureKey','en'); и $modx->setOption('cultureKey', 'en'); не помогло.
Я даже просто пробовала показать $_SESSION['lang'], переходя по ссылкам http://shop.test1.ru/?lang=en и http://shop.test1.ru/?lang=ru - ничего не выводит, т.е. даже сессию не устанавливает.
Включила кеширование настроек контекстов (до этого было отключено), сессия устанавливается. Теперь пробую выводить нужные ТВ в зависимости от сессии, работает через раз - при каждом обновлении страницы, меняются с русских на англ. и наоборот) Видимо дело в кешировании! Подскажите, кто сталкивался, как с этим бороться? Спасибо.
Нет) Простите за флуд, Я так понимаю сессия устанавливается при первом заходе, и уже выводятся нужные ТВ при следующем обновлении страницы. Наверное я туплю, пошла разбираться)
Все получилось, всем спасибо!)
На здоровье! =)
Привет. Bond Nataly, как я понял, Вы пытались создать отдельные TV под каждый язык для каждого ресурса, и в итоге все получилось? Буду благодарен если у Вас будет возможность расписать решение поподробнее.
Ох, это ж было аж год назад, почти ничего не помню уже) Ну приблизительно могу описать так: При переключении языка у меня в сессию записывался язык (ru,en,ua). И потом исходя из этого, у меня подставлялись нужные TV, которые были названы с префиксом своего языка. Например, en_pagetitle, ua_pagetitle и тд. И сниппет для вызова нужной тв, например так pagetitle вызывала:
И сам сниппет cK:
Спасибо. Уже ближе к полуночи сам к такому решению пришёл, а теперь убедился в правильности хода мыслей. Данное решение позволяет избавиться от дублирования ресурсов, что в некоторых случаях (сайтах) очень даже правильно, и это мне подходит. ) Спасибо за оперативность.
Пожалуйста )
Ты однако круче чем Чак Норис. Помог человек силой мысли)) во как!!! ))
Не поминай имя Чака всуе, а то - накажет!
Спасибище огромное! Как нельзя кстати вовремя) только вот не получается сделать с тремя языками, наведите на мысль пожалуйста, в php не особо силен
Разобрался, правда незнаю насколько это правильно. Воспользовался elseif: код плагина
Все верно.
Только в последнем блоке вместо 2х if лучше тоже else if.
Точно, поторопился что-то. еще пришлось сделать небольшой сниппет для вывода своего меню в каждом контексте, чтобы не делать несколько шаблонов. Если надо кому выложу
Было бы здорово.
делаю для заказчика и важен только сайт, а не гугловская выдача, но интересно, как гугл на такие сессионные вещи реагирует, спасибо за простое и красивое решение.
Пока не было проблем.
Как думаете Василий, лучше делать копии шаблонов, например для английских ресурсов или проверку контекста/сессии для вывода соответствующих чанков/сниппетов в общих шаблонах?
Проверка удобнее, а шаблоны быстрее.
Ну а выбирает каждый сам, зависит от размера сайта и личных предпочтений.
А зачем делать копии чанков или шаблонов? Для каждой фразы создается свой ключ в настройках контекста, а в шаблоне подставляется [[++ключ_фразы]]. Параметры в сниппеты тоже можно передавать таким образом, например [[getresources? &parents=
\[\[++ID\_родителя\_для\_текущего\_языка\]\]
]]. После завершения основной версии, делается копия контекста и в настройках копии просто переводим фразы на соответствующий язык. По такой схеме, пока не приходилось использовать копии чанков и шаблонов.Зачем использовать системные параметры, если есть лексиконы?
Тег [[%name]] специально для этого. Вот дока.
Спасибо, Василий, так еще лучше, почему-то не обращал раньше внимания на управление словарями.
Самое удобное решение из тех, что встречал, но не без недостатка - url каждой страницы на разных языках должны быть одинаковыми, столкнулся с необходимостью вручную устанавливать урлы во всех контекстах для большого количества ресурсов, что очень неудобно.
Поправил немного сниппет для вывода ссылки на переключение языка:
Теперь нет необходимости указания одинаковых url для соответствующих страниц. Естественно, все соответствующие страницы должны быть связаны через Babel.
Здравствуйте. Подскажите в чем может быть проблема (все делал по пунктам). При переходе на английскую версию сайт выдает ошибку
503 Error Page not found The page you requested was not found. Спасибо.
Та же ересь. Никак не найду почему. :(
а страничка в английском контексте у тебя стем же урл что и в русском? должны быть одинаковые
Абсолютно идентичные и урл и алиасы - на болванке сайта тестирую, по странице в каждом контексте. Более того - такую же ошибку выдает в недефолтном (en) контексте при простом просмотре страницы. Предположений много, но дело, кажется, в каких-то настройках - сам скрипт потестить пока не выходит. Есть идеи?
Повторил по инструкции на тестовом сайте: заработало! Причин отказа так и не понял. Предполагаемое решение см. чуть ниже.
Решение: Предположительно, надо быть внимательным к адресу контекста в плагине:
$modx->switchContext('адрес_контекста');
Результат: http://s2955.modx-test.com
Здравствуйте! А как можно при входе на сайт автоматический выбирать язык в зависимости от страны?
http://workinweb.com.ua/content/php-opredelenie-yazyka-brauzera-i-perenapravlenie-na-relevantnuyu-yazykovuyu-stranicu
Узнаешь язык клиента и инициализируешь соответсвующий контекст в сесси
Да, я видел эту страницу. Просто думал по ip как-то надежнее, а тут http://mitasych.com/kak-opredelit-geograficheskoe-polozhenie-po-ip-i-svyazat-ego-s-google-maps не нашел где качать файлы geoip.inc, geoipcity.inc, geoipregionvars.php.
а если человек с ноутом заходит на твой сайт из макдональда в Англии и хочет русский а получает en
То он переключит язык на русский, и выбранный язык хранится в сессии. Какой вариант лучше - однозначного мнения нет, как я понял :)
ну вот видишь сам ответ дал)
Подскажите пожалуйста, в чём может быть проблема!
Всё прекрасно работало, но в один момент ошибка стала вылетать 404ая, копал и накопал вот что когда отключаешь событие OnHandleRequest в плагине:
то сайт открывается, а язык не переключается..
Помогите пожалуйста, 2 дня уже убил, кэш чистил, переустанавливал систему, ничего не помогает :(
Фазы луны, вероятно. Тоже лечил, но была 503-я: здесьУ меня все работает с настройками, приведенными в топике. Проверьте имена контекстов в коде (второй контекст точно зовется en?) и их настройки.
Всё работало, я только установил Quip и что то пошло не так, естественно я удалил Quip... Точно фаза луны, блин..
Удалил [[!Loginza?action=
getProfile
]] всё заработало, фаза луны пришла в норму, что думаете по этому поводу?Увы, у меня нет версий. Я не очень в php шарю. :( Может Логинза что-то в запросе свое дописывала, что скрипт мультиязычности понять не мог?
Василий, если есть время, кивни правильно или нет. Воюю с контекстами. Есть домен site.ru и поддомен sub.site.ru. Делаю согласно официальному руководству и твоим комментам на habre Как я воевал с контекстами. Не работает через http_host, хоть ты тресни (в контекстах прописал все настройки согласно твоей картинке из коммента). Вот плагин на OnHandleRequest
Если заменить $modx->getOption('http_host') на $_SERVER['HTTP_HOST'], то все работает, но хотелось бы узнать мнение грамотных специалистов - правильно так?
Если работает - это правильно.
Спасибо. Успокоил.
При переключении языков Wayfinderы частично отключаются т.е. главное меню работает а доп.меню слева не работает, а в английской версии и главное пропадает, после обновления страницы всё появляется
З.Ы точно так же форма ввода пароля не отображается, только после повторного обновления страницы. Пакет Login. Помогите пожалуйста кто чем может?!
С таким не сталкивался. Все работало как надо.
Я делал для каждого языка категорию и в нее копировал чанки снипеты и шаблоны отдельно копия каждого элемента для каждого языка нудно зато потом путаницы нет что где менять и скешированием тоже нету проблемм.
Заметил что контекст (а именно [[*context_key]]) срабатывает правильно, а вот айди из словаря подставляет от другого контекста. Что за магия, не могу понять
С cultureKey проблемы, хотя в контекстах настроено правильно
Help!!!
Заманался, cultureKey путается при переключении на другие языки.. короче спасибо за помощь
На здоровье!
Установил чистый MODx 2.2.8 сделал все по пунктам, не работает ни русская версия ни английская (((( Че за БРЕД ?!?!?!
Все, разобрался. Оказывается в этой части
там где
надо вместо "en" явно указать имя своего контекста для англоязычных материалов.
На демосайте в Firefox 22 под Mac OS после достаточно быстрой смены языков 3-4 раза на странице каталога(да и вообще любой кроме товара) туда-сюда возникает такое при открытии конкретного товара
остаются часть чанков случайным образом от прошлого языка. решается сменой языка туда-обратно на странице товара. на скрине, например, от текущего русского есть только цвет. наверное, такое в реальности не произойдет, но все же баг
На этом сайте вообще один контекст и все тексты переключаются через лексиконы, динамически. То есть, это одна и таже страница, и некоторые плейсхолдеры на ней кэшируются.
Если же делать 2 контекста, как расписано в заметке, то такой проблемы быть не может.
Я тоже собирался через лексиконы делать, потому что получается наполнение на всех языках одно, нужно только подписывать в зависимости от языка. Судя по всему, возникает проблема только при быстром переключении подряд, если же это рабочий режим и все делается достаточно медленно, то все ок.
Я вот делал мультиязычность вида your.domain/en/ и т.п. скок душе угодно по этой инструкции.
Правда никаких сессий там не используют и соответственно $_GET параметров.
Я уже которые сутки пытаюсь догуглиться до истины. Для этого плагина нужен же этот сниппет? На http://minishop2.com/ Я его не видел, там так же не переводятся товары. Можно настроить это все так чтобы весь сайт был полностью на англ \ рус языке? Я так понял babel создает во втором контексте копию документа, который меняется контентом, шаблонами, и на сайте потом подменяется исходный ресурс на копию. Верно? А как же cart.html, он на сайте должен же быть один.
На minishop2.com это сделано довольно коряво.
Нормальный мультиязычный магазин лично я ни разу не делал, но со всех сторон кажется, что дублировать товары для перевода на другой язык - плохо.
Подскажите, кто в курсе. Я всё насчёт поисковиков и индексации. Может вместо использования clean-param, который прикажет игнорировать все ?lang= лучше использовать Disallow /*?lang=ru? Иначе как поисковики попадут на страницы переводов, если будут шарить по страницам без параметров? С другой стороны, тогда останутся дубли у иностранных страниц...
Robots.txt вам в помощь.
Эта заметка устарела, лучше делать вот так - http://bezumkin.ru/sections/tips\_and\_tricks/2439/
О, спасибо. Может стоит это указать в начале заметки? А то в гугле эту первым делом выдаёт.
Лучше я просто редирект сделаю.
http://bezumkin.ru/sections/tips\_and\_tricks/2439/