Spec-Zone.ru › CodeIgniter 4

Локализация

  • Работа с локалями
    • Настройка локали
    • Обнаружение локали
    • Получение текущей локали
  • Локализация языка
    • Создание файлов языка
    • Основное использование
    • Обратная связь локализации
    • Перевод сообщений

Работа с локалями

CodeIgniter предоставляет несколько инструментов для локализации вашего приложения для разных языков. Хотя полная локализация приложения — сложная задача, легко заменить строки в вашем приложении на разные поддерживаемые языки.

Строки языка хранятся в каталоге app/Language, с подкаталогом для каждого поддерживаемого языка:

/app
    /Language
        /en
            app.php
        /fr
            app.php

Важно

Обнаружение локали работает только для веб-запросов, использующих класс IncomingRequest. Запросы командной строки не будут иметь этих функций.

Настройка локали

Каждый сайт будет иметь язык/локаль по умолчанию. Это можно установить в Config/App.php:

public $defaultLocale = 'en';

Значение может быть любой строкой, используемой приложением для управления строками текста и другими форматами. Рекомендуется использовать код языка BCP 47. Это приводит к кодам языка, таким как en-US для американского английского или fr-FR для французского языка/Франции. Более понятное введение в это можно найти на сайте W3C.

Система достаточно умна, чтобы перейти к более общим кодам языка, если точного совпадения нет. Если код локали был установлен на en-US, а у нас есть только файлы языка для en, то они будут использоваться, так как ничего не существует для более конкретного en-US. Однако, если каталог языка существовал в app/Language/en-US, то он будет использоваться в первую очередь.

Обнаружение локали

Для обнаружения правильной локали во время запроса поддерживаются два метода. Первый — метод «установить и забыть», который автоматически выполнит переговоры о содержании для определения правильной локали для использования. Второй метод позволяет указать сегмент в ваших маршрутах, который будет использоваться для установки локали.

Если вам когда-либо потребуется установить локаль напрямую, вы можете использовать IncomingRequest::setLocale(string $locale).

Переговоры о содержании

Вы можете настроить автоматические переговоры о содержании, установив два дополнительных параметра в Config/App. Первое значение сообщает классу Request, что мы хотим переговорить о локали, поэтому просто установите его в true:

public $negotiateLocale = true;

После включения система автоматически определит правильный язык на основе массива локали, который вы определили в $supportLocales. Если между поддерживаемыми вами языками и запрошенным языком не найдено совпадения, будет использоваться первый элемент в $supportedLocales. В следующем примере локаль en будет использоваться, если совпадение не найдено:

public $supportedLocales = ['en', 'es', 'fr-FR'];

В маршрутах

Второй метод использует пользовательский плейсхолдер для обнаружения желаемой локали и установки ее в запросе. Плейсхолдер {locale} может быть размещен как сегмент в вашем маршруте. Если он присутствует, содержимое соответствующего сегмента будет вашей локалью:

$routes->get('{locale}/books', 'App\Books::index');

В этом примере, если пользователь попытался посетить http://example.com/fr/books, то локаль будет установлена на fr, предполагая, что она была настроена как допустимая локаль.

Примечание

Если значение не соответствует допустимой локали, как определено в файле конфигурации приложения, вместо этого будет использоваться локаль по умолчанию.

Получение текущей локали

Текущая локаль всегда может быть получена из объекта IncomingRequest с помощью метода getLocale(). Если ваш контроллер наследуется от CodeIgniter\Controller, это будет доступно через $this->request.

<?php

namespace App\Controllers;

class UserController extends \CodeIgniter\Controller
{
    public function index()
    {
        $locale = $this->request->getLocale();
    }
}

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

$locale = service('request')->getLocale();

Локализация языка

Создание файлов языка

Для файлов языка нет каких-либо специфических правил именования. Файл должен быть логически назван для описания типа содержимого, которое он хранит. Например, предположим, что вы хотите создать файл, содержащий сообщения об ошибках. Вы можете назвать его просто: Errors.php.

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

'language_key' => 'The actual message to be shown.'

Также поддерживается вложенное определение:

'language_key' => [
    'nested' => [
        'key' => 'The actual message to be shown.',
    ],
],

Примечание

Хорошей практикой является использование общего префикса для всех сообщений в данном файле, чтобы избежать коллизий с аналогично названными элементами в других файлах. Например, если вы создаете сообщения об ошибках, вы можете добавить к ним префикс error_

return [
    'errorEmailMissing'    => 'You must submit an email address',
    'errorURLMissing'      => 'You must submit a URL',
    'errorUsernameMissing' => 'You must submit a username',
    'nested'               => [
        'error' => [
            'message' => 'A specific error message',
        ],
    ],
];

Основное использование

Вы можете использовать функцию lang() helper для получения текста из любого файла языка, передавая имя файла и ключ языка как первый параметр, разделенные точкой (.). Например, чтобы загрузить строку errorEmailMissing из файла языка Errors, вы должны сделать следующее:

echo lang('Errors.errorEmailMissing');

Для вложенного определения вы должны сделать следующее:

echo lang('Errors.nested.error.message');

Если запрошенный ключ языка не существует в файле для текущей локали, строка будет возвращена без изменений. В этом примере будет возвращено ‘Errors.errorEmailMissing’ или ‘Errors.nested.error.message’, если это значение не существует.

