Перейти к содержанию

Мультиязычность⚓︎

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

Один язык, отличный от английского⚓︎

Если вы используете только один язык, включите переводы и добавьте код своего языка в файл user/config/system.yaml:

languages:
  translations: true
  supported:
    - ru

или в конфигурации системы в админке.

Это гарантирует, что Grav использует правильные языковые строки во внешнем интерфейсе. Кроме того, если тема поддерживает это, она добавит код вашего языка в тег HTML.

Основы мультиязычности⚓︎

Поскольку вы уже должны быть знакомы с тем, как Grav использует файлы разметки в папках для определения архитектурной структуры, а также для установки важных опций страницы и её содержимого, мы не будем углубляться в эту механику напрямую. Тем не менее, имейте в виду, что по умолчанию Grav ищет один файл .md в папке, представляющей страницу. При включенной мультиязычной поддержке Grav будет искать соответствующий языковой файл, например, default.en.md или default.ru.md.

Конфигурация языков⚓︎

Прежде всего нужно установить некоторую базовую языковую конфигурацию в файле user/config/system.yaml.

languages:
  supported:
    - en
    - ru

Предоставляя секцию languages со списком поддерживаемых языков, вы эффективно включаете поддержку нескольких языков в Grav.

В этом примере видно, что были описаны два поддерживаемых языка (en и ru). Это позволит вам поддерживать английский и русский языки.

Если язык не запрашивается явно (через URL или код), Grav будет использовать указанный порядок языков для выбора правильного языка. Итак, в приведенном выше примере языком по умолчанию является en или английский. Если бы у вас сначала был ru, русский язык был бы языком по умолчанию.

Конечно, можно предоставить столько языков, сколько захотите, и вы даже можете использовать локальные коды типа en-GB, en-US и ru-RU. Если вы используете это именование на основе локали, вам придется заменить все короткие языковые коды на локальные версии.

Многоязычные страницы⚓︎

По умолчанию в Grav каждая страница представлена одним файлом, например, default.md. Когда вы включите поддержку нескольких языков, Grav будет искать файл с соответствующим названием. Например, поскольку английский язык является нашим языком по умолчанию, Grav сначала будет искать файл default.en.md.

Если этот файл не найден, далее будет проверяться наличие файла default.ru.md. Если этот файл не будет найден, Grav запросит файл default.md для предоставления информации для страницы.

Это поведение по умолчанию изменилось в Grav 1.7. Раньше Grav отображал несуществующую английскую страницу на французском языке, теперь все языки возвращаются только к языку по умолчанию, если не указано иное в content_fallback. Поэтому если страница не может быть найдена ни на одном из резервных языков, вместо нее отображается страница ошибки 404.

Если бы у нас были самые базовые Grav-сайты, с одним файлом 01.home/default.md, мы могли бы начать с переименования default.md в default.en.md, и его содержимое могло бы выглядеть так:

---
title: Homepage
---

This is my Grav-powered homepage!

Затем вы можете создать новую страницу, расположенную в той же папке 01.home/ под названием default.ru.md с содержимым:

---
title: Главная страница
---

Это моя домашняя страница на основе Grav!

Теперь вы определили две страницы для текущей домашней страницы на нескольких языках.

Если вы конвертируете существующий сайт для использования мультиязычности, вы можете альтернативно установить include_default_lang_file_extension: false, чтобы сохранить использование простого расширения файла .md для вашего основного языка. Читать далее...

Активный язык через URL-адрес⚓︎

Поскольку английский язык является языком по умолчанию, при запросе конкретной страницы без указания языка, Grav обратится к файлу default.en.md, но вы также могли бы явно запросить английский, указав вашему браузеру следующий адрес:

http://yoursite.com/en

Для доступа к русской версии страницы используйте:

http://yoursite.com/ru

Если вы предпочитаете не использовать языковой префикс для языка по умолчанию, установите include_default_lang: false. Читать далее...

Активный язык через браузер⚓︎

