Laravel - Change locale using Ajax

巧了我就是萌 提交于 2020-01-11 12:27:17

问题


I am trying to change the language of my system using ajax but I don't know how to change the locale and make it permanent until the user decides to change again. Currently, the locale in the app.php is set to 'en' and I want to change it to 'nl' using a select menu. I tried using App::setLocale($value) but that does not do anything, unfortunately. How can I accomplish this?

Form

<form method="POST" action="{{ route('change_language',['id' => Auth::user()->id]) }}" class="form-row my-3">
  {{ csrf_field() }}
  {{ method_field('PATCH') }}
  <div class="form-group col-9">
     <h4 class="mb-0">{{ __('Language') }}</h4>
     <p class="m-0 sub-text">{{ __('Change the language of the dashboard') }}</p>
  </div>
  <div class="form-group col-3 d-flex justify-content-end align-items-center">
    <select name="language" id="language" class="form-control">
       <option value="nl" {{ ( Auth::user()->language == 'nl') ? 'selected' : '' }}>{{ __('Dutch') }}</option>
        <option value="en" {{ ( Auth::user()->language == 'en') ? 'selected' : '' }}>{{ __('English') }}</option>
    </select>
  </div>
  <div class="col-md-12 text-right">
    <p class="text-success saved-message" style="display: none">{{ __('The language has changed!') }}</p>
  </div>
</form>

AJAX

$('#language').change(function() {
  $.ajax({
    headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
    url: '{{ route('change_language', ['id' => Auth::user()->id]) }}',
    type: 'PATCH',
    data: {"language": $(this).children("option:selected").val()},
    success: function(data) {
             $('.saved-message').fadeIn();
                setTimeout(function() {
                   $('.saved-message').fadeOut();
                }, 1000);
           }
      })
});

Route

Route::patch('/dashboard/user/{id}/language', 'PreferencesController@changeLanguage')->name('change_language');

Controller method

public function changeLanguage(Request $request, $id)
    {
        $user = User::findOrFail($id);

        $user->language = $request->get('language');
        $user->save();

        App::setLocale($request->language);
    }

回答1:


You must have some kind of middleware because session (language) is not persistent. You can try something like this (Language Middleware):

public function handle($request, Closure $next)
    {
        if (auth()->check()) {
            $language = auth()->user()->language;
            if (empty($language)) {
                $language = config('app.fallback_locale');
            }
            app()->setLocale($language);
            Session::put('applocale', $language);
            auth()->user()->language = $language;
            auth()->user()->save();
            return $next($request);
        }
        if (Session::has('applocale')) {
            app()->setLocale(Session::get('applocale'));
        } else {
            app()->setLocale(config('app.fallback_locale'));
            Session::put('applocale', config('app.fallback_locale'));
        }
        return $next($request);
    }

as you can see I store language per user in db. In controller you could have something like this:


        if (auth()->check()) {
            auth()->user()->language = $language;
            auth()->user()->save();
            return back();
        } 
            Session::put('applocale', $language);
            return back();
        }

try consider something like this




回答2:


You haven't described any error but probably you are not familiar how locale works in Laravel. Locale is set per requets. So if you set locale in this controller method (assuming it's working fine) when you visit site then locale will be again same as set in configuration file.

To solve this AppServiceProvider in boot method you could add code like this:

if ($user = auth()->user()) {
    App::setLocale($user->language);
}

This way, when user is logged and locale is saved in his profile each time he visit site (assuming he is logged) he will see site in valid locale. Of course it does not solve the issue when user is not logged. For such case you might want to create additional cookie for user to set locale from cookie in case user is not logged.




回答3:


You need middleware to persist the localization

class Language
{
    protected $app;

    public function __construct(Application $app, Request $request) {
        $this->app = $app;
    }

    public function handle($request, Closure $next)
    {
        $this->app->setLocale(session('user_locale', config('app.locale')));

        return $next($request);
    }
}

And this middleware should work on every route:

protected $middlewareGroups = [
        'web' => [
              // ...
              \App\Http\Middleware\Language::class,
        ]
];


来源:https://stackoverflow.com/questions/59584454/laravel-change-locale-using-ajax

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!