Статті

Покрокове керівництво з локалізації Laravel, посібник із прикладами

Як локалізувати проект Laravel, як розробити проект у Laravel і зробити його придатним для використання кількома мовами.

У цій статті ми побачимо, як налаштувати файли перекладу, створити селектор мови тощо з прикладами.

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

передумови

  • У цій статті ми торкнемося Laravel версії 8.x;
  • Щоб успішно дотримуватися цього підручника, вам потрібно мати необхідні знання мови програмування PHP і фреймворку Laravel.
  • Ваш домен localhost. Якщо ні, замініть localhost з вашим власним доменним іменем або IP-адресою (залежно від вашої інсталяції).

Робота з файлами перекладу

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

  • Старіший підхід, який зберігає файли в такому місці: resources/lang/{en,fr,ru}/{myfile.php};
  • Новий підхід, який зберігає файли в такому місці: resources/lang/{fr.json, ru.json};

Для мов, які відрізняються територією, слід назвати їх directory/file мови відповідно до ISO 15897. Наприклад, для британської англійської ви б використали en_GB замість en-gb. У цій статті ми зосередимося на другому підході, але те саме стосується першого (за винятком того, як ключі перекладу називаються та витягуються). 

Прості переклади

Давайте розглянемо файл resources/views/welcome.blade.php і замініть вміст тегу body з нашими, як це:

<body class="antialiased">
    <div class="relative flex items-top justify-center min-h-screen bg-gray-100 dark:bg-gray-900 sm:items-center py-4 sm:pt-0">
        <div class="max-w-6xl mx-auto sm:px-6 lg:px-8">
            <div class="flex justify-center pt-8 sm:justify-start sm:pt-0">
                Welcome to our website
            </div>
        </div>
    </div>
</body>

Ми почнемо з підготовки нашого вітального повідомлення щодо локалізації, яке дуже легко зробити в Laravel. Все, що вам потрібно зробити, це замінити текст «Ласкаво просимо на наш сайт» наступним кодом: {{ __('Welcome to our website') }}. Це накаже Laravel відображати «Ласкаво просимо на наш веб-сайт» за замовчуваннямdefinite та шукайте переклади цього рядка, якщо встановлено мову, відмінну від англійської (ми поговоримо про це пізніше). Англійська мова буде встановлена ​​як мова за замовчуваннямdefiзавершення нашої програми, тому за умовчаннямdefinita ми просто відобразимо текст «Ласкаво просимо на наш сайт». Якщо локалізація інша, ми спробуємо знайти відповідний переклад, який буде створено за мить.

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

Але як Laravel дізнається, яка поточна мова або які мови доступні в програмі? 

Це робиться шляхом налаштування локальної конфігурації в програмі config/app.php. Давайте відкриємо цей файл і шукаємо інформацію в асоціативній матриці:

/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
'locale' => 'en',
/*
|--------------------------------------------------------------------------
| Application Fallback Locale
|--------------------------------------------------------------------------
|
| The fallback locale determines the locale to use when the current one
| is not available. You may change the value to correspond to any of
| the language folders that are provided through your application.
|
*/
'fallback_locale' => 'en',

Описи, які передують призначенню ключів locale e fallback_locale вони зрозумілі самі за себе. У всякому разі, ключ locale містить попередню локалізаціюdefiкінець вашої заявки (принаймні, якщо ніхто інший locale було встановлено в коді). І fallback_locale активується, якщо ми встановимо a locale не існує в нашій програмі.

Поки цей файл відкритий, давайте додамо новий ключ 'available_locales' для нашої зручності, перераховуючи всі локалі, які підтримуватиме наша програма. Ми використаємо це пізніше, коли додамо локальний комутатор. Однак це необов’язкове завдання, оскільки Laravel не вимагає від нас його виконання.

/*
|--------------------------------------------------------------------------
| Available locales
|--------------------------------------------------------------------------
|
| List all locales that your application works with
|
*/
'available_locales' => [
  'English' => 'en',
  'Italian' => 'it',
  'French' => 'fr',
],

