Простая локализация i18n для Laravel, полезный инструмент для объединения с классами локализации Laravel.
Пакет предлагает следующее:
Ларавел | laravel-локализация |
---|---|
4.0.х | 0.13.х |
4.1.х | 0.13.х |
4.2.х | 0.15.x |
5.0.х/5.1.х | 1.0.х |
5.2.x-5.4.x (PHP 7 не требуется) | 1.2. |
5.2.0-6.x (требуется версия PHP >= 7) | 1.4.х |
6.x-10.x (требуется версия PHP >= 7) | 1.8.х |
10.x-11.x (требуется версия PHP >= 8.2) | 2.0.х |
Установите пакет через композитор: composer require mcamara/laravel-localization
Для Laravel 5.4 и ниже необходимо зарегистрировать поставщика услуг.
Чтобы отредактировать конфигурацию по умолчанию, вы можете выполнить:
php artisan vendor:publish --provider="McamaraLaravelLocalizationLaravelLocalizationServiceProvider"
После этого будет создан config/laravellocalization.php
.
Варианты конфигурации:
Вы можете зарегистрировать промежуточное программное обеспечение пакета в файле app/Http/Kernel.php
:
<?php namespace App Http ;
use Illuminate Foundation Http Kernel as HttpKernel ;
class Kernel extends HttpKernel {
/**
* The application's route middleware.
*
* @var array
*/
protected $ middlewareAliases = [
/**** OTHER MIDDLEWARE ****/
' localize ' => Mcamara LaravelLocalization Middleware LaravelLocalizationRoutes::class,
' localizationRedirect ' => Mcamara LaravelLocalization Middleware LaravelLocalizationRedirectFilter::class,
' localeSessionRedirect ' => Mcamara LaravelLocalization Middleware LocaleSessionRedirect::class,
' localeCookieRedirect ' => Mcamara LaravelLocalization Middleware LocaleCookieRedirect::class,
' localeViewPath ' => Mcamara LaravelLocalization Middleware LaravelLocalizationViewPath::class
];
}
Если вы используете Laravel 11, вы можете зарегистрироваться в файле bootstrap/app.php
в конце withMiddleware
:
return Application:: configure (basePath: dirname ( __DIR__ ))
// Other application configurations
-> withMiddleware ( function ( Middleware $ middleware ) {
$ middleware -> alias ([
/**** OTHER MIDDLEWARE ALIASES ****/
' localize ' => Mcamara LaravelLocalization Middleware LaravelLocalizationRoutes::class,
' localizationRedirect ' => Mcamara LaravelLocalization Middleware LaravelLocalizationRedirectFilter::class,
' localeSessionRedirect ' => Mcamara LaravelLocalization Middleware LocaleSessionRedirect::class,
' localeCookieRedirect ' => Mcamara LaravelLocalization Middleware LocaleCookieRedirect::class,
' localeViewPath ' => Mcamara LaravelLocalization Middleware LaravelLocalizationViewPath::class,
]);
})
Добавьте в файл маршрутов следующее:
// routes/web.php
Route:: group ([ ' prefix ' => LaravelLocalization:: setLocale ()], function ()
{
/** ADD ALL LOCALIZED ROUTES INSIDE THIS GROUP **/
Route:: get ( ' / ' , function ()
{
return View:: make ( ' hello ' );
});
Route:: get ( ' test ' , function (){
return View:: make ( ' test ' );
});
});
/** OTHER PAGES THAT SHOULD NOT BE LOCALIZED **/
Как только эта группа маршрутов будет добавлена в файл маршрутов, пользователь сможет получить доступ ко всем языковым стандартам, добавленным в supportedLocales
(по умолчанию en
и es
). Например, приведенный выше файл маршрута создает следующие адреса:
// Set application language to English
http://url-to-laravel/en
http://url-to-laravel/en/test
// Set application language to Spanish
http://url-to-laravel/es
http://url-to-laravel/es/test
// Set application language to English or Spanish (depending on browsers default locales)
// if nothing found set to default locale
http://url-to-laravel
http://url-to-laravel/test
Пакет устанавливает локаль вашего приложения App::getLocale()
в соответствии с вашим URL-адресом. Затем локаль можно использовать для функций локализации Laravel.
Вы можете добавить промежуточное программное обеспечение в свою группу следующим образом:
Route:: group (
[
' prefix ' => LaravelLocalization:: setLocale (),
' middleware ' => [ ' localeSessionRedirect ' , ' localizationRedirect ' , ' localeViewPath ' ]
], function (){ //...
});
1. : Настоятельно рекомендуется использовать промежуточное ПО для перенаправления. URL-адреса без локали следует использовать только для определения локали браузера/языка по умолчанию и для перенаправления на локализованный URL-адрес. В противном случае, когда роботы поисковых систем сканируют, например, http://url-to-laravel/test
они могут получать контент на разных языках при каждом посещении. Кроме того, наличие нескольких URL-адресов для одного и того же контента создает проблему дублирования контента для SEO.
2. : Настоятельно рекомендуется локализовать ссылки, даже если вы используете промежуточное программное обеспечение для перенаправления. В противном случае вы будете вызывать как минимум одно перенаправление каждый раз, когда пользователь нажимает на ссылку. Кроме того, любой URL-адрес действия из формы публикации должен быть локализован, чтобы предотвратить его перенаправление на запрос получения.
Следующее промежуточное программное обеспечение перенаправления зависит от hideDefaultLocaleInURL
и useAcceptLanguageHeader
в config/laravellocalization.php
:
Всякий раз, когда локаль присутствует в URL-адресе, она будет сохранена в сеансе этим промежуточным программным обеспечением.
Если в URL-адресе нет локали, это промежуточное программное обеспечение проверит следующее
useAcceptLanguageHeader
установлено значение true, вычислите локаль из браузера и перенаправьте на URL-адрес с локалью.hideDefaultLocaleInURL
установлено значение true. Например, если пользователь перейдет по адресу http://url-to-laravel/test, а текущим языковым стандартом будет en
, он автоматически перенаправится на http://url-to-laravel/en/test.
Похож на LocaleSessionRedirect, но сохраняет значение в файле cookie, а не в сеансе.
Всякий раз, когда локаль присутствует в URL-адресе, она сохраняется в файле cookie этим промежуточным программным обеспечением.
Если в URL-адресе нет локали, это промежуточное программное обеспечение проверит следующее
useAcceptLanguageHeader
установлено значение true, вычислите языковой стандарт из браузера и перенаправьте на URL-адрес с языковым стандартом.hideDefaultLocaleInURL
установлено значение true. Например, если пользователь перейдет по адресу http://url-to-laravel/test, а текущая локаль de
, он автоматически перенаправится на http://url-to-laravel/de/test.
Если в URL-адресе присутствует локаль по умолчанию, а для hideDefaultLocaleInURL
установлено значение true, промежуточное программное обеспечение перенаправляет на URL-адрес без локали.
Например, если es
является локалью по умолчанию, то http://url-to-laravel/es/test будет перенаправлен на http://url-to-laravel/test и будет установлен App::getLocale()
es
.
В этот пакет входит множество помощников.
Локализованные URL-адреса учитывают привязку модели маршрута при создании локализованного маршрута, а также настройки hideDefaultLocaleInURL
и Translated Routes.
// If current locale is Spanish, it returns `/es/test`
<a href="{{ LaravelLocalization:: localizeUrl ( ' /test ' ) }}">@ lang ( ' Follow this link ' )</a>
Получить текущий URL-адрес в определенной локали:
// Returns current url with English locale.
{{ LaravelLocalization:: getLocalizedURL ( ' en ' ) }}
Возвращает URL-адрес без какой-либо локализации.
// Returns /about
{{ LaravelLocalization:: getNonLocalizedURL ( ' /es/about ' ) }}
Возвращает маршрут, локализованный для нужной локали. Если ключ перевода не существует в указанной локали, эта функция вернет false.
// Returns /es/acerca
{{ LaravelLocalization:: getURLFromRouteNameTranslated ( ' es ' , ' routes.about ' ) }}
Пример локализованной ссылки с использованием маршрутов с атрибутами
// An array of attributes can be provided.
// Returns /en/archive/ghosts, /fr/archive/fantômes, /pt/arquivo/fantasmas, etc.
<a href="{{ LaravelLocalization:: getURLFromRouteNameTranslated ( App:: currentLocale (), ' routes.archive ' , array ( ' category ' => ' ghosts ' )) }}">Ghost Stories</a>
Верните все поддерживаемые локали и их свойства в виде массива.
{{ LaravelLocalization:: getSupportedLocales () }}
Возвращает все поддерживаемые локали, но в порядке, указанном в файле конфигурации. Эту функцию можно использовать для печати локалей в средстве выбора языка.
{{ LaravelLocalization:: getLocalesOrder () }}
Верните массив со всеми ключами для поддерживаемых локалей.
{{ LaravelLocalization:: getSupportedLanguagesKeys () }}
Вернуть ключ текущей локали.
{{ LaravelLocalization:: getCurrentLocale () }}
Вернуть имя текущей локали в виде строки (английский/испанский/арабский/..и т. д.).
{{ LaravelLocalization:: getCurrentLocaleName () }}
Возвращает собственное имя текущей локали в виде строки (английский/испанский/عربى/ ..etc).
{{ LaravelLocalization:: getCurrentLocaleNative () }}
Возвращает региональное имя текущей локали в виде строки (en_GB/en_US/fr_FR/ ..etc).
{{ LaravelLocalization:: getCurrentLocaleRegional () }}
Возвращает направление текущей локали в виде строки (ltr/rtl).
{{ LaravelLocalization:: getCurrentLocaleDirection () }}
Верните код ISO 15924 для текущего сценария локали в виде строки; «Латн», «Кирл», «Араб» и др.
{{ LaravelLocalization:: getCurrentLocaleScript () }}
Зарегистрируйте промежуточное программное обеспечение LaravelLocalizationViewPath
чтобы установить текущий языковой стандарт как путь к базовому представлению.
Теперь вы можете помещать свои представления в папки на основе языка, например файлы перевода.
resources/views/en/
, resources/views/fr
, ...
Поскольку вы можете изменять поддерживаемые локали, даже переименовывая их ключи, можно использовать строку uk
вместо en-GB
для предоставления пользовательских сегментов URL-адресов на языке. Конечно, вам необходимо предотвратить любые конфликты с уже существующими ключами и придерживаться соглашения как можно дольше. Но если вы используете такой пользовательский ключ, вам придется сохранить свое сопоставление в массиве localesMapping
. Это localesMapping
необходимо, чтобы LanguageNegotiator мог правильно назначить нужные локали на основе заголовка HTTP Accept Language. Вот краткий пример того, как сопоставить заголовок языка HTTP Accept «en-GB» с сегментом URL «uk»:
// config/laravellocalization.php
' localesMapping ' => [
' en-GB ' => ' uk '
],
После этого http://url-to-laravel/en-GB/a/b/c
станет http://url-to-laravel/uk/a/b/c
.
LaravelLocalization:: getLocalizedURL ( ' en-GB ' , ' a/b/c ' ); // http://url-to-laravel/uk/a/b/c
LaravelLocalization:: getLocalizedURL ( ' uk ' , ' a/b/c ' ); // http://url-to-laravel/uk/a/b/c
Если вы поддерживаете несколько локалей в своем проекте, вам, вероятно, захочется предоставить пользователям возможность менять язык. Ниже приведен простой пример кода шаблона блейда, который можно использовать для создания собственного средства выбора языка.
< ul >
@foreach ( LaravelLocalization :: getSupportedLocales () as $localeCode => $properties )
< li >
< a rel = " alternate " hreflang = " {{ $localeCode } } " href = " {{ LaravelLocalization :: getLocalizedURL ( $localeCode , null , [], true ) } } " >
{{ $properties [ ' native ' ] } }
</ a >
</ li >
@endforeach
</ ul >
Здесь язык по умолчанию будет принудительно присутствовать в getLocalizedURL() в URL-адресе, даже hideDefaultLocaleInURL = true
.
Обратите внимание, что привязка модели маршрута поддерживается.
Вы можете перевести свои маршруты. Например, http://url/en/about и http://url/es/acerca (acerca по-испански означает «about») или http://url/en/article/important-article и http://url/ es/articulo/important-article (статья на испанском языке — articulo) будет перенаправлена на тот же контроллер/представление следующим образом:
Необходимо, чтобы в вашем промежуточном программном обеспечении Route::group
было загружено как минимум localize
промежуточное программное обеспечение (см. инструкцию по установке).
Для каждого языка добавьте файл routes.php
в папку resources/lang/**/routes.php
. Файл содержит массив со всеми переводимыми маршрутами. Например, вот так:
Имейте в виду: начиная с Laravel 9, папка
resources/lang
теперь находится в корневой папке проекта (lang
). Если ваш проект имеет папкуlang
в корне, вы должны добавить файлroutes.php
в папкуlang/**/routes.php
.
<?php
// resources/lang/en/routes.php
return [
" about " => " about " ,
" article " => " article/{article} " ,
];
<?php
// resources/lang/es/routes.php
return [
" about " => " acerca " ,
" article " => " articulo/{article} " ,
];
Вы можете добавить маршруты в routes/web.php
следующим образом:
Route:: group ([ ' prefix ' => LaravelLocalization:: setLocale (),
' middleware ' => [ ' localize ' ]], function () {
Route:: get (LaravelLocalization:: transRoute ( ' routes.about ' ), function () {
return view ( ' about ' );
});
Route:: get (LaravelLocalization:: transRoute ( ' routes.article ' ), function ( App Article $ article ) {
return $ article ;
});
//,...
});
После сохранения файлов вы сможете получить доступ к http://url/en/about, http://url/es/acerca, http://url/en/article/important-article и http://url/es/. articulo/важная статья без проблем.
Возможно, в предыдущем примере вы заметили английскую фразу в испанском URL:
http://url/es/articulo/important-article
Можно перевести слизни, например так:
http://url/en/article/important-change
http://url/es/articulo/cambio-importante
Однако для этого каждая статья должна иметь множество ярлыков (по одному для каждой локали). Вам решать, как вы хотите реализовать это отношение. Единственное требование для переводимых параметров маршрута — чтобы соответствующая модель реализовывала интерфейс LocalizedUrlRoutable
.
Чтобы реализовать McamaraLaravelLocalizationInterfacesLocalizedUrlRoutable
, необходимо создать функцию getLocalizedRouteKey($locale)
, которая должна возвращать для данной локали переведенный фрагмент. В приведенном выше примере внутри статьи модели getLocalizedRouteKey('en')
должен возвращать important-change
, а getLocalizedRouteKey('es')
должен возвращать cambio-importante
.
Чтобы использовать привязку модели маршрута, необходимо перезаписать resolveRouteBinding($slug)
в модели. Функция должна возвращать модель, принадлежащую переведенному пулу $slug
. Например:
public function resolveRouteBinding ( $ slug )
{
return static :: findByLocalizedSlug ( $ slug )-> first () ?? abort ( 404 );
}
Возможно, вы захотите посмотреть это видео, которое демонстрирует, как можно настроить переводимые параметры маршрута.
Вы можете записать параметры URL-адреса во время перевода, если хотите перевести и их. Для этого просто создайте прослушиватель событий routes.translation
следующим образом:
Event:: listen ( ' routes.translation ' , function ( $ locale , $ attributes )
{
// Do your magic
return $ attributes ;
});
Обязательно передайте локаль и атрибуты в качестве параметров замыканию. Вы также можете использовать подписчиков на события, см.: http://laravel.com/docs/events#event-subscribers.
Для кэширования ваших маршрутов используйте:
php artisan route:trans:cache
... вместо обычной команды route:cache
. Использование artisan route:cache
будет работать неправильно !
Чтобы решение для кэширования маршрутов работало, необходимо внести незначительные изменения в предоставление маршрута вашего приложения.
до Ларавел 11
В RouteServiceProvider
вашего приложения используйте признак LoadsTranslatedCachedRoutes
:
<?php
class RouteServiceProvider extends ServiceProvider
{
use Mcamara LaravelLocalization Traits LoadsTranslatedCachedRoutes;
после ларавеля 11
В AppServiceProvider
вашего приложения используйте класс CachedTranslatedRouteLoader
в методе регистрации:
<?php
class AppServiceProvider extends ServiceProvider
{
use Mcamara LaravelLocalization Traits LoadsTranslatedCachedRoutes;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
RouteServiceProvider:: loadCachedRoutesUsing ( fn () => $ this -> loadCachedRoutes ());
. . .
}
Более подробную информацию смотрите здесь.
Это может произойти, если вы не локализуете свой маршрут действия, который находится внутри вашей Routes::group
. Это может вызвать перенаправление, которое затем изменит запрос на отправку на запрос на получение. Чтобы предотвратить это, просто используйте помощник локализации.
Например, если вы используете Auth::routes()
и поместите их в свою Route::group
Тогда
<form action="/logout" method="POST">
<button>Logout</button>
</form>
не будет работать. Вместо этого нужно использовать
<form action ="{{ LaravelLocalization:: localizeURL ( ' /logout ' ) }} " method= " POST ">
<button>Logout</button>
</form>
Другой способ решить эту проблему — добавить метод http в конфигурацию «laravellocalization.httpMethodsIgnored», чтобы предотвратить обработку запросов этого типа.
Если вы не локализуете URL-адрес публикации и используете промежуточное программное обеспечение для перенаправления, запрос на публикацию будет перенаправлен как запрос на получение. Если вы не определили такой маршрут получения, вы вызовете это исключение.
Чтобы локализовать URL-адрес публикации, см. пример в разделе POST не работает.
Это также происходит, если вы не локализовали URL-адрес публикации. Если вы не локализуете URL-адрес публикации, во время проверки устанавливается локаль по умолчанию, а при возврате к back()
отображается сообщение проверки на локали по умолчанию.
Чтобы локализовать URL-адрес публикации, см. пример в разделе POST не работает.
Во время тестовой настройки вызываемый маршрут еще не известен. Это означает, что язык не может быть установлен. Когда запрос делается во время теста, это приводит к ошибке 404 — без установленного префикса локализованный маршрут не существует.
Чтобы это исправить, вы можете использовать эту функцию для ручной установки префикса языка:
// TestCase.php
protected function refreshApplicationWithLocale ( $ locale )
{
self :: tearDown ();
putenv (LaravelLocalization:: ENV_ROUTE_KEY . ' = ' . $ locale );
self :: setUp ();
}
protected function tearDown (): void
{
putenv (LaravelLocalization:: ENV_ROUTE_KEY );
parent :: tearDown ();
}
// YourTest.php
public function testBasicTest ()
{
$ this -> refreshApplicationWithLocale ( ' en ' );
// Testing code
}
Спросите Макамару, хотите ли вы быть одним из них!
Посмотреть список изменений здесь -> журнал изменений
Laravel Localization — это пакет Laravel с открытым исходным кодом, лицензированный по лицензии MIT.