Большинство браузеров позволяют настроить, на каких языках вы предпочитаете просматривать содержимое. Grav имеет возможность прочитать значение http_accept_language и сравнить его с текущими поддерживаемыми языками сайта, и если определённый язык не был обнаружен, показать вам содержимое на предпочтительном для вас языке.

Для этого вы должны включить опцию в вашем файле user/system.yaml в секции languages::

languages:
  http_accept_language: false

Установка локали для активного языка⚓︎

Настройка булевых параметров установит метод PHP setlocale(), который контролирует такие вещи, как денежные значения, даты, сравнение строк, классификацию символов и другие специфические для локали настройки в соответствии с настройками активного языка. По умолчанию это значение установлено в false, а затем оно будет использовать системную локаль, если вы установите это значение в true, то оно переопределит локаль с текущим активным языком.

languages:
  override_locale: false

Префикс языка по умолчанию⚓︎

По умолчанию код языка по умолчанию префиксован во всех URL. Например, если у вас есть поддержка английского и русского языков (en и ru), и по умолчанию английский. Маршрут страницы может выглядеть как /en/my-page на английском языке и /ru/ma-page на русском. Однако часто предпочтительнее иметь язык по умолчанию без префикса, так что вы можете просто установить этот параметр в false и страница на английском языке будет выглядеть как /my-page.

languages:
  include_default_lang: false

Мультиязыковая маршрутизация⚓︎

Grav обычно использует имена папок для создания URL маршрута для определенной страницы. Это позволяет легко понять и реализовать архитектуру сайта в виде вложенного набора папок. Однако при создании мультиязычного сайта вы можете использовать URL-адрес, который имеет больший смысл в данном конкретном языке.

Если бы у нас была следующая структура папок:

- 01.Animals
  - 01.Mammals
  - 01.Bats
  - 02.Bears
  - 03.Foxes
  - 04.Cats
  - 02.Reptiles
  - 03.Birds
  - 04.Insets
  - 05.Aquatic

Это приведет к появлению таких URL, как http://yoursite.com/animals/mammals/bears. Это отлично подходит для английского сайта, но если вы хотите иметь русскую версию, вы предпочитаете, чтобы слаги были переведены соответствующим образом. Самый простой способ достичь этого — добавить пользовательский слаг для каждого файла страницы ru.md. Например, страница с млекопитающими может выглядеть как-то так:

---
title: Млекопитающие
slug: млекопитающие
---

Млекопитающие (класс Mammalia) - это таксон, входящий в отряд позвоночных, традиционный класс, определённый в классификации Линнея. Этот таксон считается монофилетическим...

Это в сочетании с соответствующими переопределяющими слагами в других файлах должно привести к URL http://yoursite.com/animaux/mammiferes/ours, который гораздо больше похож на русский!

Другим вариантом является использование новой поддержки маршрутов на уровне страниц и предоставление полного псевдонима маршрута для страницы.

Домашняя страница на английском языке⚓︎

Если вы переопределите маршрут/слаг для главной страницы, Grav не сможет найти главную страницу, как это определено вашей опцией home.alias в system.yaml. Он будет искать /homepage, а у вашей русской домашней страницы может быть маршрут /домашняя-страница.

Для поддержки мультиязычных домашних страниц в Grav появилась новая опция, которая может быть использована вместо home.alias и это простое home.aliases, и это может выглядеть примерно так:

home:
  aliases:
    en: /homepage
    ru: /домашняя-страница

Таким образом, Grav знает, как добраться до главной страницы, если активным языком является английский или русский.

Языковые шаблоны Twig⚓︎

По умолчанию Grav использует имя файла Markdown для определения шаблона Twig, который будет использоваться для рендеринга. Например, default.ru.md будет искать Twig-файл под названием default.html.twig в соответствующих путях к Twig-шаблону текущей темы и любых плагинов, регистрирующих пути к Twig-шаблону. При использовании нескольких языков Grav также добавляет текущий активный язык в структуру пути. Это означает, что если вам нужен специальный языковой Twig-файл, вы можете просто поместить его в папку с языками корневого уровня. Например, если ваша текущая тема использует шаблон, расположенный в templates/default.html.twig, вы можете создать папку templates/ru/ и поместить туда ваш русский специфический Twig-файл: шаблоны/ru/default.html.twig.