Тепер наш додаток підтримує три мови: англійську, італійську та французьку.

Файл перекладу

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

Почнемо з додавання нових файлів локалізації до папки resources/lang. Потім створюємо файл resources/lang/it.json і додайте відповідні переклади, як показано нижче:

{
  "Welcome to our website": "Benvenuto nel nostro sito web"
}

Отже, давайте створимо файл resources/lang/fr.json:

{

«Ласкаво просимо на наш сайт»: «Ласкаво просимо на наш сайт»

}

Як бачите, ми завжди посилаємося на попереднє повідомленняdefinito, який ми додали у файл welcome.blade.php (який був {{ __('Welcome to our website') }}). Причина, чому нам не потрібно створювати файл en.json це тому, що Laravel вже знає, які повідомлення ми передаємо за попередніми налаштуваннямиdefiзакінчив на функції __() вони для нашого місцевого преdefinito en.

Зміна локалізації в Laravel

На даний момент Laravel не знає, як змінити локалізацію, тому поки що ми виконуємо переклади безпосередньо в межах шляху. Редагувати попередній шлях привітанняdefiзавершено, як показано нижче:

Route::get('/{locale?}', function ($locale = null) {
    if (isset($locale) && in_array($locale, config('app.available_locales'))) {
        app()->setLocale($locale);
    }
    
    return view('welcome');
});

Тепер ми можемо відвідати наш веб-сайт, вказавши будь-яку з доступних мов як перший сегмент шляху: наприклад, localhost/itlocalhost/fr. Ви повинні побачити локалізований вміст. Якщо ви вкажете непідтримувану мову або взагалі не вкажете мову, Laravel використовуватиме en за замовчуваннямdefinita.

проміжне

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

Для цього ми створимо новий middleware, і ми його назвемо app/Http/Middleware/Localization.php, запустивши командний рядок artisan make:middleware Localization.

Після виконання команди, відкривши файл Localization.php, ми побачимо defiвизначення класу локалізації:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Session;

class Localization
{
    /**
    * Handle an incoming request.
    *
    * @param  \Illuminate\Http\Request  $request
    * @param  \Closure  $next
    * @return mixed
    */
    public function handle(Request $request, Closure $next)
    {
        if (Session::has('locale')) {
            App::setLocale(Session::get('locale'));
        }
        return $next($request);
    }
}

Це проміжне програмне забезпечення вказує Laravel використовувати вибрану користувачем мову, якщо цей вибір присутній у сеансі.

Оскільки цю операцію потрібно виконувати для кожного запиту, нам також потрібно додати її до попереднього стеку проміжного програмного забезпеченняdefiзакінчив у app/http/Kernel.php і зокрема в асоціативному ряду $middlewareGroups:

* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
  'web' => [
      \App\Http\Middleware\EncryptCookies::class,
      \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
      \Illuminate\Session\Middleware\StartSession::class,
      // \Illuminate\Session\Middleware\AuthenticateSession::class,
      \Illuminate\View\Middleware\ShareErrorsFromSession::class,
      \App\Http\Middleware\VerifyCsrfToken::class,
      \Illuminate\Routing\Middleware\SubstituteBindings::class,
      \App\Http\Middleware\Localization::class, /* <--- add this */
  ],

Cambiare le route

Далі нам потрібно додати шлях для зміни локалі. Ми використовуємо шлях закриття, але ви можете використовувати точно такий же код у своєму контролері, якщо хочете:

Route::get('language/{locale}', function ($locale) {
    app()->setLocale($locale);
    session()->put('locale', $locale);

    return redirect()->back();
});

Крім того, не забудьте видалити перемикач локалі, який раніше було додано в наш попередній шлях привітанняdefiнічний:

Route::get('/', function () {
    return view('welcome');
});

Після того, як це буде зроблено, єдиний спосіб для користувача змінити поточну встановлену мову – ввести localhost/language/{locale}. Вибір locale зберігатимуться в сеансі та перенаправлятимуть користувачів туди, звідки вони прийшли (перевірте проміжне ПЗ Localization). Щоб спробувати, перейдіть на сторінку localhost/language/ru (поки ваш сеансовий файл cookie присутній у вашому браузері), і ви побачите перекладений вміст. Ви можете вільно переміщатися веб-сайтом або спробувати оновити сторінку та переконатися, що вибрана мова збережена.

