Локализация темы
lang. CMS загружает общий файл переводов и дополнительный файл, соответствующий текущему шаблону.Для получения строк в шаблонах используется статический класс SiteLang.
Структура папок
Языковые файлы хранятся внутри активной темы:
example/
lang/
ru/
common.php
index.php
404.php
page/
default.php
post/
news.php
en/
common.php
index.php
404.php
page/
default.php
post/
news.phpНазвание языковой папки должно совпадать с URL-префиксом языка.
Например:
prefix: ru -> lang/ru
prefix: en -> lang/enКод языка и его URL-префикс могут отличаться. Для названия папки используется именно префикс.
Префикс записывается строчными латинскими буквами и может содержать цифры или -.
Общие переводы
Файл common.php загружается на всех обычных страницах сайта:
lang/ru/common.phpПример:
<?php
return [
'main' => 'Главная',
'contacts' => 'Контакты',
'copyright' => 'Все права защищены.',
];Получение значения:
$title = SiteLang::get('main');Общие переводы подходят для:
- header и footer
- главного меню
- общих кнопок
- контактных данных
- повторяющихся подписей
- сообщений, используемых в разных шаблонах
Вложенные ключи
Переводы можно объединять во вложенные массивы:
<?php
return [
'navigation' => [
'main' => 'Главная',
'catalog' => 'Каталог',
'contacts' => 'Контакты',
],
'buttons' => [
'send' => 'Отправить',
'read-more' => 'Читать далее',
],
];Путь к значению записывается через точку:
$catalog = SiteLang::get('navigation.catalog');
$send = SiteLang::get('buttons.send');SiteLang::get() возвращает только скалярное значение. Если путь указывает на массив, используется резервное значение.
Контекстные переводы
Кроме common.php, CMS загружает файл текущего контекста.
| Контекст | Файл |
|---|---|
| Главная страница | lang/{prefix}/index.php |
| Страница ошибки | lang/{prefix}/404.php |
| Шаблон страницы | lang/{prefix}/page/{template}.php |
| Шаблон записи | lang/{prefix}/post/{template}.php |
Контекстный файл дополняет общие переводы и может переопределять их.
Главная страница
Для главной страницы используется:
lang/ru/index.phpПример:
<?php
return [
'hero' => [
'title' => 'Добро пожаловать',
'description' => 'Описание главной страницы.',
],
];Использование в index.php темы:
<section class="hero">
<h1><?php echo SiteLang::html('hero.title'); ?></h1>
<p><?php echo SiteLang::html('hero.description'); ?></p>
</section>Шаблон страницы
Для файла шаблона:
template/page/default.phpиспользуется файл переводов:
lang/ru/page/default.phpПример:
<?php
return [
'title' => 'О странице',
'back' => 'Вернуться назад',
];Использование в шаблоне:
<h1><?php echo SiteLang::html('title'); ?></h1>
<a href="<?php echo CurrentLanguage::url('/'); ?>">
<?php echo SiteLang::html('back'); ?>
</a>Имя языкового файла определяется именем шаблона, а не URL страницы.
Несколько страниц с шаблоном default используют один контекстный файл переводов.
Шаблон записи
Для файла:
template/post/news.phpиспользуется:
lang/ru/post/news.phpПример:
<?php
return [
'published' => 'Опубликовано',
'back-to-list' => 'Вернуться к новостям',
];Использование:
<p><?php echo SiteLang::html('published'); ?></p>
<a href="<?php echo CurrentLanguage::url('/news'); ?>">
<?php echo SiteLang::html('back-to-list'); ?>
</a>Страница ошибки
Переводы страницы ошибки хранятся в:
lang/ru/404.phpПример:
<?php
return [
'title' => 'Страница не найдена',
'description' => 'Проверьте адрес или вернитесь на главную страницу.',
'home' => 'На главную',
];Использование в template/404.php:
<h1><?php echo SiteLang::html('title'); ?></h1>
<p><?php echo SiteLang::html('description'); ?></p>
<a href="<?php echo CurrentLanguage::url('/'); ?>">
<?php echo SiteLang::html('home'); ?>
</a>Переводы компонентов
Переводы повторно используемого компонента можно хранить отдельно от общих и контекстных переводов.
Например, создайте файл lang/ru/components/product-card.php:
<?php
return [
'product-card' => [
'buy' => 'Купить',
],
];Для других языков создайте файлы с такой же структурой в соответствующих языковых папках. Например, в lang/en/components/product-card.php значением ключа buy будет Buy.
В компоненте includes/product-card.php подключите файл до первого обращения к его переводам:
<?php SiteLang::load('components', 'product-card.php'); ?>
<button type="button"><?php echo SiteLang::html('product-card.buy'); ?></button>В load() передаётся путь внутри lang/{prefix} без языкового префикса. Язык выбирается автоматически.
При вызове сначала загружается файл языка по умолчанию, затем текущего языка. Отсутствующие файлы пропускаются.
Дополнительные переводы дополняют уже загруженные значения и переопределяют совпадающие ключи. Отдельная группа product-card отделяет переводы компонента от общих ключей.
Один и тот же путь загружается только один раз за запрос. Поэтому вызов load() можно размещать внутри компонента, даже если компонент выводится несколько раз.
Переводы в JavaScript
Переводы из PHP-файлов темы можно использовать и в JavaScript. Для этого отметьте нужные ключи через SiteLang::useInJS().
Для компонента из предыдущего примера:
<?php
SiteLang::load('components', 'product-card.php');
SiteLang::useInJS('product-card.buy');
?>load() загружает переводы компонента, а useInJS() выбирает значения для передачи в браузер.
Выполните эти вызовы до существующего вызова CurrentTheme::getJS(). CMS передаст выбранные переводы и подключит необходимые средства автоматически. Дополнительные теги <script> не нужны.
В JavaScript-модуле темы, например assets/js/modules/script.js, получите строку:
const buyText = window.wsSiteLang.get('product-card.buy', 'Купить');Для русского языка результатом будет Купить, для английского при наличии соответствующего перевода — Buy.
Второй аргумент является резервным текстом. Он используется, если ключ отсутствует, не передан в JavaScript или указывает на группу вместо отдельной строки.
Чтобы передать всю группу компонента, используйте SiteLang::useInJS('product-card'). В браузер попадут только выбранные ключи и группы, а не весь словарь темы.
Полученная строка не содержит HTML-экранирования. При выводе обычного текста в элемент используйте textContent.
Язык по умолчанию
Переводы языка по умолчанию используются как основа.
Допустим, русский язык является языком по умолчанию:
<?php
return [
'main' => 'Главная',
'contacts' => 'Контакты',
'catalog' => 'Каталог',
];А английский файл содержит только часть переводов:
<?php
return [
'main' => 'Home',
'catalog' => 'Catalog',
];Для английской версии сайта:
mainвернётHomecatalogвернётCatalogcontactsвернётКонтакты
Отсутствующий перевод сохраняется из языка по умолчанию.
Порядок объединения
При автоматической загрузке файлы объединяются в следующем порядке:
common.phpязыка по умолчанию.common.phpтекущего языка.- Контекстный файл языка по умолчанию.
- Контекстный файл текущего языка.
Каждый следующий файл дополняет предыдущие данные и переопределяет совпадающие ключи.
Вложенные массивы объединяются рекурсивно.
Это позволяет:
- хранить основной набор переводов в языке по умолчанию
- переводить только необходимые значения
- задавать общие строки в
common.php - переопределять строки для конкретного шаблона
Получение строки
get(string $path, string $default = ''): string
Возвращает строку без дополнительной обработки:
$title = SiteLang::get('page.title');Резервное значение передаётся вторым аргументом:
$title = SiteLang::get(
'page.title',
'Заголовок страницы'
);Резервное значение возвращается, если:
- ключ отсутствует
- путь указывает на массив
- значение не является скалярным
Вывод текста в HTML
html(string $path, string $default = ''): string
Экранирует специальные HTML-символы:
<h1><?php echo SiteLang::html('page.title'); ?></h1>Резервное значение также экранируется:
<p>
<?php echo SiteLang::html('page.description', 'Описание отсутствует'); ?>
</p>Используйте html() для обычного текста, который выводится в HTML.
HTML-теги внутри перевода будут показаны как текст:
<?php
return [
'message' => '<strong>Важное сообщение</strong>',
];При выводе через html() браузер не обработает тег <strong>.
Получение исходного значения
get() не экранирует результат:
$value = SiteLang::get('message');Используйте его, когда значение:
- не выводится напрямую в HTML
- передаётся в другую функцию
- сравнивается в PHP
- обрабатывается отдельно перед выводом
Все загруженные переводы
Получить весь объединённый массив можно через:
$translations = SiteLang::all();Массив содержит:
- общие переводы
- переводы текущего контекста
- значения языка по умолчанию
- переопределения текущего языка
- переводы из дополнительных файлов, подключённых через
SiteLang::load()
Добавление нового языка
Перед созданием файлов язык должен быть настроен и активирован в CMS.
После этого:
- Узнайте URL-префикс языка.
- Создайте папку
lang/{prefix}. - Добавьте
common.php. - Добавьте необходимые контекстные файлы.
- Откройте страницу с префиксом нового языка.
- Проверьте переводы и резервные значения.
Например, для префикса de:
lang/de/common.php
lang/de/index.php
lang/de/page/default.phpНеобязательно сразу копировать все файлы языка по умолчанию. Отсутствующие значения будут унаследованы.
Переводы и URL
SiteLang отвечает только за текстовые значения.
Для формирования внутренних ссылок текущего языка используйте:
$url = CurrentLanguage::url('/contacts');Пример:
<a href="<?php echo CurrentLanguage::url('/contacts'); ?>">
<?php echo SiteLang::html('navigation.contacts', 'Контакты'); ?>
</a>Важные замечания
- каждый языковой файл должен возвращать массив
- папка языка называется по URL-префиксу
- контекстный файл называется по шаблону
- общие строки следует хранить в
common.php - переводы шаблонов страниц и записей хранятся в
lang/{prefix}/page/{template}.phpиlang/{prefix}/post/{template}.phpсоответственно - язык по умолчанию должен содержать основной набор переводов
- отсутствующий файл текущего языка не мешает использовать переводы языка по умолчанию
theme-settings.jsonиспользует собственные названия полей и не загружается черезSiteLang