Джерело: https://laravelukraine.com/docs/13.x/localization

# Локалізація

- [Вступ](#introduction)
    - [Публікація мовних файлів](#publishing-the-language-files)
    - [Налаштування локалі](#configuring-the-locale)
    - [Мова множини](#pluralization-language)
- [Опис рядків перекладу](#defining-translation-strings)
    - [Короткі ключі](#using-short-keys)
    - [Рядки перекладу як ключі](#using-translation-strings-as-keys)
- [Отримання рядків перекладу](#retrieving-translation-strings)
    - [Заміна параметрів у рядках перекладу](#replacing-parameters-in-translation-strings)
    - [Множина](#pluralization)
- [Перевизначення мовних файлів пакетів](#overriding-package-language-files)

<a name="introduction"></a>
## Вступ

> [!NOTE]
> За замовчуванням каркас застосунку Laravel не містить каталогу `lang`. Якщо ви хочете налаштувати мовні файли Laravel, опублікуйте їх командою Artisan `lang:publish`.

Можливості локалізації Laravel надають зручний спосіб отримувати рядки різними мовами, дозволяючи легко підтримувати кілька мов у вашому застосунку.

Laravel пропонує два способи керувати рядками перекладу. Перший: мовні рядки можна зберігати у файлах у каталозі `lang` застосунку. У цьому каталозі можуть бути підкаталоги для кожної мови, яку підтримує застосунок. Саме цей підхід Laravel використовує для рядків перекладу вбудованих можливостей - наприклад, повідомлень про помилки валідації:

```text
/lang
    /en
        messages.php
    /es
        messages.php
```

Або ж рядки перекладу можна описати у JSON-файлах, розміщених у каталозі `lang`. За такого підходу кожна мова, яку підтримує ваш застосунок, матиме відповідний JSON-файл у цьому каталозі. Цей підхід рекомендують для застосунків з великою кількістю рядків для перекладу:

```text
/lang
    en.json
    es.json
```

Ми розглянемо кожен підхід до керування рядками перекладу в цій документації.

<a name="publishing-the-language-files"></a>
### Публікація мовних файлів

За замовчуванням каркас застосунку Laravel не містить каталогу `lang`. Якщо ви хочете налаштувати мовні файли Laravel або створити власні, згенеруйте каталог `lang` командою Artisan `lang:publish`. Команда `lang:publish` створить у вашому застосунку каталог `lang` і опублікує стандартний набір мовних файлів, які використовує Laravel:

```shell
php artisan lang:publish
```

<a name="configuring-the-locale"></a>
### Налаштування локалі

Мова за замовчуванням для вашого застосунку зберігається в опції конфігурації `locale` у файлі `config/app.php`, яку зазвичай задають змінною середовища `APP_LOCALE`. Ви вільні змінити це значення під потреби свого застосунку.

Ви також можете налаштувати «запасну мову», яка використовуватиметься, коли в мові за замовчуванням немає потрібного рядка перекладу. Як і мову за замовчуванням, запасну мову налаштовують у файлі `config/app.php`, а її значення зазвичай задають змінною середовища `APP_FALLBACK_LOCALE`.

Ви можете змінити мову за замовчуванням для окремого HTTP-запиту під час виконання методом `setLocale` фасаду `App`:

```php
use Illuminate\Support\Facades\App;

Route::get('/greeting/{locale}', function (string $locale) {
    if (! in_array($locale, ['en', 'es', 'fr'])) {
        abort(400);
    }

    App::setLocale($locale);

    // ...
});
```

<a name="determining-the-current-locale"></a>
#### Визначення поточної локалі

Методи `currentLocale` та `isLocale` фасаду `App` дозволяють визначити поточну локаль або перевірити, чи має вона задане значення:

```php
use Illuminate\Support\Facades\App;

$locale = App::currentLocale();

if (App::isLocale('en')) {
    // ...
}
```

<a name="pluralization-language"></a>
### Мова множини

<style>
.code-list-no-flex-break code {
    display: contents !important;
}
</style>

<div class="code-list-no-flex-break">

Ви можете вказати «плюралізатору» Laravel, який Eloquent та інші частини фреймворку використовують для перетворення рядків з однини на множину, працювати з мовою, відмінною від англійської. Це робиться викликом методу `useLanguage` у методі `boot` одного з сервіс-провайдерів вашого застосунку. Наразі плюралізатор підтримує такі мови: `french`, `norwegian-bokmal`, `portuguese`, `spanish` та `turkish`:

</div>

```php
use Illuminate\Support\Pluralizer;

/**
 * Bootstrap any application services.
 */
public function boot(): void
{
    Pluralizer::useLanguage('spanish');

    // ...
}
```

> [!WARNING]
> Якщо ви змінюєте мову плюралізатора, вам слід явно описати [назви таблиць](/docs/{{version}}/eloquent#table-names) ваших моделей Eloquent.

<a name="defining-translation-strings"></a>
## Опис рядків перекладу

<a name="using-short-keys"></a>
### Короткі ключі

Зазвичай рядки перекладу зберігаються у файлах у каталозі `lang`. У цьому каталозі має бути підкаталог для кожної мови, яку підтримує ваш застосунок. Саме цей підхід Laravel використовує для рядків перекладу вбудованих можливостей - наприклад, повідомлень про помилки валідації:

```text
/lang
    /en
        messages.php
    /es
        messages.php
```

Усі мовні файли повертають масив рядків із ключами. Наприклад:

```php
<?php

// lang/en/messages.php

return [
    'welcome' => 'Welcome to our application!',
];
```

> [!WARNING]
> Для мов, які різняться за територією, називайте мовні каталоги за стандартом ISO 15897. Наприклад, для британської англійської слід використовувати «en_GB», а не «en-gb».

<a name="using-translation-strings-as-keys"></a>
### Рядки перекладу як ключі

У застосунках з великою кількістю рядків для перекладу опис кожного рядка «коротким ключем» може заплутувати під час звертання до ключів у представленнях, та й вигадувати ключі для кожного рядка перекладу обтяжливо.

Тому Laravel також підтримує опис рядків перекладу, де ключем є «стандартний» переклад рядка. Мовні файли, у яких рядки перекладу є ключами, зберігаються як JSON-файли в каталозі `lang`. Наприклад, якщо ваш застосунок має іспанський переклад, створіть файл `lang/es.json`:

```json
{
    "I love programming.": "Me encanta programar."
}
```

#### Конфлікти ключів і файлів

Не описуйте ключі рядків перекладу, які конфліктують з іменами інших мовних файлів. Наприклад, переклад `__('Action')` для локалі «NL», коли файл `nl/action.php` існує, а файлу `nl.json` немає, призведе до того, що перекладач поверне весь вміст `nl/action.php`.

<a name="retrieving-translation-strings"></a>
## Отримання рядків перекладу

Отримати рядки перекладу з мовних файлів можна функцією-хелпером `__`. Якщо ви описуєте рядки перекладу «короткими ключами», передайте функції `__` файл, який містить ключ, і сам ключ через «крапковий» синтаксис. Наприклад, дістаньмо рядок перекладу `welcome` з мовного файлу `lang/en/messages.php`:

```php
echo __('messages.welcome');
```

Якщо вказаного рядка перекладу не існує, функція `__` поверне ключ рядка перекладу. Тож у прикладі вище функція `__` повернула б `messages.welcome`, якби рядка перекладу не існувало.

Якщо ви використовуєте [стандартні рядки перекладу як ключі](#using-translation-strings-as-keys), передайте функції `__` стандартний переклад свого рядка;

```php
echo __('I love programming.');
```

Знову ж таки, якщо рядка перекладу не існує, функція `__` поверне переданий їй ключ рядка перекладу.

Якщо ви користуєтеся [шаблонізатором Blade](/docs/{{version}}/blade), вивести рядок перекладу можна синтаксисом виведення `{{ }}`:

```blade
{{ __('messages.welcome') }}
```

<a name="replacing-parameters-in-translation-strings"></a>
### Заміна параметрів у рядках перекладу

За бажанням ви можете описувати в рядках перекладу плейсхолдери. Усі плейсхолдери мають префікс `:`. Наприклад, ви можете описати вітальне повідомлення з плейсхолдером імені:

```php
'welcome' => 'Welcome, :name',
```

Щоб замінити плейсхолдери під час отримання рядка перекладу, передайте масив замін другим аргументом функції `__`:

```php
echo __('messages.welcome', ['name' => 'dayle']);
```

Якщо ваш плейсхолдер написано великими літерами або з великої літери, перекладене значення буде відповідно капіталізовано:

```php
'welcome' => 'Welcome, :NAME', // Welcome, DAYLE
'goodbye' => 'Goodbye, :Name', // Goodbye, Dayle
```

<a name="object-replacement-formatting"></a>
#### Форматування підстановки об'єктів

Якщо ви спробуєте передати об'єкт як плейсхолдер перекладу, буде викликано його метод `__toString`. Метод [__toString](https://www.php.net/manual/en/language.oop5.magic.php#object.tostring) - один із вбудованих «магічних методів» PHP. Проте інколи ви можете не контролювати метод `__toString` певного класу - наприклад, коли клас, з яким ви працюєте, належить сторонній бібліотеці.

У таких випадках Laravel дозволяє зареєструвати власний обробник форматування для конкретного типу об'єктів. Для цього викличте метод `stringable` перекладача. Метод `stringable` приймає замикання, у якому слід вказати тип об'єкта, за форматування якого воно відповідає. Зазвичай метод `stringable` викликають у методі `boot` класу `AppServiceProvider` вашого застосунку:

```php
use Illuminate\Support\Facades\Lang;
use Money\Money;

/**
 * Bootstrap any application services.
 */
public function boot(): void
{
    Lang::stringable(function (Money $money) {
        return $money->formatTo('en_GB');
    });
}
```

<a name="pluralization"></a>
### Множина

Множина - складна задача, адже різні мови мають розмаїті складні правила її утворення; проте Laravel допоможе перекладати рядки по-різному за правилами множини, які ви опишете. Символом `|` ви можете розділити форми однини та множини рядка:

```php
'apples' => 'There is one apple|There are many apples',
```

Звісно, множина підтримується й тоді, коли ви використовуєте [рядки перекладу як ключі](#using-translation-strings-as-keys):

```json
{
    "There is one apple|There are many apples": "Hay una manzana|Hay muchas manzanas"
}
```

Ви можете створювати й складніші правила множини, які задають рядки перекладу для кількох діапазонів значень:

```php
'apples' => '{0} There are none|[1,19] There are some|[20,*] There are many',
```

Описавши рядок перекладу з варіантами множини, ви можете скористатися функцією `trans_choice`, щоб отримати рядок для заданої «кількості». У цьому прикладі, оскільки кількість більша за одиницю, буде повернуто форму множини:

```php
echo trans_choice('messages.apples', 10);
```

Ви також можете описувати в рядках множини плейсхолдери-атрибути. Замінити їх можна, передавши масив третім аргументом функції `trans_choice`:

```php
'minutes_ago' => '{1} :value minute ago|[2,*] :value minutes ago',

echo trans_choice('time.minutes_ago', 5, ['value' => 5]);
```

Якщо ви хочете вивести ціле число, передане функції `trans_choice`, скористайтеся вбудованим плейсхолдером `:count`:

```php
'apples' => '{0} There are none|{1} There is one|[2,*] There are :count',
```

<a name="overriding-package-language-files"></a>
## Перевизначення мовних файлів пакетів

Деякі пакети можуть постачатися з власними мовними файлами. Замість змінювати основні файли пакета заради правки цих рядків, ви можете перевизначити їх, розмістивши файли в каталозі `lang/vendor/{package}/{locale}`.

Наприклад, якщо вам потрібно перевизначити англійські рядки перекладу в `messages.php` для пакета `skyrim/hearthfire`, покладіть мовний файл за шляхом: `lang/vendor/hearthfire/en/messages.php`. У цьому файлі описуйте лише ті рядки перекладу, які хочете перевизначити. Усі рядки, які ви не перевизначили, і далі завантажуватимуться з оригінальних мовних файлів пакета.