Другая опция, которая требует ручной настройки, это переопределение параметра template: в заголовках страниц. Например:

template: default.ru

При этом будет искаться шаблон, расположенный в файле templates/default.ru.html.twig.

Это дает вам два варианта для предоставления языковых переопределений Twig.

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

Перевод через Twig⚓︎

Самый простой способ использовать эти строки перевода в ваших Twig-шаблонах — с помощью фильтра |t. Вы также можете использовать функцию t() Twig, но, честно говоря, фильтр чище и делает то же самое:

<h1 id="site-name">{{ "SITE_NAME"|t }}</h1>
<section id="header">
    <h2>{{ "HEADER.MAIN_TEXT"|t }}</h2>
    <h3>{{ "HEADER.SUB_TEXT"|t }}</h3>
</section>

При использовании функции Twig t() решение аналогично:

<h1 id="site-name">{{ t("SITE_NAME") }}</h1>
<section id="header">
    <h2>{{ t("HEADER.MAIN_TEXT") }}</h2>
    <h3>{{ t("HEADER.SUB_TEXT") }}</h3>
</section>

Ещё один новый фильтр/функция Twig позволяет выполнять переводы из массива. Это особенно полезно, если у вас есть список значений, таких как месяцы, года или дни недели. Например, скажем, у вас есть этот перевод:

en:
  GRAV:
    MONTHS_OF_THE_YEAR:
      [
        January,
        February,
        March,
        April,
        May,
        June,
        July,
        August,
        September,
        October,
        November,
        December,
      ]

Вы можете получить подходящий перевод для месяца поста следующим образом:

{{ 'GRAV.MONTHS_OF_THE_YEAR'|ta(post.date|date('n') - 1) }}

Вы также можете использовать это в качестве функции Twig с ta().

Переводы с переменными⚓︎

Вы также можете использовать переменные в ваших Twig-переводах, используя синтаксис PHP-функции sprintf:

SIMPLE_TEXT: There are %d monkeys in the %s

А затем вы можете заполнить эти переменные с помощью Twig:

{{ "SIMPLE_TEXT"|t(12, "Лондонском зоопарке") }}

в результате получается перевод:

В Лондонском зоопарке живут 12 обезьян

Комплексные переводы⚓︎

Иногда требуется выполнять сложные переводы с заменой на определённые языки. Вы можете использовать всю мощь метода translate() с помощью фильтра/функции tl. Например:

{{ ["SIMPLE_TEXT", 12, 'Лондонском зоопарке']|tl(['ru']) }}

Переведет строку SIMPLE_TEXT и заменит плейсхолдеры на 12 и Лондонском зоопарке соответственно. Также есть массив, переданный с переводами языков, чтобы попробовать в порядке первого поиска-первого использования. Результат будет выведен на русский язык:

В Лондонском зоопарке живут 12 обезьян

Переводы PHP⚓︎

Также как и Twig-фильтр и функции, вы можете использовать тот же подход в вашем Grav-плагине:

$translation = $this->grav['language']->translate(['HEADER.MAIN_TEXT']);

Вы также можете указать язык:

$translation = $this->grav['language']->translate(['HEADER.MAIN_TEXT'], 'ru');

Для перевода определенного элемента в использовании массива:

$translation = $this->grav['language']->translateArray('GRAV.MONTHS_OF_THE_YEAR', 3);

Перевод плагинов и тем⚓︎

Вы также можете предоставить свои собственные переводы в плагинах и темах. Это делается путем создания файла languages.yaml в корне вашего плагина или темы (например. /user/plugins/error/languages.yaml, или user/themes/antimatter/languages.yaml) с перечислением всех поддерживаемыех языков:

