Мультиязычность в Albireo CMS.
Есть несколько подходов в реализации мультиязычного сайта.
Язык посетителя
В Albireo CMS есть функция detectUserLang()
, которая анализирует $_SERVER['HTTP_ACCEPT_LANGUAGE']
и на выходе выдаёт двухсимвольный код языка (ISO 639), например «uk», «en», «fr» и т.п.
Язык сайта по умолчанию
Для правильной работы, нужно задать основной язык сайта в config.php
. Если у страницы не будет указан язык, то будет использовано это значение.
'defaultLang' => 'ru',
На основе этого поля будет сформирован тэг <html>
:
<html lang="язык">
Этот язык может быть переопределен у каждой страницы:
html[lang]: en
В конфигурации в config.php
также можно указать список языков, которые поддерживает сайт.
'langAllowed' => 'ru, uk, en',
Эти значения используются по умолчанию и позволяют ограничить язык посетителя. Если сайт работает только на одном языке, то нужно указать только его:
'langAllowed' => 'ru',
Эти данные можно переопределить на каждой странице. Они используются для формирования корректного перевода фраз и html-кода страницы.
Языковой перевод страниц
Самый простой вариант создания мультиязычных страниц — это разделения контента под каждый язык в отдельные файлы.
Например могут быть такие файлы:
about.php about@lang-uk.php about@lang-en.php
Здесь основной файл about.php
, а остальные файлы имеют тоже имя, только префикс @lang-ЯЗЫК
и будут содержать текст своего языка.
Файл about.php
будет примерно такого вида:
<?php if (!defined('BASE_DIR')) exit('No direct script access allowed'); /** title: Титул по умолчанию announce: Анонс по умолчанию # прочие поля как нужно ... # языки на которых будет работать страница lang: ru, en, uk # языковой перевод для полей # EN lang.en[title]: Титул для EN lang.en[announce]: Анонс для EN # UK lang.uk[title]: Титул для UK lang.uk[announce]: Анонс для UK **/ ?> <!-- заголовок записи, но можно перенести в контекстный файл языка --> <?= extras('info1-header.php') ?> <?php // код, подключающий языковой файл if ($fnLang = langFile()) { require $fnLang; return; } ?> Текст по умолчанию как обычно.
Таким образом в about.php
происходит диспетчеризация контекстного файла и его подключение. Если языкового файла нет, то будет выводиться текст по умолчанию.
Для того, чтобы добавить новую языковую версию, например fr
, следует добавить язык lang: ru, en, uk, fr
и создать файл about@lang-fr.php
Этот способ мультиязычности хорош тем, что текст языка хранится в отдельном файле — это позволяет легко создавать переводы, основываясь на основном тексте.
При необходимости можно вынести и текст по умолчанию в отдельный файл: about@lang-ru.php
— менять при этом файл about.php
не нужно, поскольку файл будет определён и подключен автоматически.
Контекстный файл языка будет содержать только непосредственно текст и не будет рассматриваться как страница сайта. Например about@lang-fr.php
:
<?php if (!defined('BASE_DIR')) exit('No direct script access allowed'); ?> Texte en français.
Мультиязычность в одном файле
Если текст страницы небольшой, то можно все языковые версии разместить прямо в одном файле. Он формируется точно также, только тексты выводятся по php-условиям. Вот пример файла terms.php
:
<?php if (!defined('BASE_DIR')) exit('No direct script access allowed'); /** title: Условия использования и копирайты description: Условия использования и копирайты # языки на которых будет работать страница lang: ru, en, uk # переводы полей lang.en[title]: Terms of Use and Copyright lang.uk[title]: Умови використання та копірайти lang.en[description]: Terms of Use and Copyright lang.uk[description]: Умови використання та копірайти **/ ?> <?php if (getPageData('user-lang') == 'uk') : ?> Здесь текст для UK <?php elseif (getPageData('user-lang') == 'en') : ?> Здесь текст для EN <?php else : ?> Здесь текст по умолчанию <?php endif ?>
PHP-код getPageData('user-lang')
возвращает язык посетителя, который просто сверяется. Чтобы добавить новый язык нужно добавить и новое php-условие.
Ограничение языка посетителя
Поле lang
служит для того, чтобы ограничить язык посетителя только указанными. Таким образом, если у посетителя будет стоять язык, не входящий в список lang
, то ему будет предложена страница и язык по умолчанию.
Если стоит задача самостоятельно определить язык посетителя, то можно воспользоваться функцией detectUserLang()
:
$lang = detectUserLang('ru, en, uk'); pr($lang); // отладочная функция для вывода данных
Функция будет анализировать переменную $_SERVER['HTTP_ACCEPT_LANGUAGE']
до тех пор, пока не встретит разрешенный язык. Если же среди разрешенных языков нет языка посетителя, то функция вернёт значение по умолчанию (первый язык в списке).
Это позволяет корректно находить язык посетителя, когда он задан в сложном виде, например fr-FR,fr;q=0.8,en-US;q=0.5,en;q=0.3
. Поскольку в разрешенных языках нет fr
, то функция вернёт en
(он разрешён), который указан как «дополнительный язык» посетителя.
Другие алгоритмы мультиязычного сайта см. ниже.
Перевод отдельных фраз
Для перевода отдельных фраз используется функция lang()
— она принимает фразу для перевода. Если перевода нет, то возвращается исходная фраза.
Сам перевод хранится в отдельных файлах в каталоге конфигурации langs
, где каждый язык в отдельном подкаталоге. Файлы возвращают обычный php-массив, примерно так:
// uk return [ 'Powered by Albireo CMS' => 'Працює на Albireo CMS', 'The site uses cookies' => 'Сайт використовує cookies', 'Terms of Use' => 'Умови використання', 'Sitemap' => 'Карта сайту', 'Contacts' => 'Контакти', 'Projects' => 'Проекти', 'Links' => 'Посилання', 'Categories' => 'Рубрики', 'Related Posts' => 'Схожі записи', 'Tags' => 'Мітки', 'Categories' => 'Рубрики', 'RSS comments' => 'RSS коментарі', ];
По умолчанию используется английский язык, поэтому есть отдельно русский и украинские переводы. Таким способом можно переводить тексты в разных частях сайта: шапки, подвалы, меню, виджеты и т.п.
Перевод работает как с фразами, так и их «кодом». Например можно указать lang('content-about')
, а в языковых файлах:
'content-about' => 'Працює на Albireo CMS',
Сами языковые файлы произвольны, поэтому можно выделить свои переводы отдельным файлом — они все подключатся скопом.
Динамическая замена языковых полей
При желании можно указать языковые фразы каждого языка в полях страницы. Для этого используется поле такого формата: lang.ЯЗЫК[ПОЛЕ]
. Например у нас есть страница условия использования сайта, которая меняет свой title
в зависимости от языка пользователя.
# фраза для языка по умолчанию title: Условия использования и копирайты # языковой перевод для каждого языка lang.en[title]: Terms of Use and Copyright lang.uk[title]: Умови використання та копірайти
Albireo CMS при формировании данных страницы, автоматически заменит поле title
на то, которое соответствует языку посетителя. У конструкции lang.XX[YY]
можно указывать произвольные поля и значения.
Такой вариант языкового перевода хорош тем, что нет необходимости менять файл словаря.
Использование PHP
Поскольку в полях страницы можно использовать PHP-код, то изменить поле на нужный язык можно и с помощью функции lang()
:
title: <?= lang('Home') ?>
Таким образом система выполнит перевод слова для этого поля. Этот код будет эквивалентен (пример для украинского):
title: Головна
Использование PHP в полях позволяет создавать переводы для фраз, которые могут потом использоваться в теле страницы. Демо-пример возможностей системы:
# произвольное поле # по умолчанию my: Солнце # языковые версии lang.uk[my]: Сонце lang.en[my]: Sun
Получение значения поля происходит с помощью функции getPageData('поле')
:
pr(getPageData('my')); // Солнце или Сонце или Sun в зависимости от языка посетителя
При необходимости получить исходное значение поля my
(если была замена) можно с помощью префикса _old.
:
pr(getPageData('_old.my'));
Отладка языкового перевода
Если в конфигурации сайта включена отладка сайта (автоматом это сделано для LOCALHOST), то в случае, если переводимая фраза не найдена для текущего языка (кроме EN), внизу сайта выводится отладочная панель, которая выводит массив отсутствующих слов и его язык. Таким образом в процессе написания кода, можно сразу контролировать языковые словари.
Самостоятельные языковые страницы
В Albireo CMS можно создавать раздельные копии страниц, которые будут доступны по разным адресам. Например:
ru/ page1.php -> сайт/ru/page1 page2.php -> сайт/ru/page2 page3.php -> сайт/ru/page3 en/ page1.php -> сайт/en/page1 page2.php -> сайт/en/page2 page3.php -> сайт/en/page3 uk/ page1.php -> сайт/uk/page1 page2.php -> сайт/uk/page2 page3.php -> сайт/uk/page3
Здесь имена файлов и каталогов произвольны. Каждый файл представляет собой полностью самостоятельную страницу и в задачу автора блога будет входить определить как именно он будет предлагать посетителям языковые страницы. Часто это выполняется с помощью php-кода, который будет определять язык посетителя и предлагать ему подходящую языковую версию страницы (с помощью ссылки или автоматического редиректа).
Для того, чтобы поисковики корректно смогли определить все языковые версии, следует в полях страницы их указать:
head-lang[uk]: [SITE_URL]uk/page1 head-lang[en]: [SITE_URL]en/page1 head-lang[ru]: [SITE_URL]ru/page1
Это будет эквивалентно такому коду:
<link rel="alternate" hreflang="uk" href="https://site.com/uk/page1"> <link rel="alternate" hreflang="en" href="https://site.com/en/page1"> <link rel="alternate" hreflang="ru" href="https://site.com/ru/page1">
Автоматический редирект может быть выполнен примерно так:
<?php if (getPageData('user-lang') == 'uk') header('Location: АДРЕС для UK'); elseif (getPageData('user-lang') == 'en') header('Location: АДРЕС для EN'); ?>
Отдельные сайты для языковых версий
Поскольку Albireo CMS поддерживает мультисайтинг, то можно сделать отдельную копию website
под каждый язык. В этом случае сайты будут полностью самостоятельные, хотя и использовать общее ядро системы.
Преимущество такого подхода в том, что эти сайты будут содержать полностью изолированный контент, изображения, настройки и т.п.