I’m currently trying to implement a language detection plugin for neos, and I’m looking for some help and ideas from more experienced users (that’s my third day using Neos / flow).
Here is my idea:
At first, it will try to find a language setting by…
checking the URL parameters for a language setting.
checking the session for a language setting (for the case that cookies are disabled).
checking the cookies for a language setting.
If the language was found, it will proceed with it. Otherwise it tries to detect the browsers language. If that fails too, it will return a fallback value immediately.
The last step is to check if the detected language is present in a predefined list of available languages. If not, it will return the fallback language too.
My idea is, that this all happens before any part of the site is rendered. If the language has changed, or there was no language given (e.g when visiting the homepage for the first time or on requesting an obsolete link without language parameter), the user will be redirected to the correct url for his language, and the new language will be written into the session/cookies.
Long story short, i know how to implement the detection functionality, but I have no idea where to kick it off. Is an Aspect the right way for doing this?
Session without Cookies is horrible and doesn’t work with Flow, so you can skip that. IMHO writing the language to session is bad because you need to transfer the information in the url anyway otherwise you cannot change languages. I would look for URL parameter and Accept-Language headers in some order and that’s it.
Server based language detection has some drawbacks. No matter if you stick to the accept-language header or GeoIP or whatever. And especially using GeoIP is completely the wrong tool since a country is not a language but a country
So to me, picking languages is completely a client issue. Let me explain why.
Think about every bot or crawler hitting your site. Let’s call it googlebot, just as an example. Using a server based mechanism to either switch the language of your result content or create a redirect to a URL fitting this language better, both will prevent googlebot from reaching other content than the english one.
The most reliable way and least annoying one is leaving this decission to the user.
Here’s what we usually do:
Every language variant gets its own URL.
There’s the link rel=alternate tag. Make use of it and expos every language variant of your site.
Changing languages is done by the user by clicking a button or a link. Neither on the server side nor on the client side, nothing is done automatically.
Once the user decided for a language, its value is stored in a cookie. That’s completely client side and done by “onclick”.
If this cookie is not available, cient side JS code compares the browsers accept-header with all available link refl=alternate variants and shows a pretty prominent link to the user asking to either switching the language immediately (which will set the cookie to the target language of the link since its an explicit klick on a button) or keept the current language (which will set the cookie to the current language because that’s a button, too).
If this cookie is available, client side JS code compares not the browsers accept-header but the cookie value with all available link rel=alternate variants.
This results in:
As long as the page language delivered to the user fits the accept-language header, the user is not distrubed.
If a user has decided for a language (which means there is a cookie value available) that fits the current language, the user is not disturbed, too.
If the user has not decided for a language, yet (which means there is no cookie avilable) and the browsers accept-language votes for a language switch, a promiment button is displayed.
If a user has dedied for a language that is not the one currently displayed and there is a better alternative, the button is shown as well.
There is only one tiny limitation of this setting: The browsers accept-language header is not available to JS, unfortunately. There is the current browser language, which is the language of the browser UI. But that’s not the accept-language.
So I created a small PHP script that just fetches the accept-language from the request header and returns it.
Of course that’s a TYPO3 CMS page and no Neos page, but there is really no server side code involved, except one tiny script that looks something like this <?PHP echo $_SERVER['HTTP_ACCEPT_HEADER']; and has nothing to do with any framework.