Peppermintology
Peppermintology

Reputation: 10210

Symfony default locale without specifying in URL

I would like to configure the Symfony locale options so that I can successfully access the following routes:

/route
/{locale}/route

Currently, I can access /{locale}/route and I get my view, however, /route returns a No route found for "GET /route". My configuration is as follows:

#app/config/parameters.yml
parameters:
    locale: en

#app/config/config.yml
parameters:
    app_locales: en|fr
framework:
    translator: { fallback: "%locale%" }
    default_locale: "%locale%"

#app/config/routing.yml
app:
    resource: '@AppBundle/Controller/'
    type: annotation

My Controller has the following annotations:

#src/AppBundle/Controller/Admin/MyController.php
/**
 *
 * @Route(
 *     "/{_locale}/admin/my",
 *     defaults={"_locale":"%locale%"},
 *     requirements={"_locale":"%app_locales%"}
 *     )
 */
class MyController extends Controller
{
    /**
     * @Route("/", name="admin_my_list")
     * @Method("GET")
     */
    public function listAction()
    {
        ...
    }
}

If I specifically include the locale, it all works. If I exclude the locale, I get the No route found error.

Upvotes: 5

Views: 5132

Answers (3)

lordrhodos
lordrhodos

Reputation: 2745

You have to define another route to cover the scenario without the provided locale, try changing your route definition to:

#src/AppBundle/Controller/Admin/MyController.php

class MyController extends Controller
{
    /**
     * @Route(
     *     "/admin/my",
     *     defaults={"_locale":"%locale%"},
     *     )
     * @Route(
     *     "/{_locale}/admin/my",
     *     requirements={"_locale":"%app_locales%"}
     *     )
     * @Method("GET")
     */
    public function listAction()
    {
        ...
    }
}

You can read more about this process here in the docs

Upvotes: 6

Raid
Raid

Reputation: 825

I was able to accomplish this with:

#[Route(['/{_locale}/{path}', 'en' => '/{path}'], requirements: ['path' => '.*', '_locale' => 'en|fr'])]

This is explained at: https://symfony.com/doc/current/routing.html#localized-routes-i18n

Normally one would use:

'en' => '/en/{path}', 'fr' => '/fr/{path}'

But seeing as {_locale} gets captured first, and $request->getLocale() is set to the locale if you use 'fr' for example, and we just enforce that for the second match for the default locale 'en', which sets the locale from the associative array.

Upvotes: 0

Martin Fasani
Martin Fasani

Reputation: 823

I agree with what Boris commented up there.

An alternative solution about making a RouteMatcher is to use EventListener and redirect user into same route with the default Locale (Check the answer that has more upvotes)

In my opinion doing this with EventListeners like Athlan explained there is the way to go. I would not mess with making your own RouteMatcher. Just see what lordrhodos wrote, never tried to put two routes like this in a Controller annotations, but I think if you have only one Controller is the way to go. If they are going to be a lot might be a lot cleaner to do this with EventListeners in only one place.

Upvotes: 0

Related Questions