Joomla 4 - мультиязычность

archive view archive save

joomla.jpg Создание мультиязычного сайта или блога на новой установке движка Joomla 4 состоит из нескольких этапов: установка языков; включение языковых плагинов; включение модуля переключения языков; создание материалов и их категорий, пунктов меню на каждом из установленных языков.

Например мы хотим мультиязычный блог, движок будет установлен в отдельный подкаталог /blog/ корня основного сайта, соответственно упоминая далее выражение корень блога мы подразумеваем /blog/

  1. Система - Настройки - Общие настройки
  2. Система - Установка - Языки
  3. Система - Управление - Языки контента
  4. Система - Управление - Плагины
  5. Система - Управление - Модули
  6. Мультиязычность и структура контента
    1. Контент - Материалы
    2. Контент - Категории
    3. Меню
  7. Компоненты - Теги

Система - Настройки - Общие настройки

На вкладке Сайт, в секции Параметры SEO:

  • Включить SEF - Да
    Перенаправлять URL - Да

Создаём в корне блога файл .htaccess и копируем в него содержимое из расположенного там же htaccess.txt, и добавим RewriteBase /blog/.

## These directives are only enabled if the Apache mod_rewrite module is enabled
<IfModule mod_rewrite.c>
RewriteEngine On
...
# RewriteBase /
RewriteBase /blog/
...
</IfModule>

Система - Установка - Языки

Установить нужные: Russian (ru-RU), Ukrainian (uk-UA), English (en-GB)

Система - Управление - Языки контента

Убедиться, что установленные языки имеют Состояние = Вкл, - включить, если отключено.

Система - Управление - Плагины

Включить плагины без изменения настроек по-умолчанию:

  1. Система - Подмена кода языка
    system / languagecode
    Плагин для обеспечения подмены кода языка в HTML-разметке страницы сайта для улучшения SEO. Параметры будут доступны после включения плагина.
  2. Система - Фильтр языка
    system / languagefilter
    Плагин для фильтрации контента сайта в зависимости от языка.

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

Система - Управление - Модули

Добавляем модуль Переключение языков и выбираем для него позицию для размещения.

Мультиязычность и структура контента

На предыдущих шагах базовые приготовления для создания мультиязычного блога завершены.

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

Контент - Материалы

Установлено 3 языка: Russian (ru-RU), Ukrainian (uk-UA), English (en-GB)

Чтобы мультиязычность заработала, нужно:

  1. создавать материалы (статьи/посты) для каждого языка (выбирается в настройках материала) в отдельности - 3 языка = 3 статьи;
  2. устанавливать между ними т.н. Связи на одноимённой вкладке при редактировании материала.

Алиасы одного материала на 3 языках будут иметь разные заголовки и автоматически созданные для них разные алиасы соответственно:

  • Russish post 1 (alias: russish-post-1)
  • Ukrainish post 1 (alias: ukrainish-post-1)
  • English post 1 (alias: english-post-1)

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

Зачем это делать? А делается это затем, чтобы избежать путаницы в ссылках на материал. Установив одинаковый алиас post1 для всех языковых вариантов мы получим варианты ссылок:

  • /blog/ru/post1
  • /blog/uk/post1
  • /blog/en/post1

А теперь фокус! Открываем настройки плагина Система - Фильтр языка, врубаем фичу Удалять код языка из URL и по-идее для всех 3х языковых вариантов материала должны бы получить всего одну единственную ссылку:

  • /blog/post1

вместо 3х:

  • /blog/russish-post-1
  • /blog/ukrainish-post-1
  • /blog/english-post-1

Такой подход поможет нам стабилизировать ссылку для всех языковых версий материала на одном единственном УРЛ /blog/post1, избежать ошибок 404 при отключении мультиязичности, соответственно улучшить показатели СЕО нашего будущего блога  - но, это так было бы в идеале.

Увы, данный фокус не во всех случаях работает корректно (создаёт некорректные УРЛ; выдаёт ошибку 404; ...) и вызывает активные бурления в Интернетах:

Remove URL Language Code - срабатывает только для языка по-умолчанию, согласно документации!

Chunk4x:Extensions Plugin Manager Edit System Group
...
System - Language Filter

Remove URL Language Code. Whether to remove or not the defined URL Language Code (eg. your_domain_name/en) of your Content Language that corresponds to the default site language when SEF URL is set to "Yes".