en:
  PLUGIN_ERROR:
    TITLE: Error Plugin
    DESCRIPTION: The error plugin provides a simple mechanism for handling error pages within Grav.
ru:
  PLUGIN_ERROR:
    TITLE: Плагин ошибок
    DESCRIPTION: Плагин ошибок предоставляет простой механизм для обработки страниц с ошибками в Grav.

Условием для плагинов является использование PLUGIN_PLUGINNAME.* в качестве префикса для всех строк языка, чтобы избежать конфликтов имен. Темы с меньшей вероятностью приведут к конфликтам языковых строк, но хорошей идеей является префикс строк, добавляемых в темы с помощью THEME_THEMENAME.*.

Переопределения перевода⚓︎

Если вы хотите переопределить определённый перевод, просто поместите измененную пару ключ/значение в соответствующий языковой файл в вашей папке user/languages/. Например, файл под названием user/languages/en.yaml может содержать:

PLUGIN_ERROR:
  TITLE: My Error Plugin

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

Расширенные настройки⚓︎

Обработка языков на основе окружения⚓︎

Вы можете воспользоваться конфигурацией окружения Grav для автоматического перенаправления пользователей на правильную версию вашего сайта на основе URL-адреса. Например, если у вас есть URL типа http://ruench.mysite.com, который является псевдонимом для вашего стандартного http://www.mysite.com, вы можете настроить конфигурацию среды:

/user/ruench.mysite.com/config/system.yaml

languages:
  supported:
    - ru
    - en

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

Языковые маршруты псевдонимов⚓︎

Поскольку каждая страница может иметь свой собственный маршрут, будет сложно переключаться между различными языковыми версиями одной и той же страницы. Однако у объекта Page появился новый метод (.rawRoute()), который получит один и тот же необработанный маршрут для любого перевода одной страницы на другой язык. Всё, что вам нужно будет сделать, это поместить код языка впереди, чтобы получить правильный маршрут к определенной языковой версии страницы.

Например, скажем, вы находитесь на странице на английском языке с пользовательским маршрутом:

/my-custom-english-page

Локализованная страница имеет пользовательский маршрут:

/моя-пользовательская-страница

Вы можете получить необработанную страницу на английском языке, и это может быть:

/blog/custom/my-page

Затем просто добавьте нужный язык, и это будет ваш новый URL:

/ru/blog/custom/my-page

Это позволит получить ту же самую страницу, что и /моя-пользовательская-страница.

Поддержка перевода⚓︎

Grav предоставляет простой, но мощный механизм для предоставления переводов в Twig, а также через PHP для использования в темах и плагинах. Это включено по умолчанию, и будет использовать язык en, если не определен ни один другой язык. Для ручного включения или выключения переводов в вашем system.yaml есть параметр:

languages:
  translations: true

В переводах используется тот же список языков, который определен параметром languages: supported: в вашем system.yaml.

Система перевода работает аналогично конфигурации Grav, и есть несколько мест и способов предоставления переводов.

Первое место, где Grav ищет файлы перевода, находится в папке system/languages. Ожидается, что файлы будут созданы в формате: en.yaml, ru.yaml и т. д. Каждый файл yaml должен содержать массив или вложенные массивы пар ключ/значение:

SITE_NAME: My Blog Site
HEADER:
  MAIN_TEXT: Welcome to my new blog site
  SUB_TEXT: Check back daily for the latest news

Для удобства идентификации Grav предпочитает использовать строки на языке с заглавными буквами, поскольку это помогает определить непереведенные строки, а также делает их более понятными при использовании в шаблонах Twig.

Grav имеет возможность вернуться назад через поддерживаемые языки, чтобы найти перевод, если один для активного языка не найден. Это включено по умолчанию, но может быть отключено с помощью опции translations_fallback:

languages:
  translations_fallback: true

Помогите Grav охватить более широкое сообщество пользователей, предоставляя переводы на вашем языке. Мы используем платформу для переводов Crowdin для облегчения переводов ядра Grav и плагина админки Grav. Зарегистрируйтесь и начните переводить сегодня же!