Комутатор

Тепер нам потрібно створити щось, на що користувач зможе клацнути, щоб змінити мову, замість того, щоб вручну вводити коди мови в URL-адресу. Для цього ми додамо дуже простий елемент керування мовою. Тому давайте створимо новий файл resources/views/partials/language_switcher.blade.php з таким кодом:

<div class="flex justify-center pt-8 sm:justify-start sm:pt-0">
    @foreach($available_locales as $locale_name => $available_locale)
        @if($available_locale === $current_locale)
            <span class="ml-2 mr-2 text-gray-700">{{ $locale_name }}</span>
        @else
            <a class="ml-1 underline ml-2 mr-2" href="language/{{ $available_locale }}">
                <span>{{ $locale_name }}</span>
            </a>
        @endif
    @endforeach
</div>

Включіть щойно створений перемикач у вікні «вітання»:

Інноваційний бюлетень
Не пропустіть найважливіші новини про інновації. Підпишіться, щоб отримувати їх електронною поштою.
<body class="antialiased">
    <div class="relative flex items-top justify-center min-h-screen bg-gray-100 dark:bg-gray-900 sm:items-center py-4 sm:pt-0">
        <div class="max-w-6xl mx-auto sm:px-6 lg:px-8">
            @include('partials/language_switcher')
            <div class="flex justify-center pt-8 sm:justify-start sm:pt-0">
                {{ __('Welcome to our website') }}
            </div>
        </div>
    </div>
</body>

Відкрийте файл app/Providers/AppServiceProvider.php і додайте код для спільного використання, коли наш перемикач мов активний. Зокрема, ми надамо доступ до поточних параметрів мови, доступ до яких можна отримати як файл {{ $current_locale }}.

Розширені параметри перекладу в PHP Laravel

В основному ми будемо працювати з resources/views/welcome.blade.php, тому все має відбуватися в нашому бажаному вигляді.

Параметри в рядках перекладу

Наприклад, привітаємося з нашим уявним користувачем (Аманда) замість того, щоб просто відображати загальне повідомлення:

{{ __('Welcome to our website, :Name', ['name' => 'caroline']) }}

Зауважте, що ми використали ім’я з першою літерою в нижньому регістрі, але заповнювач із першою літерою у верхньому регістрі. Таким чином, Laravel може допомогти вам автоматично вводити слово з великої літери. Це станеться, якщо заповнювач починається з великої літери, наприклад, :Nameстворює слово «Кароліна» або повністю написане з великої літери слово,  :NAME, випускає “CAROLINE”.

Ми також оновлюємо наші файли перекладу resources/lang/fr.jsonresources/lang/it.json.

французька:

{

   "Welcome to our website, :Name": "Bienvenue sur notre site, :Name"

}

Італійська:

{

   "Welcome to our website, :Name": "Benvenuto sul nostro sito web, :Name"

}

Множинність

Щоб побачити множину в дії, давайте додамо новий абзац тексту. 

Щоб виконати множину, необхідно скористатися функцією trans_choice замість __(), наприклад:

{{ __('Welcome to our website, :Name', ['name' => 'caroline']) }}
<br>
{{ trans_choice('There is one apple|There are many apples', 2) }}

Як бачимо, форми множини розділяються а |.

А що, якщо нам потрібні кілька форм множини? 

Це також можливо:

{{ trans_choice('{0} There :form no apples|{1} There :form just :count apple|[2,19] There :form :count apples', 24) }}

У цьому випадку ми допускаємо цифри 01, і 219, і нарешті з 20 і далі. Звичайно, ви можете додати скільки завгодно правил.

То що, якщо ми хочемо, щоб заповнювачі були у формі множини? 

{{ trans_choice('{0} There :form no apples|{1} There :form just :count apple|[2,19] There :form :count apples', 24, ['form' => 'is']) }}

