Skip to content

Commit

Permalink
Merge pull request #34356 from gmcgibbon/docs_i18n_with_locale_thread…
Browse files Browse the repository at this point in the history
…safe

Make i18n locale setting docs use around_action
  • Loading branch information
rafaelfranca committed Oct 31, 2018
2 parents b86c2a6 + bcccf8b commit f98901c
Showing 1 changed file with 23 additions and 15 deletions.
38 changes: 23 additions & 15 deletions guides/source/i18n.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,14 @@ The default locale is used for all translations unless `I18n.locale` is explicit

A localized application will likely need to provide support for multiple locales. To accomplish this, the locale should be set at the beginning of each request so that all strings are translated using the desired locale during the lifetime of that request.

The locale can be set in a `before_action` in the `ApplicationController`:
The locale can be set in an `around_action` in the `ApplicationController`:

```ruby
before_action :set_locale
around_action :switch_locale

def set_locale
I18n.locale = params[:locale] || I18n.default_locale
def switch_locale(&action)
locale = params[:locale] || I18n.default_locale
I18n.with_locale(locale, &action)
end
```

Expand All @@ -169,10 +170,11 @@ One option you have is to set the locale from the domain name where your applica
You can implement it like this in your `ApplicationController`:

```ruby
before_action :set_locale
around_action :switch_locale

def set_locale
I18n.locale = extract_locale_from_tld || I18n.default_locale
def switch_locale(&action)
locale = extract_locale_from_tld || I18n.default_locale
I18n.with_locale(locale, &action)
end

# Get locale from top-level domain or return +nil+ if such locale is not available
Expand Down Expand Up @@ -212,7 +214,7 @@ This solution has aforementioned advantages, however, you may not be able or may

#### Setting the Locale from URL Params

The most usual way of setting (and passing) the locale would be to include it in URL params, as we did in the `I18n.locale = params[:locale]` _before_action_ in the first example. We would like to have URLs like `www.example.com/books?locale=ja` or `www.example.com/ja/books` in this case.
The most usual way of setting (and passing) the locale would be to include it in URL params, as we did in the `I18n.with_locale(params[:locale], &action)` _around_action_ in the first example. We would like to have URLs like `www.example.com/books?locale=ja` or `www.example.com/ja/books` in this case.

This approach has almost the same set of advantages as setting the locale from the domain name: namely that it's RESTful and in accord with the rest of the World Wide Web. It does require a little bit more work to implement, though.

Expand Down Expand Up @@ -275,8 +277,11 @@ NOTE: Have a look at various gems which simplify working with routes: [routing_f
An application with authenticated users may allow users to set a locale preference through the application's interface. With this approach, a user's selected locale preference is persisted in the database and used to set the locale for authenticated requests by that user.

```ruby
def set_locale
I18n.locale = current_user.try(:locale) || I18n.default_locale
around_action :switch_locale

def switch_locale(&action)
locale = current_user.try(:locale) || I18n.default_locale
I18n.with_locale(locale, &action)
end
```

Expand All @@ -291,10 +296,11 @@ The `Accept-Language` HTTP header indicates the preferred language for request's
A trivial implementation of using an `Accept-Language` header would be:

```ruby
def set_locale
def switch_locale(&action)
logger.debug "* Accept-Language: #{request.env['HTTP_ACCEPT_LANGUAGE']}"
I18n.locale = extract_locale_from_accept_language_header
locale = extract_locale_from_accept_language_header
logger.debug "* Locale set to '#{I18n.locale}'"
I18n.with_locale(locale, &action)
end

private
Expand Down Expand Up @@ -335,10 +341,12 @@ end
```ruby
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
before_action :set_locale

def set_locale
I18n.locale = params[:locale] || I18n.default_locale
around_action :switch_locale

def switch_locale(&action)
locale = params[:locale] || I18n.default_locale
I18n.with_locale(locale, &action)
end
end
```
Expand Down

0 comments on commit f98901c

Please sign in to comment.