I’m running a private, international forum for a club where most content is German and some is mixed. Users can choose their preferred language in their user settings, but this is non-obvious for visitors (and doubly so for most of “my” visitors).
The website we are running selects the display language based on the HTTP Accept-Language header field. I’d like to see a new option where I can advise Discourse to auto-select the language based on the header field. Bonus points if users are able to override the automatic detection with their preferred language.
Is this a viable option?
Awesome! However, in our case, the forum requires a login and uses SSO auth (with the website), so users are always logged in but most do not have the language set by themselves. Is this use case possible with the addon?
Would it work for you to have the signed-in user’s locale default to the locale from their HTTP headers, but also give them the option to set their locale for Discourse in their user preferences?
If so, it looks like this can be easily done. I have a working prototype for this now. The only downside that I can see for doing it this way is that until the user sets their language preferences with Discourse, the emails they get from the system will be in the forum’s default language.
Another option is to change how Discourse single-sign-on works so that it accepts a locale parameter and uses that to create the Discourse user from the SSO parameters.
Thanks for the link, I wanted to request that, too (however it will probably not help much in my case) …
Yes, that’s exactly what I need.
Huh. What about caching the last “known” language? This obviously needs to be a different field from the user preference.
Or better yet, have a heuristic based on how often you access the forum with a specific language? That’s increasing complexity a lot, however a simple solution could be to store an array with “known” languages and a weighting (value between 0 and 1), which is updated every time a user logs in: increase weighting for the current language and decrease it for the other ones in the array … well, not that simple.
Or just cache the language the HTTP header field contains and once the user visits with a different language, show a prompt saying something like “We are having trouble identifying your main language. Please choose your preferred language from the list below:” and let that update the user preference. Then we know for sure and the user is informed / will not be surprised if the language changes because he was on vacation for too long …
Another option would be to update the user’s locale preference from their HTTP headers on login.
I think the best/simplest solution for doing this in a plugin is to ask the user to confirm their language preferences from the locale select input. If you are concerned that your users won’t be able to find that in their preferences, it could be added to the header for users who have not yet confirmed their language.
Started GET "/" for x.x.x.x at 2015-11-19 13:44:56 +0000
Processing by CategoriesController#index as HTML
Completed 500 Internal Server Error in 3ms (ActiveRecord: 0.0ms)
NoMethodError (undefined method `ensure_all_loaded!' for I18n:Module)
/var/www/discourse/plugins/variable-language/plugin.rb:35:in `set_locale'
I added the plugin in the container configuration file:
Yes, before that it was using I18n.fallbacks.ensure_loaded!. If you can’t update to 1.5 you could probably get the plugin to work by changing its set_locale method to this:
def set_locale
if SiteSetting.allow_user_locale
if !current_user
I18n.locale = locale_from_http_header
else
if current_user.preferred_locale?
I18n.locale = current_user.preferred_locale
else
I18n.locale = locale_from_http_header
end
end
else
I18n.locale = SiteSetting.default_locale
end
I18n.fallbacks.ensure_loaded!
end
Thanks, I think I can wait until 1.5, hoping it will release around New Year.
On the other hand, would it be possible to make the plugin downwards-compatible by checking for the existance of ensure_all_loaded and falling back to fallbacks.ensure_loaded otherwise?
It might not make sense for most discussion forums, but it makes sense for forums that are providing a service to clients who may speak different languages.
Sure, I’ll do that in the next couple of days. Also, I found a problem with the plugin where it is causing an error when the site is accessed without the accept-language headers being set. I’ll fix that too.
I’ve updated this. I haven’t tested it on 1.4.2. Let me know if there are any problems. You may need to clear your browser cache to get a new locale from the headers.
There is an issue with the login_required_welcome_message being cached in the first locale that accesses it. I assume that’s not a problem if you are using SSO.