20. listopadu 2021
Lokalizace Laravel aplikace
Naučte se, jak lokalizovat Laravel aplikaci. Tento průvodce pokrývá vše od nastavení jazykových souborů až po přepínání jazyků.
Níže uvedený návod popisuje jednoduchou lokalizaci Laravel aplikace (tedy překlady pouze částí aplikace, nikoliv překlad obsahu stránek uloženého v databázi či lokalizace URL adres). Návod se tedy věnuje, jak nastavit překlady řetězců objevujících se v šabloně Laravel aplikace.
Testováno
CS_CONTENT continues from where it was cut: Testováno ve verzi: Laravel 8 Logika je poměrně jednoduchá, není potřeba žádného zásahu do databáze. config/app.php: app/Http/Middleware/Language.php: app/Http/Kernel.php: routes/web.php: app/Http/Controllers/LanguageController.php: routes/web.php: app/Providers/RouteServiceProvider.php: Příklad pro použití ve stacku: Laravel, Jetstream – Livewire + Blade, Tailwindcss resources/views/navigation-menu.blade.php: Desktop Responzivní verze Například resources/lang/cs.json: Česká verze: Anglická verze: Pokud používáte Jetstream spolu s Livewire jako v příkladu a chcete defaultní routy lokalizovat, pak musíte udělat ještě několik menších úprav. Ze složky /vendor/jetstream/routes/ překopírujte routy k Vašim routám. Soubor pak může vypadat následovně (routes/web.php): Pokud bychom upravili například routu pro zobrazení profilu, například takto (routes/web.php): Pokud uděláme výše uvedenou změnu, zobrazení profilu bude dostupné jak na naší routě /profile, tak i můžeme využít výchozí routu /user/profile (načítanou z package – laravel/jetstream/routes/livewire.php). Pokud chceme výchozí routy vypnout, pak musíme upravit JetsreamServiceProvider.php (app/Providers/JetsreamServiceProvider.php).
Stack: Jetstream / Livewire + Blade/Tailwind CSS, ale prakticky se změnami na straně front endu lze použít kdekoliv
Dokumentace: https://laravel.com/docs/8.x/localizationLogika
Nastavení jazyků
...
'locales' => [
'en' => 'English',
'cs' => 'Czech',
],
...Middleware Language
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\URL;
class Language
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
App::setLocale($request->language);
URL::defaults(['language' => $request->language]);
$request->route()->forgetParameter('language');
return $next($request);
}
}Přidání middlewaru do kernelu
...
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\Language::class, // Localization
],
...
];
...Routy ve web.php
...
Route::group([
'prefix' => "{language}",
'where' => ['language' => '[a-zA-Z]{2}']
], function () {
...
});
...Kontroler LanguageController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\URL;
class LanguageController extends Controller
{
public function switchLang(Request $request, $lang)
{
// $urlParts[1] == current lang
$urlParts = explode('/', str_ireplace(array('http://', 'https://'), '', url()->previous()));
$newUrl = str_replace(
'/' . $urlParts[1] . '/',
'/' . $lang . '/',
url()->previous()
);
App::setLocale($lang);
URL::defaults(['language' => $lang]);
return redirect()->to($newUrl);
}
}Přidání routy kontroleru do web.php
...
Route::get('lang/{lang}', [App\Http\Controllers\LanguageController::class, 'switchLang'])->name('langSwitcher');
...RouteServiceProvider.php
...
public const DASHBOARD = '/en/dashboard';
...Vytvoření Language switcheru
...
<!-- Language Dropdown -->
<div class="ml-3 relative">
<x-jet-dropdown align="right" width="48">
<x-slot name="trigger">
<span class="inline-flex rounded-md">
<button type="button" class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 bg-white hover:text-gray-700 focus:outline-none transition">
@lang(config('app.locales')[App::getLocale()])
<svg class="ml-2 -mr-0.5 h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" />
</svg>
</button>
</span>
</x-slot>
<x-slot name="content">
<!-- Language Switcher -->
<div class="block px-4 py-2 text-xs text-gray-400">
{{ __('Select language') }}
</div>
@foreach (config('app.locales') as $lang => $language)
@if ($lang !== App::getLocale())
<x-jet-dropdown-link href="{{ route('langSwitcher', $lang) }}">
@lang($language)
</x-jet-dropdown-link>
@endif
@endforeach
</x-slot>
</x-jet-dropdown>
</div>
......
<div class="mt-3 space-y-1">
<div class="border-t border-gray-200"></div>
<div class="block px-4 py-2 text-xs text-gray-400">
{{ __('Select language') }}
</div>
@foreach (config('app.locales') as $lang => $language)
@if ($lang !== App::getLocale())
<x-jet-responsive-nav-link href="{{ route('langSwitcher', $lang) }}">
@lang($language)
</x-jet-responsive-nav-link>
@endif
@endforeach
<div class="border-t border-gray-200"></div>
</div>
...Doplnění překladů
{
"Dashboard": "Nástěnka",
"Select language": "Vyberte jazyk",
"Czech": "Čeština",
...
}Výsledek


Tip
<?php
use Illuminate\Support\Facades\Route;
use Laravel\Jetstream\Http\Controllers\CurrentTeamController;
use Laravel\Jetstream\Http\Controllers\Livewire\ApiTokenController;
use Laravel\Jetstream\Http\Controllers\Livewire\PrivacyPolicyController;
use Laravel\Jetstream\Http\Controllers\Livewire\TeamController;
use Laravel\Jetstream\Http\Controllers\Livewire\TermsOfServiceController;
use Laravel\Jetstream\Http\Controllers\Livewire\UserProfileController;
use Laravel\Jetstream\Http\Controllers\TeamInvitationController;
use Laravel\Jetstream\Jetstream;
Route::get('lang/{lang}', [App\Http\Controllers\LanguageController::class, 'switchLang'])->name('langSwitcher');
Route::get('/', function () {
return redirect()->route('login');
});
Route::group([
'prefix' => "{language}",
'where' => ['language' => '[a-zA-Z]{2}']
], function () {
Route::group(['middleware' => config('jetstream.middleware', ['web'])], function () {
if (Jetstream::hasTermsAndPrivacyPolicyFeature()) {
Route::get('/terms-of-service', [TermsOfServiceController::class, 'show'])->name('terms.show');
Route::get('/privacy-policy', [PrivacyPolicyController::class, 'show'])->name('policy.show');
}
Route::group(['middleware' => ['auth:sanctum', 'verified']], function () {
Route::get('/user/profile', [UserProfileController::class, 'show'])
->name('profile.show');
if (Jetstream::hasApiFeatures()) {
Route::get('/user/api-tokens', [ApiTokenController::class, 'index'])->name('api-tokens.index');
}
if (Jetstream::hasTeamFeatures()) {
Route::get('/teams/create', [TeamController::class, 'create'])->name('teams.create');
Route::get('/teams/{team}', [TeamController::class, 'show'])->name('teams.show');
Route::put('/current-team', [CurrentTeamController::class, 'update'])->name('current-team.update');
Route::get('/team-invitations/{invitation}', [TeamInvitationController::class, 'accept'])
->middleware(['signed'])
->name('team-invitations.accept');
}
});
});
Route::group(['middleware' => ['auth:sanctum', 'verified']], function () {
Route::get('/dashboard', function () {
return view('dashboard');
})->name('dashboard');
});
});...
// Old value: /user/profile
Route::get('/profile', [UserProfileController::class, 'show'])->name('profile.show');
......
public function register()
{
Jetstream::ignoreRoutes();
}
...