Дисклеймер — способов сделать несколько языковых версий на 1С-Битрикс в интернете очень много! Я взял тот, который подошел мне по возможностям и временным затратам. В то же время, я не нашел ни одного способа, даже в документации самого битрикса, где бы в одном месте давалась четкая последовательность всех действий и описание возможных ошибок. Данную статью следует рассматривать как справочный материал по одному из типов решений создания многоязычности на 1C-BITRIX. Поехали!
Примерный порядок создания второй и последующих языковой версии сайта
- Создаем в административном интерфейсе новый сайт. Выставляем в настройках нужный нам язык (допустим, английский). Каждая редакция Битрикс идет сразу с возможностью создать на одной лицензии два сайта. Нужно больше языков — докупаем новые сайты (поверьте мне, это будет дешевле, чем делать многоязычность другими способами и платить разработчику, чтоб это все поддерживать).
- Русский сайт переименовываем в «RU», английский называем «EN» — для вывода переключателя языков в шапке или подвале сайта.
- Создаем в корне сайта раздел «en», указываем адрес папки в настройках английской версии. Или можно создать поддомен en.ВАШ_САЙТ.ru и указать в настройках его.
- Определяемся с тем, какие страницы и инфоблоки нужны нам в английской версии. Может быть все, а может, и не все. Вам нужно будет создать копии всех нужных инфоблоков для каждой версии языка. Об этом подробнее в 8-м пункте.
- Переопределяем навигацию — верхнее, нижнее и другие меню — в папке «en» создаем копии файлов меню из корневого раздела и меняем все названия на английские, а к адресам ссылок добавляем «/en».
Как это сделать? В админке переходим в раздел контент — «Структура сайта» — «файлы и папки».
В корневой папке обычно лежат файлы меню. Выбираем их и копируем в папку en:
После этого открываете скопированный файл в папке en и редактируете — переводите все пункты на английский.
- Копируем в папку «en» все необходимые нам папки со разделами, страницами и инфоблоками. В них могут быть свои вложенные файлы меню, которые нужно будет тоже перевести отдельно, как в предыдущем пункте.
- Со страницами и разделами все понятно — переименовываем во всех разделах названия в файлах section.php, меняем текст в страницах.
Отдельная тема: многоязычность для инфоблоков
- Самое простое — сделать копии нужных нам инфоблоков и скопировать туда все или необходимые элементы.
- А потом перенести уже внутри новых инфоблоков.
- Поменять id инфоблоков на соответствующих страницах английского раздела. Как это сделать? Для этого вам нужно открыть каждый файл в папке en, где подключен тот или иной инфоблок и найти там код подключения инфоблока. Пример:
Дальше вам нужно найти id аналогичного инфоблока, который вы создали для английской версии. И вставить это id вместо текущего.
- Внести правки в файлы локализации (для кнопочек, метаданных и т.д.) с помощью функции
<?=GetMessage("UNIC_ID")?>
Вставляете функцию там, где выводился русский текст, придумываете в скобках уникальный идентификатор, прописываете его в файлах локализации (папка lang в шаблоне компонента) для всех версий сайта.
Если нужно сохранить один инфоблок для всех языковых версий (например, в случае большого торгового каталога, то придется создавать дополнительные свойства и поля для всей дублируемой информации (названия элементов и разделов, описания и т.д.), а потом прописывать в шаблонах условия для вывода в определенной языковой версии определенного поля.
Свойства элемента инфоблока выводятся так:
<?=$arItem["PROPERTIES"]["PROPERTY_NAME"]["VALUE"]?>
Вместо «VALUE» может быть другой метод вывода, подробнее в документации (не могу пока найти ссылку, добавлю позже))).
Если не получается узнать, какое название переменной или значение использовать, часто помогает простая команда:
<?print_r(НАЗВАНИЕ_ПЕРЕМЕННОЙ)?>
Вбиваете название нужно переменной и получаете ее полный расклад.
Дополнительные поля раздела выводятся через такой код:
<? $res=CIBlockSection::GetList(Array("SORT"=>"ASC"), Array("IBLOCK_ID"=>"ID инфоблока", "ID"=>"ID раздела"),false, Array("название дополнительного поля"));if($res=$res->GetNext()){echo $res['название дополнительного поля'];}?><?}?> // Если нам нужно вывести нефильтрованный html из дополнительного поля, то перед название поля ставим тильду: {echo $res['~название дополнительного поля'];}
Проверку языковой версии можно устроить так:
<?if (LANGUAGE_ID == 'ru') {?> это для русской версии <?} elseif (LANGUAGE_ID == 'en') {?> а это для английской <?}?>
Через эту проверку выводим нужные нам поля для каждой версии сайта.
Важный момент: в настройках инфоблока проверьте, что отмечены галочки нужных сайтов!
Естественно, код вывода инфоблока для каждой версии поправьте, указав правильный каталог SEF. Что-то типа:
"SEF_FOLDER" => "/en/catalog/"
Можно это же сделать через визуальные настройки компонента.
Еще один вариант условия, по которому можно выводить нужные поля для каждой версии сайта — по адресу текущей страницы. Если у вас вторая версия расположена в подпапке /en/, то проверяем — при нахождении внутри папки показываем одни данные, иначе — другие:
<?if(CSite::InDir('/en/') ) {?> Тут выводим, например, английский заголовок элемента <? } else { ?> Тут выводим русский <? } ?>
Можно использовать множественные условия.
Настройка шаблона сайта под разные языковые версии
Можно сделать под каждый язык свой шаблон, в котором просто все перевести. А можно использовать один шаблон, локализовав в нем все, что можно, через функцию
<?=GetMessage("UNIC_ID")?>
А остальное (всякие включаемые области и файлы) определить через проверку языковой версии. Для русской версии выводим один файл (копирайт, контакты в подвале, слоган в шапке и т.д.), для английской — другой.
Если вы используете какие-то специфические скрипты (всякие модальные окна с формами), где уже прописан русский, то проще всего сделать английскую копию скрипта и отдавать ее по условию, чем пытаться все прописать в одном файле. Для js я лично пока не знаю способов локализации.
Как вывести переключатель языков на сайте?
Вставьте в нужное место шаблона вот этот код:
<?$APPLICATION->IncludeComponent( "bitrix:main.site.selector", "", Array( "SITE_LIST" => array(), "CACHE_TYPE" => "A", "CACHE_TIME" => "3600" ), false );?>
Если вам нужно вывести вместо названий языков флаги, то скопируйте шаблон этого компонента и отредактируйте его примерно таким образом:
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?> <?foreach ($arResult["SITES"] as $key => $arSite):?> <?if ($arSite["CURRENT"] == "Y"):?> <img src="<?if(is_array($arSite['DOMAINS']) && strlen($arSite['DOMAINS'][0]) > 0 || strlen($arSite['DOMAINS']) > 0):?>//<?endif?><?=(is_array($arSite["DOMAINS"]) ? $arSite["DOMAINS"][0] : $arSite["DOMAINS"])?><?=$arSite["DIR"]?>lang_active.jpg" alt="<?=$arSite["NAME"]?>"><?else:?><a href="<?if(is_array($arSite['DOMAINS']) && strlen($arSite['DOMAINS'][0]) > 0 || strlen($arSite['DOMAINS']) > 0):?>//<?endif?><?=(is_array($arSite["DOMAINS"]) ? $arSite["DOMAINS"][0] : $arSite["DOMAINS"])?><?=$arSite["DIR"]?>" title="<?=$arSite["NAME"]?>"><img src="<?if(is_array($arSite['DOMAINS']) && strlen($arSite['DOMAINS'][0]) > 0 || strlen($arSite['DOMAINS']) > 0):?>//<?endif?><?=(is_array($arSite["DOMAINS"]) ? $arSite["DOMAINS"][0] : $arSite["DOMAINS"])?><?=$arSite["DIR"]?>lang.jpg" border="0" alt="<?=$arSite["NAME"]?>"></a> <?endif?> <?endforeach;?>
Вам понадобится положить в корень 4 картинки с флагами языков:
lang.jpg и lang_active.jpg — для русского языка в обычном и активном состоянии.
enlang.jpg и enlang_active.jpg — для английского языка в обычном и активном состоянии.
Второй вариант кода шаблона, если вам нужно, чтобы при переключении языков пользователь попадал на перевод текущей страницы. Данный код работает только, если структура обоих версий полностью одинакова:
<?foreach ($arResult["SITES"] as $key => $arSite):?> <?if ($arSite["CURRENT"] == "Y"):?> <img src="<?if(is_array($arSite['DOMAINS']) && strlen($arSite['DOMAINS'][0]) > 0 || strlen($arSite['DOMAINS']) > 0):?>//<?endif?><?=(is_array($arSite["DOMAINS"]) ? $arSite["DOMAINS"][0] : $arSite["DOMAINS"])?><?=$arSite["DIR"]?>lang_active.jpg" alt="<?=$arSite["NAME"]?>"><?else:?> <a href="<?=preg_replace('#^' . SITE_DIR . '#', $arSite["DIR"], $APPLICATION->GetCurPageParam(false, array("ELEMENT_ID")))?>" title="<?=$arSite["NAME"]?>"> <img src="<?if(is_array($arSite['DOMAINS']) && strlen($arSite['DOMAINS'][0]) > 0 || strlen($arSite['DOMAINS']) > 0):?>//<?endif?><?=(is_array($arSite["DOMAINS"]) ? $arSite["DOMAINS"][0] : $arSite["DOMAINS"])?><?=$arSite["DIR"]?>lang.jpg" border="0" alt="<?=$arSite["NAME"]?>"></a> <?endif?> <?endforeach;?>
Перевод свойств заказа в интернет-магазине Битрикс
К сожалению, Битрикс до сих пор не добавил поддержку языков в свойствах заказа. Единственное решение — кастомная доработка шаблона оформления заказа. Точнее, два возможных решения:
- Свойства создаются один раз на одном языке, а при проверке языковой версии подгружается соответствующее название свойства из перевода шаблона. Нужно будет каждое свойство прописать вручную в файлах переводов, а также добавить в шаблон проверку названий свойств и языковой версии.
- Свойства создаются отдельно для каждого языка, с нужными названиями. А при оформлении заказа список свойств проверяется и выводятся только те, которые относятся к нужному языку (то есть, в коде шаблона нужно заранее определить массивы свойств).
Первый способ — более изящный, но при условии, что в админке все заказы обрабатываются на одном языке (чаще всего так и бывает).
Кроме того, нужно будет выбранное решение (одно из двух) повторить и для доработки почтовых уведомлений и статусов в личном кабинете (если там выводятся свойства). Пробуйте, пишите в комментариях, что получилось!
Updates:
- Обновление статьи от 8 февраля 2018 г. — раскрыл некоторые сложные моменты — по навигации и инфоблокам. Пишите ваши вопросы в комментариях, отвечу всем!
- Обновление от 18 ноября 2019 г. — добавил описание переключателя языков с учетом текущей страницы сайта. Чтобы при переключении языков открывалась не главная, а текущая страница на другом языке (только при условии, что структура обоих сайтов полностью идентична). А также обновил код шаблона переключателя, чтобы сделать его протоколо-независимым)), поскольку у большинства сейчас сайты на https.
- Обновление от 25 декабря 2019 г. — добавлено еще одно условие показа данных для разных языковых версий — по адресу текущей страницы.
- Обновление от 18 октября 2020 г. — добавлена информация (пока только теоретическая), как можно решить вопрос с переводом свойств заказа.