Активный язык в сессии⚓︎

Если вы хотите запомнить активный язык независимо от URL, вы можете активировать сессионное хранение активного языка. Чтобы это произошло, вы должны убедиться, что включена соответствующая опция в system.yaml. Затем необходимо включить настройку языка:

languages:
  session_store_active: true

В этом случае активный язык будет сохранен в сессии.

Переключатель языков⚓︎

Вы можете загрузить простой плагин переключения языков через плагин админки или через GPM с помощью:

bin/gpm install langswitcher

Документация по конфигурации и использованию находится на GitHub.

Настройка с языковыми доменами⚓︎

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

Убедитесь, что параметр

pages.redirect_default_route: true

в вашем system.yaml имеет значение true.

Добавьте следующее в ваш .htaccess файл и измените языковые слаги и доменные имена в соответствии со своими нуждами:

# http://www.cheat-sheets.org/saved-copy/mod_rewrite_cheat_sheet.pdf
# http://www.workingwith.me.uk/articles/scripting/mod_rewrite

# handle top level e.g. http://grav-site.com/ru
RewriteRule ^en/?$ "http://grav-site.com" [R=302,L]
RewriteRule ^ru/?$ "http://grav-site.ru" [R=302,L]

# handle sub pages, exclude admin path
RewriteCond %{REQUEST_URI} !(admin) [NC]
RewriteRule ^en/(.*)$ "http://grav-site.com/$1" [R=302,L]
RewriteCond %{REQUEST_URI} !(admin) [NC]
RewriteRule ^ru/(.*)$ "http://grav-site.ru/$1" [R=302,L]

Если вы знаете, как упростить правила переписывания, пожалуйста, отредактируйте эту страницу на GitHub, нажав на ссылку Редактировать в верхней части страницы.

Вот упрощённая версия набора правил:

# http://www.cheat-sheets.org/saved-copy/mod_rewrite_cheat_sheet.pdf
# http://www.workingwith.me.uk/articles/scripting/mod_rewrite

# Redirect top-level URLs
RewriteRule ^en/?$ "http://grav-site.com" [R=302,L]
RewriteRule ^ru/?$ "http://grav-site.de" [R=302,L]

# Redirect sub-pages, excluding the admin path
RewriteCond %{REQUEST_URI} !^/admin [NC]
RewriteRule ^(en|ru)/(.*)$ "http://grav-site.$1/$2" [R=302,L]

Эта упрощённая версия объединяет правила рерайта для перенаправления подстраниц для en и ru в одно правило с помощью группировки. Кроме того, он объединяет RewriteCond для пути администратора, чтобы уменьшить дублирование.

Убедитесь, что эти правила добавлены до правил по умолчанию, которые поставляются с Grav CMS.

Языковая логика в шаблонах Twig⚓︎

Часто возникает необходимость доступа к состоянию и логике языка из шаблонов Twig. Например, если Вам необходимо получить доступ к определённому файлу изображения, который отличается для определённого языка и имеет различные имена (myimage.en.jpg и myimage.ru.jpg).

Для отображения правильной версии изображения необходимо знать текущий активный язык. Это возможно в Grav путем доступа к объекту Language через объект Grav и вызова соответствующего метода. В приведенном выше примере это может быть достигнуто с помощью следующего кода Twig:

{{ page.media.images['myimage.'~grav.language.getActive~'.jpg'].html }}

Вызов getActive в Twig эффективно вызывает Language->getActive() для возврата текущего активного кода языка. Несколько полезных языковых методов включают в себя:

  • getLanguages() - Возвращает массив всех поддерживаемых языков
  • getLanguage() - Возвращает текущий активный, в противном случае возвращает язык по умолчанию
  • getActive() - Возвращает текущий активный язык
  • getDefault() - Возвращает язык по умолчанию (первый)

Полный список доступных методов можно посмотреть в файле \Grav\Common\Language\Language.php.