问题
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