Замена параметров

Примечание

Для работы всех следующих функций необходим расширение intl на вашем сервере. Если расширение не загружено, попытка замены не будет осуществлена. Подробный обзор можно найти на Sitepoint.

Вы можете передать массив значений для замены плейсхолдеров в строке языка в качестве второго параметра функции lang(). Это позволяет очень просто переводить числа и форматировать их:

// The language file, Tests.php:
return [
    "apples"      => "I have {0, number} apples.",
    "men"         => "The top {1, number} men out-performed the remaining {0, number}",
    "namedApples" => "I have {number_apples, number, integer} apples.",
];

// Displays "I have 3 apples."
echo lang('Tests.apples', [ 3 ]);

Первый элемент в плейсхолдере соответствует индексу элемента в массиве, если он числовой:

// Displays "The top 23 men out-performed the remaining 20"
echo lang('Tests.men', [20, 23]);

Вы также можете использовать именованные ключи, чтобы проще отслеживать значения:

// Displays "I have 3 apples."
echo lang("Tests.namedApples", ['number_apples' => 3]);

Очевидно, вы можете сделать больше, чем просто заменить числа. В соответствии с официальной документацией ICU для базовой библиотеки, можно заменить следующие типы данных:

  • числа — целые, валюты, проценты
  • даты — короткие, средние, длинные, полные
  • время — короткие, средние, длинные, полные
  • прописью — числа прописью (т.е. 34 становится тридцать четыре)
  • порядковый
  • продолжительность

Вот несколько примеров:

// The language file, Tests.php
return [
    'shortTime'  => 'The time is now {0, time, short}.',
    'mediumTime' => 'The time is now {0, time, medium}.',
    'longTime'   => 'The time is now {0, time, long}.',
    'fullTime'   => 'The time is now {0, time, full}.',
    'shortDate'  => 'The date is now {0, date, short}.',
    'mediumDate' => 'The date is now {0, date, medium}.',
    'longDate'   => 'The date is now {0, date, long}.',
    'fullDate'   => 'The date is now {0, date, full}.',
    'spelledOut' => '34 is {0, spellout}',
    'ordinal'    => 'The ordinal is {0, ordinal}',
    'duration'   => 'It has been {0, duration}',
];

// Displays "The time is now 11:18 PM"
echo lang('Tests.shortTime', [time()]);
// Displays "The time is now 11:18:50 PM"
echo lang('Tests.mediumTime', [time()]);
// Displays "The time is now 11:19:09 PM CDT"
echo lang('Tests.longTime', [time()]);
// Displays "The time is now 11:19:26 PM Central Daylight Time"
echo lang('Tests.fullTime', [time()]);

// Displays "The date is now 8/14/16"
echo lang('Tests.shortDate', [time()]);
// Displays "The date is now Aug 14, 2016"
echo lang('Tests.mediumDate', [time()]);
// Displays "The date is now August 14, 2016"
echo lang('Tests.longDate', [time()]);
// Displays "The date is now Sunday, August 14, 2016"
echo lang('Tests.fullDate', [time()]);

// Displays "34 is thirty-four"
echo lang('Tests.spelledOut', [34]);

// Displays "It has been 408,676:24:35"
echo lang('Tests.ordinal', [time()]);

Вы должны изучить класс MessageFormatter и базовую библиотеку форматирования ICU, чтобы лучше понять ее возможности, такие как условная замена, множественное число и многое другое. Обе предоставленные ссылки дадут вам отличное представление о доступных возможностях.

Указание локали

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

// Displays "The time is now 23:21:28 GMT-5"
echo lang('Test.longTime', [time()], 'ru-RU');

// Displays "£7.41"
echo lang('{price, number, currency}', ['price' => 7.41], 'en-GB');
// Displays "$7.41"
echo lang('{price, number, currency}', ['price' => 7.41], 'en-US');

Вложенные массивы

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

// Language/en/Fruit.php

return [
    'list' => [
        'Apples',
        'Bananas',
        'Grapes',
        'Lemons',
        'Oranges',
        'Strawberries',
    ],
];

// Displays "Apples, Bananas, Grapes, Lemons, Oranges, Strawberries"
echo implode(', ', lang('Fruit.list'));

Обратная связь локализации

Если у вас есть набор сообщений для данной локали, например Language/en/app.php, вы можете добавить варианты языка для этой локали, каждый в своей папке, например Language/en-US/app.php.

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

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

Таким образом, если вы используете локаль fr-CA, сначала будет искомое сообщение в Language/fr/CA, затем в Language/fr, и, наконец, в Language/en.

Перевод сообщений

У нас есть «официальный» набор переводов в их своём репозитории.

Вы можете загрузить этот репозиторий и скопировать папку Language в app. Включённые переводы будут автоматически взяты, потому что пространство имен App сопоставлено с папкой app.

В качестве альтернативы, лучшей практикой будет composer require codeigniter4/translations внутри вашего проекта, и переведённые сообщения будут автоматически взяты, потому что папки переводов сопоставляются должным образом.

© 2014–2020 British Columbia Institute of Technology
Licensed under the MIT License.
https://codeigniter.com/user_guide/outgoing/localization.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API