laravel-localized-routes icon indicating copy to clipboard operation
laravel-localized-routes copied to clipboard

Remembering preferred locale when `omit_url_prefix_for_locale` is not null

Open Yiddishe-Kop opened this issue 3 years ago • 4 comments

Thanks for this awesome package! 👍

I'm trying to figure this out for a long time...

I have 2 locales, ['en', 'he']. I set omit_url_prefix_for_locale to 'en', so the en locale is unprefixed. But now whenever someone visits the default url, the locale is changed back to the default locale.

Is it possible to redirect to the previously chosen url (using the cookie/session/browser)? In other words, if I switch to he, then a day later visit the default url, I should be redirected to the he locale.

Yiddishe-Kop avatar May 11 '21 13:05 Yiddishe-Kop

Hi,

That was a brain cracker :) What you're asking is currently not supported by the package. If I understand it right, you need a middleware that runs before the SetLocale middleware that does the following:

  • If $request->route()->getAction('localized-routes-locale') is the omitted locale
  • and the user has no active session locale
  • and the user has a cookie locale
  • and the cookie locale does not match the $request->route()->getAction('localized-routes-locale')
  • then redirect to the localized route

Don't forget to set the use_localizer config to true and to add the middleware to your default route. This will store a cookie, etc.

To see how the locale is detected and set, check the localizer package: https://github.com/codezero-be/laravel-localizer

I will keep this open to see if I can add this as an option and improve the SetLocale middleware. But this will be at later time.

Let me know if you have any problems with this, I'd be happy to help!

ivanvermeyen avatar May 11 '21 17:05 ivanvermeyen

Thanks for pointing me in the right direction!

and the user has no active session locale

But when the session locale is set I'll always get changed to the default locale.

My final middleware code based on your solution, I just added the set_locale param [he is the default unprefixed locale]:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use CodeZero\Localizer\Stores\CookieStore;
use Illuminate\Support\Facades\Cookie;
use Illuminate\Support\Facades\Route;

class SetLocale
{
    public function handle(Request $request, Closure $next)
    {
        $locale = $request->route()->getAction('localized-routes-locale');

        if (
            $locale == 'he' &&
            $request->input('set_locale') != 'he' && // I add this param to change the locale
            Cookie::get('locale') == 'en'
        ) {
            (new CookieStore)->store('en');
            return redirect(Route::localizedUrl('en'));
        }

        return $next($request);
    }
}

Yiddishe-Kop avatar May 11 '21 19:05 Yiddishe-Kop

i think better solution is add detector via config, but it added at last position and you need to add App::resolving(Localizer) in app service provider

michail1982 avatar Jul 09 '21 11:07 michail1982

that peace of code save route params znd didn`t break bindings

        $defaultLocale = config('localized-routes.omit_url_prefix_for_locale');
        if ($request->input($key = 'set_locale') == $defaultLocale) {
            $locale = $this->localizer->detect();
            if($locale != $defaultLocale) {
                $this->localizer->store($defaultLocale);
                $params = $request->route()->parameters();
                $params[$key] = null;
                return redirect(Route::localizedUrl($defaultLocale, $params));
            }
        }
        return parent::handle($request, $next);

michail1982 avatar Jul 26 '21 08:07 michail1982