FEATURE: Support locale in routing from the request
This change is supposed to allow to define a RoutePart @locale in routing, that will be resolved and then in turn copied to generated URIs. This will allow to easily create a HTTP component, that will set the application locale from the routing information and/or other request parameters, like cookie or headers, which can then be used to localize the application.
Related to #1233
Ignore the test failures for now. They should be easy to fix. I'd like to get feedback, if this is something that would get support from the rest of the team.
I decided to keep everything locale to just be a string. Resolving to an actual Locale object or detecting the best matching locale via the i18n services is something that should be handled by the HTTP component.
Edit: In the end, something like this should be possible via configuration/routing:
Routing.yaml
-
name: 'Acme Labs with locale'
uriPattern: '({@locale}/)acme/<AcmeSubroutes>'
routeParts:
'@locale':
handler: 'Flowpack\Localize\Http\LocaleRoutePart'
subRoutes:
'AcmeSubroutes':
package: 'Acme.Labs'
Settings.yaml
http:
chain:
'process':
chain:
'detectLanguage':
position: 'after routing'
component: Flowpack\Localize\Http\DetectLanguageComponent
And then whereever URIs are generated, one can either override the locale explicitly (e.g. uriBuilder->setLocale('en_US')) or otherwise the locale of the current request is used.
I like the concept, of being able to bind a routing parameter to a locale. I can see a great usecase for when building "static pages" with localized content via XLF and similar (i do that in a project).
One thing that I don't know if this change will cover, is the usage in other "locale aware" context, ex. "translation services" like "TranslateViewHelper", "Or i18nServices" for when rendering a Fluid template for email etc. just to mention a few
This change itself won't cover setting the current Locale in the i18n service yet, but that will be easily doable in a follow-up in whichever way is then seen practical. Either inside an HTTP component or within the controller initialization.
My thought is whether we should cast it to a Locale object instead of a string, to keep the future implementation easier and non-breaking?
I intentionally avoided that to prevent coupling the MVC package to the i18n package, but I'm open to that. I would otherwise handle the conversion to Locale object inside the HTTP component, which also sets the i18n current locale.
Sound legit, all though the i18n package is a part of the "core" Flow package, so I don't see what we benefit from not turning it to a object right away - but I can also see the good idea of keeping it clean and lowlevel (data-wise) at that point
I was searching for exactly this solution. i would love to see this getting implemented. we would start getting this in our dev systems right away.
What i would also love would be a solution, where the local variable can be set options without removing the possibility for other optional parts. we already have parts implemented, that are optional and i would like too add something like this: uriPattern: '({@locale}/)acme(/other-optional-part)'
just telling my usecase here for locale ;)
@sorenmalling it's just an architectural cleanness thing, because even though all packages belong to the core, we try to keep them as decoupled as possible, in order to be able to split them away when we see fit. See the few packages (Cache, Logging, etc.) already split by Christian. So if at some point we might decide to split off the i18n package, it's good to have as few interdependencies as needed.
@cwenzelg you can solve that by putting the locale optional part into your main Routes.yaml and then include your application routes with another optional part:
Routes.yaml:
-
name: 'Acme Labs with locale'
uriPattern: '({@locale}/)acme/<AcmeSubroutes>'
routeParts:
'@locale':
handler: 'Flowpack\Localize\Http\LocaleRoutePart'
subRoutes:
'AcmeSubroutes':
package: 'Acme.Labs'
Acme.Labs Routes.yaml:
-
name: 'default'
uriPattern: '{@controller}(/{@action})'
defaults:
'@package': 'Acme.Labs'
'@subpackage': ''
'@action': 'index'
'@format': 'html'
appendExceedingArguments: true
Normally, the locale is a global route parameter anyway, so that even makes sense.
So my main questions remaining are these:
-
should the locale argument in the ActionRequest be an
Localeobject -
where should the LocaleRoutePart be placed? Inside i18n in the core? Without a LocaleRoutePart the above route configuration will end up with lots of invalid routings, because
@localewill just be matched with the first path element. -
should the LocaleRoutePart be applied automatically to
@localeroute part?
@kitsunet @kdambekalns @bwaidelich maybe?
@albe I see the good point in the "slicing the elephant" that is going on.
This is, in my eyes, a Locale (i18n) specific mechanism, and makes best sense to keep it all inside the i18n part
@albe What about WIP the label?
edit: read the comments, probably still valid due to the open questions, right? So me, @bwaidelich and @kitsunet should have a look here…
I still stick to my comments at https://github.com/neos/flow-development-collection/issues/1233#issuecomment-372676767 but I won't block this of course
Yes, feedback is welcome and highly appreciated. Other than that it's mostly fixing/adding tests what is keeping this "WIP". If we can land this in 5.1 I'm happy, if not I'm not unhappy ;)
OK, a little more feedback nevertheless (:
- This still needs documentation and tests, right?
- How will this work together with Neos? i.e. shouldn't we somehow respect the new
@localeargument when selecting the backend/frontend language?
- Docs&Tests: yes!
- Neos: As long as it is not configured in the Routes.yaml, nothing changes really. Even then, an HttpComponent needs to fetch the
@localefrom Routing and "apply" it (make it the current i18n Locale, etc. - such a Component would be provided with a follow-up). I don't really know how Neos currently deals with the language in routes apart from it being a ContentDimension. So in my (not so deep) thinking, Neos could change it's Routes config and then use a HttpComponent to map the@localeto a ContentDimension. This might be totally off though, so I'd gladly work it out in a way that works for Neos
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions!
Don't close. Still a topic for me, though prioritized lower than e.g. PSR-7
This issue has been automatically closed because it has not had activity for some time. But that does not need to be final. If you find the time to work on it, feel free to open it again. Thanks again for your contributions!
Reopening to keep this on the radar - still would like to have some basic support of locale from routing in Flow
Oh my, what a loss this is still lingering here… A lot has changed in routing by now, I guess this needs to be adapted, no?
Would love to sometime rework this and finish it up. I still do think (4+ years later) it would be a worthwhile feature. But currently I don't think I can pull it off unfortunately.