-
Notifications
You must be signed in to change notification settings - Fork 260
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Set locale based on Accept-Language header #420
Set locale based on Accept-Language header #420
Conversation
This is a good option because the header is usually set by the user's browser language preferences. Code from http://guides.rubyonrails.org/i18n.html
If the header is nil, default to English.
Thanks for re-doing this. I did find out while working on #419 that this breaks if the user requests a locale we don't have. Here is a screenshot when requesting the We need some way of defaulting to something we actually have, probably Fortunately there are ways of handling this, such as: https://github.com/iain/http_accept_language That is a gem we can add and then have it select the best locale we provide, selected amongst users' requested locales. I am hoping the gem lets us fall back to a default locale when we match none of the user-accepted languages, but it's not super clear so we would have to test. Seems like most browsers might accept Or if this can be done without installing another gem that's fine by me. |
"en" | ||
else | ||
request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sets the locale to be the top-preferred locale of the user's browser, whether we have that locale translated or not. Unfortunately, if the top-preferred locale is one we don't have, users see the translation key names in the page, rather than translated strings from an actual locale.
I think we should
- Go through each of the user's preferred locales and use the first one we have.
- Find a way to revert to
en
when the user's requested locales aren't ones we have.
Can use a gem to handle this, or do it directly in custom Ruby logic.
The gem automatically chooses the optimal language to set, as the user usually provides a list of languages in order of preference. This also makes sure that the locale is set to the default when the requested locale isn't present.
I used the gem you suggested. With this, the locale gets set to the correct value and when a locale that we don't support gets requested, it defaults to the value of We tell rails which locales we supported by setting |
Looks good! Going to give it a quick test with the Also, I'm interested in possibly using |
@@ -14,17 +14,7 @@ def mobile_filter_header | |||
end | |||
|
|||
def set_locale | |||
I18n.locale = extract_locale_from_accept_language_header | |||
I18n.locale = http_accept_language.compatible_language_from(I18n.available_locales) | |||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using http_accept_language.
language_region_compatible_from
(I18n.available_locales)
?
According to this README:
language_region_compatible_from(languages): Returns the first of the user preferred languages that is also found in available languages. Finds best fit by matching on primary language first and secondarily on region. If no matching region is found, return the first language in the group matching that primary language.
vs:
compatible_language_from(languages): Returns the first of the user_preferred_languages that is compatible with the available locales. Ignores region.
This looks reallly good in further testing. First, I configured the app to believe it supported English, generic Chinese, Chinese specifically for Taiwan [aka traditional Chinese], and Chinese specifically for China [aka simplified Chinese] in
Here were my results:
Update: more testing I configured the app to belive it supported only generic English and Chinese specifically for China...
Results:
|
Thanks for all your testing @DeeDeeG! |
Wow this is fantastic. I admire all of this work! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works, and all tests pass in Travis CI.
Thoroughly tested in Vagrant.
Makes us ready for new translations, while being totally backward-compatible to our existing locale, which is just en
.
Deletes extra copy of mobile_filter_header definition in app/controllers/application_controller.rb Missed this when reviewing #420.
…tion Set locale based on Accept-Language header. Uses the http_accept_language gem to intelligently pick the most-preferred locale we have. Makes us ready to start accepting and testing new translations. Still desirable would be to have an in-app language-switcher.
Deletes extra copy of mobile_filter_header definition in app/controllers/application_controller.rb Missed this when reviewing RefugeRestrooms#420.
…tion Set locale based on Accept-Language header. Uses the http_accept_language gem to intelligently pick the most-preferred locale we have. Makes us ready to start accepting and testing new translations. Still desirable would be to have an in-app language-switcher.
Deletes extra copy of mobile_filter_header definition in app/controllers/application_controller.rb Missed this when reviewing RefugeRestrooms#420.
This used to be Intimaria#1.
Context
Summary of Changes
Now, the language of the page will change to fit with the preferred language setting of the browser.
Change Setting
Chrome Settings