Т.е., если у нас 3 языка, то Remove URL Language Code будет срабатывать только для одного, который установлен по-умолчанию в Система - Управление - Установленные языки.

Факир был пьян и фокус не удался. - но, пусть даже с удалением только кода языка по-молчанию или вовсе без удаления кода языка из УРЛ.., схема с одинаковым алиасом материала по-любому делает ссылку на материал более запоминаемой для каждого из языков и «юзверь-фрэндли» алсо.

Контент - Категории

Любой создаваемый материал обязательно должен быть помещён в какую-то категорию.

По-умолчанию существует только одна категория - Uncategorised (алиас: uncategorised), которую можно было бы переименовать, скажем в Материалы блога (алиас: post), и все посты и их языковые варианты грузить туда.

Однако, если в будущем по каким-то причинам (например заглючил плагин Система - Фильтр языка) мы захотим отключить мультиязычность и вывести материалы категории только на одном из языков, то сделать это будет невозможно!

Поэтому, под каждый язык мы создадим отдельную категорию с добавлением суффикса языка:

  1. Uncategorised (uncategorised)
  2. Материалы блога (алиас: post-ru)
  3. Матеріали блога (алиас: post-uk)
  4. Blog post (алиас: post-en)

Если для языковых вариантов материала движок позволяет делать одинаковый алиас (post1), то для языковых вариантов категории это делать запрещается.

Не удалось сохранить элемент: Другая категория в родительской категории уже использует такой алиас.

Но, это не беда и ситуация поправима пунктами меню.

Общее меню созданное по-умолчанию трогать нельзя!

  • Заголовок *: Main Menu
  • Тип меню *: mainmenu
  • Описание: The main menu for the site

Его единственный пункт Home для всех языков изменим только в части Тип пункта меню для отображения категории Материалы блога (русишь версия):

  • Заголовок *: Home
  • Тип пункта меню *: Блог категории
  • Категория *: Материалы блога
  • Алиас: home
  • Главная страница: Да
  • Язык: Все

Main Menu - это меню с одним пунктом меню будет резервное для различных аварийных ситуаций.

Открываем Меню - Меню и создаём дополнительных 3 меню для каждого языка отдельно:

  • Главное меню RU (Тип меню *: mainmenu-ru)
  • Головне меню UK (Тип меню *: mainmenu-uk)
  • Main menu EN (Тип меню *: mainmenu-en)

В каждом из дополнительных меню создаём пункт для вывода материалов категории на соответствующем языке, но с одинаковым алиасом main:

  • Заголовок *: Материалы блога
  • Тип пункта меню *: Блог категории
  • Категория *: Материалы блога
  • Алиас: main
  • Главная страница: Да
  • Язык: <выбираем в соответствии с языком меню и категории контента>

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

  • /blog/ru/
  • /blog/uk/
  • /blog/en/

Что дальше?

Компоненты - Теги

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

По этим причинам мы не плодим дополнительную туевую хучу категорий, а воспользуемся компонентом Теги. Компонент Теги, они же Метки, входящий в стандартную установку Joomla 3 и 4 позволяет дополнительно структурировать контент.

С тегами почти всё, как и с категориями:

  1. при глючности/отключении плагинов мультиязычности вывести материалы по метке только на одном из языков будет невозможно;
  2. одинаковый алиас для языковых вариантов меток запрещается: Не удалось сохранить элемент: Другой тег уже использует такой алиас.

Поэтому, для каждой языковой версии может создаватся отдельная метка, например:

  • Справка (алиас: spravka)
  • Довідка (алиас: dovidka)
  • Help (алиас: help)

Соответственно доступ по ссылкам:

  • /blog/ru/tags/spravka
  • /blog/uk/tags/dovidka
  • /blog/en/tags/help

Что, как и с категориями, может быть сведено к одному УРЛ (алиасу: help) /blog/ru/help созданием дополнительного меню и пунктов меню:

  • Меню:
    Заголовок *: Tags menu
    Тип меню *: tagsmenu
  • Пункт меню 1:
    Заголовок *: Tags
    Алиас: tags
    Тип пункта меню *: Теги
    Язык: Все

  • Пункт меню 2:
    Заголовок *: Справка
    Алиас: help
    Тип пункта меню *: Теги - Элементы
    Язык: Russian (ru-RU)

  • Пункт меню 3:
    ...для остальных языков...

