Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel change locale not working

Tags:

I am using a dropdown lists for the languages, consisting of english and dutch.

<form class="" action="{{url('/locale')}}" method="post">             Locale:               <select class="" name="locale" onchange="this.form.submit()">                  <option value="en" >English</option>                 <option value="du" >Dutch</option>               </select>           </form> 

Then this is my routes.php,

Route::post('/locale', function(){       \App::setLocale(Request::Input('locale'));       return redirect()->back(); }); 

And it is not working.

In my project, the path is like this

resources/  /du    navigation.php  /en   /navigation.php 

From the Dutch(du) 'navigation.php'

<?php return [   "home" => 'Home-test-dutch',   ]; 

and for the English(en) 'navigation.php'

<?php return [   "home" => 'Home',   ]; 
like image 630
Vahn Marty Avatar asked Dec 21 '16 15:12

Vahn Marty


People also ask

How do I change my locale in Laravel?

Laravel's gives you the option to change the locale for a single Http Request by executing the setLocale method on App Facade App::setLocale($locale); , But what if once the language is changed you don't want to worry about setting the Locale and this should be taken care by an automatic code logic.

How do I get Laravel locale?

To fetch current locale you should use App::getLocale() or App::isLocale('...') . Localization. You can also use app()->getLocale() which in Blade would be {{ app()->getLocale() }} .

What is @lang in Laravel?

Laravel-lang is a collection of over 68 language translations for Laravel by developer Fred Delrieu (caouecs), including authentication, pagination, passwords, and validation rules. This package also includes JSON files for many languages.


2 Answers

App::setLocale() is not persistent, and sets locale only for current request(runtime). You can achieve persistent in multiple ways (example of 2):

Route::post('/locale', function(){       session(['my_locale' => app('request')->input('locale')]);       return redirect()->back(); }); 

This will set session key with lang value from request for current user. Next create a Middleware to set locale based on user session language

<?php namespace App\Http\Middleware;  use Closure; use Illuminate\Http\Request; use Illuminate\Foundation\Application;  class Language {      public function __construct(Application $app, Request $request) {         $this->app = $app;         $this->request = $request;     }      /**      * Handle an incoming request.      *      * @param  \Illuminate\Http\Request  $request      * @param  \Closure  $next      * @return mixed      */     public function handle($request, Closure $next)     {         $this->app->setLocale(session('my_locale', config('app.locale')));                  return $next($request);     }  } 

This will get current session and if is empty will fallback to default locale, which is set in your app config.

In app\Http\Kernel.php add previously created Language middleware:

protected $middleware = [    \App\Http\Middleware\Language::class, ]; 

As global middlware or just for web (based on your needs). I hope this helps, and gives an idea on how things are working.

Scenario №2 - Lang based on URL path Create an array with all available locales on your app inside app config

'available_locale' => ['fr', 'gr', 'ja'], 

Inside the Middleware we will check the URL first segment en, fr, gr, cy if this segment is in available_locale, set language

public function handle($request, Closure $next) {       if(in_array($request->segment(1), config('app.available_locale'))){             $this->app->setLocale($request->segment(1));       }else{             $this->app->setLocale(config('app.locale'));       }                    return $next($request); } 

You will need to modify app\Providers\RouteServiceProvider for setting prefix to all your routes. so you can access them domain.com or domain.com/fr/ with French language Find: mapWebRoutes And add this to it: (before add use Illuminate\Http\Request;)

public function map(Request $request)     {         $this->mapApiRoutes();         $this->mapWebRoutes($request);     }     protected function mapWebRoutes(Request $request)     {         $locale = null;         if(in_array($request->segment(1), config('app.available_locale'))){           $locale = $request->segment(1);         }          Route::group([            'middleware' => 'web',            'namespace' => $this->namespace,            'prefix' => $locale         ], function ($router) {              require base_path('routes/web.php');         });     } 

This will prefix all your routes with country letter like 'fr gr cy' except en for non-duplicate content, so is better to not add into available_locales_array

like image 157
Froxz Avatar answered Oct 20 '22 08:10

Froxz


I solved my problem from this article https://mydnic.be/post/laravel-5-and-his-fcking-non-persistent-app-setlocale

Thanks to the people who contributed the word 'non persistent'

like image 43
Vahn Marty Avatar answered Oct 20 '22 08:10

Vahn Marty