Слава Україні!

Laravel 9. Префикс языка в URL

Добавление метки текущего языка в URL
15-го листопада 2022, 7:37

Эта заметка является немного переработанной статьей, взятой с сайта Web-мастерская

Конфигурация

В файле конфигурации приложения 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' => 'uk',

    // Доступные языки
    'available_locales' => ['uk', 'ru', 'en'],

    ...
    

Класс - посредник LocaleURL



    namespace App\Http\Middleware;

    use Closure;
    use Illuminate\Http\Request;

    class LocaleURL
    {
        public static $default_locale; // основной язык, который не должен отображаться в URl

        public function __construct()
        {
            self::$default_locale = config('app.locale');
        }

        /**
         * @return array
         */
        public static function locales()
        {
            // Указываем, какие языки будем использовать в приложении.
            return config('app.available_locales');
        }

        /*
         * Проверяет наличие корректной метки языка в текущем URL
         * Возвращает метку или значеие null, если нет метки
         */
        public static function getLocale()
        {
            $segment = request()->segment(1);
            // Проверяем метку языка  - есть ли она среди доступных языков
            if (!empty($segment) && in_array($segment, self::locales())) {
                if ($segment != self::$default_locale) {
                    return $segment;
                }
            }
            return null;
        }

        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
         * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
         */
        public function handle(Request $request, Closure $next)
        {
            $locale = self::getLocale();

            if ($locale) app()->setLocale($locale);
            // если метки нет - устанавливаем основной язык $mainLanguage
            else app()->setLocale(self::$default_locale);

            return $next($request); // пропускаем дальше - передаем в следующий посредник
        }
    }
    
В файле app/Http/Kernel.php в конец свойства $middleware прописываем:
\App\Http\Middleware\LocaleURL::class,
теперь класс-посредник будет вызываться при каждом запросе на сервер.

Маршрутизация

В файле routes\web.php добавляем маршрут для смены языка и группу с префиксом текущей локали.

use App\Http\Middleware\LocaleURL;
use Illuminate\Support\Facades\Route;

// Переключение языков
Route::get('/setlocale/{lang}', function ($lang) {

    $referer = redirect()->back()->getTargetUrl(); //URL предыдущей страницы
    $parse_url = parse_url($referer, PHP_URL_PATH); //URI предыдущей страницы

    // разбиваем на массив по разделителю
    $segments = explode('/', $parse_url);

    // Если URL (где нажали на переключение языка) содержал корректную метку языка
    if (in_array($segments[1], LocaleURL::locales())) {
        unset($segments[1]); //удаляем метку
    }

    // Добавляем метку языка в URL (если выбран не язык по-умолчанию)
    if ($lang != LocaleURL::$default_locale) {
        array_splice($segments, 1, 0, $lang);
    }

    // формируем полный URL
    $url = request()->root() . implode("/", $segments);

    // если были еще GET-параметры - добавляем их
    if (parse_url($referer, PHP_URL_QUERY)) {
        $url = $url . '?' . parse_url($referer, PHP_URL_QUERY);
    }
    return redirect(to: $url);

})->name('setlocale');

Route::group(['prefix' => LocaleURL::getLocale()], function(){
    Route::get('/', function () {
        return view('welcome');
    });

    Auth::routes();

    Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
});

Виджет


<?php
    $locale = app()->getLocale();
    $available_locales = config('app.available_locales');
?>
<div class="dropdown">
    <span class="dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
        <? = $available_locales[$locale] ?>
        <?php unset($available_locales[$locale]); ?>
    </span>
    <ul class="dropdown-menu dropdown-language">
        <?php foreach($available_locales as $lang_k => $lang_v): ?>
            <li><a class="dropdown-item" href="<? = route('setlocale', ['lang' => $lang_k]) ?>"><? = $lang_v ?></a></li>
        <?php endforeach ?>
    </ul>
</div>

Важлива інформація

Міністерство оборони
України
з 24.02 по 11.11
втрати противника
орієнтовно склали:
710660 ( +1770 ) особового складу
9253 ( +4 ) танків
18766 ( +40 ) бойових бронемашин
20314 ( +34 ) артилерійських систем
1245 ( +0 ) РСЗВ
996 ( +0 ) засоби ППО
369 ( +0 ) літаків
329 ( +0 ) гелікоптерів
28802 ( +119 ) автомобільної техніки
28 ( +0 ) кораблі / катери
2636 ( +2 ) крилаті ракети
18676 ( +57 ) БПЛА
3620 ( +16 ) спец. техніки
4 ( +0 ) установок ОТРК/ТРК
1 ( +0 ) підводні човни