На вкладке Связи не забываем связать между собой пункты меню для тегов.

В настройках Компоненты - Теги - Настройки, вкладка Выбор тегов параметр Фильтр по языку выбираем Текущий. Этот параметр определяет на каком языке выводить список меток по ссылке меню, а не при выборе их в визуальном редакторе! При выборе тегов в визуальном редакторе они все выведутся гамузом, независимо от языка (Все, RU, UK, ..) редактируемого материала - найти метку нужного языка будет сложновато.

Разбить метки по категориям (Метки RU, Метки UK) не представляется возможным, значит при отключении мультиязычности выводя список меток мы будем видеть все их языковые варианты, что не столь критично, как если бы выводился список всех языковых версий 1000 материалов по одной назначенной для всех метке, - 1000 х 3 языка = 3000 материалов, которым назначена одна метка, материалы добавлялись вперемешку по дате и в итоге их листинг по метке будет не последовательный.., какая каша получится.

Если отключим мультиязычность и захотим оставить метки только на одном языке, то можем открыть Компоненты - Теги, в Параметры поиска - Выбор языка выбрать нужный и отключить все метки ненужного языка, но - при большом их количестве данная процедура может быть утомительной.

Приходим к выводу, что метка должна быть на латинском или ином языке, но одна для всех языков каковой она и является (для всех языков) при её создании в визуальном редакторе - это лишает геморроя при создании некоторых меток с одинаковым написанием в разных языках таких, как например: NASA (EN), НАСА (RU), НАСА (UK).

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

Создание пунка меню на всех языках для каждой метки тоже не самая лучшая идея.., но тогда модуль переключателя языков не будет работать как ожидалось, - например, меню для вывода всех меток (алиас tags) на всех языках уже создано, открыв в английском варианте метку Help по ссылке /blog/en/tags/help в модуле переключения языков для RU и UK вместо ссылки на эту же метку ссылки будут вести на список всех меток:

  • /blog/ru/tags
  • /blog/uk/tags

При этом нет значения к какому языку пренадлежит тег Help (EN, RU, UK или Все), - это досадное недоразумение можно исправить «костылём» допилив модуль mod_languages, предварительно сделав его переопределение в /templates/<MYTEMPLATE>/html/mod_languages/default.php, следующим образом:

<?php 
defined('_JEXEC') or die;
 
...
 
// Fix multilang route
// step 1: get tag alias from request
$tagAlias = '';
$parseUrl1 = parse_url($_SERVER['REQUEST_URI']);
if (preg_match('/(.*)(\/tags\/)(.*)/', $parseUrl1['path'], $matches)) {
    // $matches
    //Array
    //(
        //[0] => /blog/en/tags/help
        //[1] => /blog/en
        //[2] => /tags/
        //[3] => help
    //)
    @$tagAlias = trim($matches[3]);
}
 
?>
<div class="mod-languages">
...
<?php if (!$language->active) : ?>
    <li>
        <a <?php echo $lbl; ?> href="<?php 
        // Fix multilang route
        // step 2: fix not active $language->link
        $parseUrl2 = parse_url($language->link);
        if (!empty($tagAlias) && $parseUrl1['path'] !== $parseUrl2['path']) {
            $langLink = $language->link . '/' . $tagAlias;
        } else {
            $langLink = $language->link;
        }
        echo htmlspecialchars_decode(htmlspecialchars($langLink, ENT_QUOTES, 'UTF-8'), ENT_NOQUOTES);
        ?>">
        ...
    </li>
<?php elseif ($params->get('show_active', 1)) : ?>
...
</div>

Нет комментариев

Вы можете стать первым, кто добавит комментарий к этой записи.

Добавить комментарий

АХТУНГ! Все комменты гостей модерасятся модерастом.
  1. Мессаги исключительно рекламного содержания, либо содержащие только одни оценочные суждения типа "круто" ("отлично", "спасибо", "автор дебил" и т.п.) не публикуются;
  2. Злостным спамерам, пранкерам и прочей сетевой нечисти рекомендуем напрасно не тратить своего времени и удовлетворять свои больные фантазии на специализированных Интернет ресурсах!;
  3. Разумная обоснованная критика, замечания, дополнения приветствуются. Поля помеченные символом * обязательны к заполнению.


Защитный код
Обновить

Комментарии в блоге
Новое на форуме