Localização fácil do i18n para Laravel, uma ferramenta útil para combinar com classes de localização do Laravel.
O pacote oferece o seguinte:
Laravel | localização laravel |
---|---|
4.0.x | 0.13.x |
4.1.x | 0.13.x |
4.2.x | 0,15.x |
5.0.x/5.1.x | 1.0.x |
5.2.x-5.4.x (PHP 7 não é necessário) | 1.2. |
5.2.0-6.x (versão PHP >= 7 necessária) | 1.4.x |
6.x-10.x (versão PHP >= 7 necessária) | 1.8.x |
10.x-11.x (versão PHP >= 8.2 necessária) | 2.0.x |
Instale o pacote via compositor: composer require mcamara/laravel-localization
Para Laravel 5.4 e anteriores é necessário registrar o provedor de serviços.
Para editar a configuração padrão você pode executar:
php artisan vendor:publish --provider="McamaraLaravelLocalizationLaravelLocalizationServiceProvider"
Depois disso, config/laravellocalization.php
será criado.
As opções de configuração são:
Você pode registrar o middleware do pacote no arquivo 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
];
}
Se você estiver usando Laravel 11, você pode se registrar no arquivo bootstrap/app.php
no encerramento 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,
]);
})
Adicione o seguinte ao seu arquivo de rotas:
// 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 **/
Depois que esse grupo de rotas for adicionado ao arquivo de rotas, um usuário poderá acessar todas as localidades adicionadas em supportedLocales
( en
e es
por padrão). Por exemplo, o arquivo de rota acima cria os seguintes endereços:
// 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
O pacote define a localidade do seu aplicativo App::getLocale()
de acordo com sua URL. O locale pode então ser usado para os recursos de localização do Laravel.
Você pode adicionar middleware ao seu grupo assim:
Route:: group (
[
' prefix ' => LaravelLocalization:: setLocale (),
' middleware ' => [ ' localeSessionRedirect ' , ' localizationRedirect ' , ' localeViewPath ' ]
], function (){ //...
});
1 .: É altamente recomendável usar um middleware de redirecionamento. URLs sem localidade devem ser usados apenas para determinar a localidade padrão/do navegador e para redirecionar para a URL localizada. Caso contrário, quando os robôs dos mecanismos de pesquisa rastreiam, por exemplo, http://url-to-laravel/test
eles podem obter conteúdo em idiomas diferentes para cada visita. Além disso, ter vários URLs para o mesmo conteúdo cria um problema de conteúdo duplicado de SEO.
2 .: É altamente recomendável localizar seus links, mesmo se você usar um middleware de redirecionamento. Caso contrário, você causará pelo menos um redirecionamento cada vez que um usuário clicar em um link. Além disso, qualquer url de ação de um formulário de postagem deve ser localizado, para evitar que seja redirecionado para uma solicitação get.
O seguinte middleware de redirecionamento depende das configurações de hideDefaultLocaleInURL
e useAcceptLanguageHeader
em config/laravellocalization.php
:
Sempre que um código de idioma estiver presente na url, ele será armazenado na sessão por este middleware.
Se não houver nenhuma localidade presente na URL, este middleware verificará o seguinte
useAcceptLanguageHeader
estiver definido como verdadeiro, calcule a localidade do navegador e redirecione para url com localidade.hideDefaultLocaleInURL
esteja definido como verdadeiro. Por exemplo, se um usuário navegar para http://url-to-laravel/test e en
for o local atual, ele será redirecionado automaticamente para http://url-to-laravel/en/test.
Semelhante ao LocaleSessionRedirect, mas armazena valor em um cookie em vez de em uma sessão.
Sempre que um código de idioma estiver presente na URL, ele será armazenado no cookie por este middleware.
Se não houver localidade presente no URL, este middleware verificará o seguinte
useAcceptLanguageHeader
estiver definido como verdadeiro, calcule a localidade do navegador e redirecione para o url com localidade.hideDefaultLocaleInURL
esteja definido como verdadeiro. Por exemplo, se um usuário navegar para http://url-to-laravel/test e de
for o código do idioma atual, ele será redirecionado automaticamente para http://url-to-laravel/de/test.
Quando o código de idioma padrão está presente no URL e hideDefaultLocaleInURL
está definido como verdadeiro, o middleware redireciona para o URL sem código de idioma.
Por exemplo, se es
for o local padrão, então http://url-to-laravel/es/test seria redirecionado para http://url-to-laravel/test e App::getLocale()
seria definido dedos do es
.
Este pacote vem com vários ajudantes.
URLS localizados levam em consideração a ligação do modelo de rota ao gerar a rota localizada, bem como as configurações hideDefaultLocaleInURL
e Rotas traduzidas.
// If current locale is Spanish, it returns `/es/test`
<a href="{{ LaravelLocalization:: localizeUrl ( ' /test ' ) }}">@ lang ( ' Follow this link ' )</a>
Obtenha o URL atual em uma localidade específica:
// Returns current url with English locale.
{{ LaravelLocalization:: getLocalizedURL ( ' en ' ) }}
Retorna uma URL sem qualquer localização.
// Returns /about
{{ LaravelLocalization:: getNonLocalizedURL ( ' /es/about ' ) }}
Retorna uma rota, localizada no local desejado. Se a chave de tradução não existir na localidade fornecida, esta função retornará falso.
// Returns /es/acerca
{{ LaravelLocalization:: getURLFromRouteNameTranslated ( ' es ' , ' routes.about ' ) }}
Exemplo de link localizado usando rotas com atributos
// 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>
Retorne todas as localidades suportadas e suas propriedades como uma matriz.
{{ LaravelLocalization:: getSupportedLocales () }}
Retorne todas as localidades suportadas, mas na ordem especificada no arquivo de configuração. Você pode usar esta função para imprimir localidades no seletor de idioma.
{{ LaravelLocalization:: getLocalesOrder () }}
Retorna uma matriz com todas as chaves das localidades suportadas.
{{ LaravelLocalization:: getSupportedLanguagesKeys () }}
Retorne a chave da localidade atual.
{{ LaravelLocalization:: getCurrentLocale () }}
Retorna o nome do local atual como string (inglês/espanhol/árabe/..etc).
{{ LaravelLocalization:: getCurrentLocaleName () }}
Retorna o nome nativo do local atual como string (English/Español/عربى/ ..etc).
{{ LaravelLocalization:: getCurrentLocaleNative () }}
Retorne o nome regional da localidade atual como string (en_GB/en_US/fr_FR/ ..etc).
{{ LaravelLocalization:: getCurrentLocaleRegional () }}
Retorna a direção da localidade atual como string (ltr/rtl).
{{ LaravelLocalization:: getCurrentLocaleDirection () }}
Retorne o código ISO 15924 do script de localidade atual como uma string; "Latn", "Cyrl", "Árabe", etc.
{{ LaravelLocalization:: getCurrentLocaleScript () }}
Registre o middleware LaravelLocalizationViewPath
para definir o local atual como view-base-path.
Agora você pode agrupar suas visualizações em pastas baseadas em idiomas, como os arquivos de tradução.
recursos resources/views/en/
, resources/views/fr
, ...
Como você pode modificar os SupportLocales mesmo renomeando suas chaves, é possível usar a string uk
em vez de en-GB
para fornecer segmentos de URL de idioma personalizados. Obviamente, você precisa evitar colisões com chaves já existentes e seguir a convenção pelo maior tempo possível. Mas se você estiver usando essa chave personalizada, será necessário armazenar seu mapeamento no array localesMapping
. Este localesMapping
é necessário para permitir que o LanguageNegotiator atribua corretamente as localidades desejadas com base no HTTP Accept Language Header. Aqui está um exemplo rápido de como mapear o cabeçalho de idioma de aceitação HTTP 'en-GB' para o segmento de URL 'uk':
// config/laravellocalization.php
' localesMapping ' => [
' en-GB ' => ' uk '
],
Depois disso http://url-to-laravel/en-GB/a/b/c
torna-se 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
Se você oferece suporte a vários locais em seu projeto, provavelmente desejará fornecer aos usuários uma maneira de alterar o idioma. Abaixo está um exemplo simples de código de modelo de blade que você pode usar para criar seu próprio seletor de idioma.
< 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 >
Aqui, o idioma padrão será forçado em getLocalizedURL() a estar presente na URL, mesmo hideDefaultLocaleInURL = true
.
Observe que há suporte para associação de modelo de rota.
Você pode traduzir suas rotas. Por exemplo, http://url/en/about e http://url/es/acerca (acerca é about em espanhol) ou http://url/en/article/important-article e http://url/ es/articulo/important-article (o artigo é articulo em espanhol) seria redirecionado para o mesmo controlador/visualização da seguinte forma:
É necessário que pelo menos o middleware localize
esteja carregado em seu middleware Route::group
(Ver instruções de instalação).
Para cada idioma, adicione um routes.php
na pasta resources/lang/**/routes.php
. O arquivo contém um array com todas as rotas traduzíveis. Por exemplo, assim:
Lembre-se: a partir do Laravel 9, a pasta
resources/lang
agora está localizada na pasta raiz do projeto (lang
). Se o seu projeto tiver a pastalang
na raiz, você deve adicionar umroutes.php
na pastalang/**/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} " ,
];
Você pode adicionar as rotas em routes/web.php
assim:
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 ;
});
//,...
});
Uma vez salvos os arquivos, você pode acessar http://url/en/about , http://url/es/acerca , http://url/en/article/important-article e http://url/es/ articulo/artigo-importante sem nenhum problema.
Talvez você tenha notado no exemplo anterior o slug em inglês na url em espanhol:
http://url/es/articulo/important-article
É possível traduzir slugs, por exemplo assim:
http://url/en/article/important-change
http://url/es/articulo/cambio-importante
Porém, para fazer isso, cada artigo deve ter muitos slugs (um para cada localidade). Depende de você como deseja implementar essa relação. O único requisito para parâmetros de rota traduzíveis é que o modelo relevante implemente a interface LocalizedUrlRoutable
.
Para implementar McamaraLaravelLocalizationInterfacesLocalizedUrlRoutable
, é necessário criar a função getLocalizedRouteKey($locale)
, que deve retornar para um determinado local o slug traduzido. No exemplo acima, dentro do artigo do modelo, getLocalizedRouteKey('en')
deve retornar important-change
e getLocalizedRouteKey('es')
deve retornar cambio-importante
.
Para usar a ligação do modelo de rota, deve-se sobrescrever a função resolveRouteBinding($slug)
no modelo. A função deve retornar o modelo que pertence ao slug traduzido $slug
. Por exemplo:
public function resolveRouteBinding ( $ slug )
{
return static :: findByLocalizedSlug ( $ slug )-> first () ?? abort ( 404 );
}
Você pode conferir este vídeo que demonstra como configurar parâmetros de rota traduzíveis.
Você pode capturar os parâmetros de URL durante a tradução se desejar traduzi-los também. Para fazer isso, basta criar um ouvinte de evento para o evento routes.translation
assim:
Event:: listen ( ' routes.translation ' , function ( $ locale , $ attributes )
{
// Do your magic
return $ attributes ;
});
Certifique-se de passar o código do idioma e os atributos como parâmetros para o fechamento. Você também pode usar Event Subscribers, consulte: http://laravel.com/docs/events#event-subscribers
Para armazenar em cache suas rotas, use:
php artisan route:trans:cache
... em vez do comando normal route:cache
. Usar artisan route:cache
não funcionará corretamente!
Para que a solução de cache de rotas funcione, é necessário fazer um pequeno ajuste no fornecimento de rotas do seu aplicativo.
antes do laravel 11
No RouteServiceProvider
do seu aplicativo, use o atributo LoadsTranslatedCachedRoutes
:
<?php
class RouteServiceProvider extends ServiceProvider
{
use Mcamara LaravelLocalization Traits LoadsTranslatedCachedRoutes;
depois do laravel 11
No AppServiceProvider
do seu App, use a classe CachedTranslatedRouteLoader
no método Register:
<?php
class AppServiceProvider extends ServiceProvider
{
use Mcamara LaravelLocalization Traits LoadsTranslatedCachedRoutes;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
RouteServiceProvider:: loadCachedRoutesUsing ( fn () => $ this -> loadCachedRoutes ());
. . .
}
Para mais detalhes veja aqui.
Isso pode acontecer se você não localizar sua rota de ação que está dentro de seu Routes::group
. Isso pode causar um redirecionamento, que então transforma a solicitação post em uma solicitação get. Para evitar isso, basta usar o auxiliar de localização.
Por exemplo, se você usar Auth::routes()
e colocá-los em seu Route::group
Então
<form action="/logout" method="POST">
<button>Logout</button>
</form>
não funcionará. Em vez disso, é preciso usar
<form action ="{{ LaravelLocalization:: localizeURL ( ' /logout ' ) }} " method= " POST ">
<button>Logout</button>
</form>
Outra maneira de resolver isso é colocar o método http para configurar em 'laravellocalization.httpMethodsIgnored' para evitar o processamento deste tipo de solicitações
Se você não localizar o URL da postagem e usar um middleware de redirecionamento, a solicitação de postagem será redirecionada como uma solicitação get. Se você não definiu essa rota get, causará esta exceção.
Para localizar o URL da sua postagem, veja o exemplo em POST não está funcionando.
Isso também acontece se você não localizou o URL da postagem. Se você não localizar o URL da postagem, a localidade padrão será definida durante a validação e, ao retornar para back()
mostrará a mensagem de validação na localidade padrão.
Para localizar o URL da sua postagem, veja o exemplo em POST não está funcionando.
Durante a configuração do teste, a rota chamada ainda não é conhecida. Isso significa que nenhum idioma pode ser definido. Quando uma solicitação é feita durante um teste, isso resulta em 404 - sem o prefixo definido, a rota localizada parece não existir.
Para corrigir isso, você pode usar esta função para definir manualmente o prefixo do idioma:
// 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
}
Pergunte ao mcamara se você quer ser um deles!
Veja o changelog aqui -> changelog
Laravel Localization é um pacote laravel de código aberto licenciado sob a licença MIT