Ми також можемо використовувати підрахунок, переданий у `trans_choice`, якщо потрібно, використовуючи заповнювач :count спеціальні:

{{ trans_choice('{0} There :form no apples|{1} There :form just :count apple|[2,19] There :form :count apples', 1, ['form' => 'is']) }}

Нарешті, не забудьте оновити ваші файли перекладу будь-якими змінами, які ви внесли в базовий переклад.

Італійська:

{
  "Welcome to our website, :Name": "Benvenuto nel nostro sito, :Name",
  "{0} There :form no apples|{1} There :form just :count apple|[2,19] There :form :count apples": "{0} Nessuna mela|{1} C'è:count mela|[2,19] Ci sono :count mele"
}

французька:

{    
  "Welcome to our website, :Name": "Bienvenue sur notre site, :Name",
  "{0} There :form no apples|{1} There :form just :count apple|[2,19] There :form :count apples": "{0} Il n'y a pas de pommes|{1} Il n'y :form :count pomme|[2,19] Il y :form :count pommes"
}

Робота з локалізованими датами в Laravel

Щоб знайти дати, ми використаємо силу Вуглець , який поставляється з Laravel за замовчуваннямdefinita. Перевірте Карбонова документація ; можна робити багато цікавого. Наприклад, ми можемо встановити нашу локаль за допомогою правил дати та часу.

Для нашого простого прикладу ми покажемо поточну дату, локалізовану для вибраної мови. В нашому routes/web.php, ми оновлюємо шлях до сторінки привітання та передаємо локалізоване повідомлення дати нашій view ласкаво просимо:

<?php
Route::get('/', function () {
    $today = \Carbon\Carbon::now()
        ->settings(
            [
                'locale' => app()->getLocale(),
            ]
        );

    // LL is macro placeholder for MMMM D, YYYY (you could write same as dddd, MMMM D, YYYY)
    $dateMessage = $today->isoFormat('dddd, LL');

    return view('welcome', [
        'date_message' => $dateMessage
    ]);
});

Давайте оновити resources/views/welcome.blade.php додавання відображення дати, наприклад:

{{ __('Welcome to our website, :Name', ['name' => 'amanda']) }}
<br>
{{ trans_choice('{0} There :form :count apples|{1} There :form just :count apple|[2,19] There :form :count apples', 1, ['form' => 'is']) }}
<br>
{{ $date_message }}

Спроба змінити мову на домашній сторінці localhost, ми побачимо, що дати тепер локалізовано, наприклад:

Форматування чисел і валют за допомогою NumberFormatter

У різних країнах люди використовують різні формати для представлення чисел, наприклад:

  • Сполучені Штати → 123.123,12
  • Франція → 123 123,12

Тому, щоб відобразити ці відмінності у вашій програмі Laravel, ви можете використовувати NumberFormatter у такий спосіб:

<?php
$num = NumberFormatter::create('en_US', NumberFormatter::DECIMAL);

$num2 = NumberFormatter::create('fr', NumberFormatter::DECIMAL);

Ви також можете написати число певною мовою та відобразити щось на зразок «сто двадцять три тисячі сто двадцять три кома один два»:

<?php
$num = NumberFormatter::create('en_US', NumberFormatter::SPELLOUT);
$num2 = NumberFormatter::create('fr', NumberFormatter::SPELLOUT);

Крім того, NumberFormatter дозволяє легко знаходити валюти, наприклад:

<?php
$currency1 = NumberFormatter::create('fr', NumberFormatter::CURRENCY);
$currency2 = NumberFormatter::create('en_US', NumberFormatter::CURRENCY);

Тому для fr ви побачите євро, а за en_US валюта буде в доларах США.

Пов'язані читання

Ercole Palmeri

Інноваційний бюлетень
Не пропустіть найважливіші новини про інновації. Підпишіться, щоб отримувати їх електронною поштою.

Читайте Innovation своєю мовою

Інноваційний бюлетень
Не пропустіть найважливіші новини про інновації. Підпишіться, щоб отримувати їх електронною поштою.

Слідуйте за нами