Enhance the "Passing Variables to Translations" part

Add more information about passing variables to translation definitions
and also merge this part with the "Interpolation" one as the latter
didn't bring any new information. Moreover, each one was referring to
the other for further information.

[ci skip]
This commit is contained in:
Evan Prothro 2015-04-12 16:18:28 +02:00 committed by Robin Dupret
parent eaa4378586
commit 984a4db3c3
1 changed files with 48 additions and 19 deletions

View File

@ -403,21 +403,64 @@ NOTE: You need to restart the server when you add new locale files.
You may use YAML (`.yml`) or plain Ruby (`.rb`) files for storing your translations in SimpleStore. YAML is the preferred option among Rails developers. However, it has one big disadvantage. YAML is very sensitive to whitespace and special characters, so the application may not load your dictionary properly. Ruby files will crash your application on first request, so you may easily find what's wrong. (If you encounter any "weird issues" with YAML dictionaries, try putting the relevant portion of your dictionary into a Ruby file.)
### Passing variables to translations
### Passing Variables to Translations
You can use variables in the translation messages and pass their values from the view.
One key consideration for successfully internationalizing an application is to
avoid making incorrect assumptions about grammar rules when abstracting localized
code. Grammar rules that seem fundamental in one locale may not hold true in
another one.
Improper abstraction is shown in the following example, where assumptions are
made about the ordering of the different parts of the translation. Note that Rails
provides a `number_to_currency` helper to handle the following case.
```erb
# app/views/home/index.html.erb
<%=t 'greet_username', user: "Bill", message: "Goodbye" %>
# app/views/products/show.html.erb
<%= "#{t('currency')}#{@product.price}" %>
```
```yaml
# config/locales/en.yml
en:
greet_username: "%{message}, %{user}!"
currency: "$"
# config/locales/es.yml
es:
currency: "€"
```
If the product's price is 10 then the proper translation for Spanish is "10 €"
instead of "€10" but the abstraction cannot give it.
To create proper abstraction, the I18n gem ships with a feature called variable
interpolation that allows you to use variables in translation definitions and
pass the values for these variables to the translation method.
Proper abstraction is shown in the following example:
```erb
# app/views/products/show.html.erb
<%= t('product_price', price: @product.price) %>
```
```yaml
# config/locales/en.yml
en:
product_price: "$%{price}"
# config/locales/es.yml
es:
product_price: "%{price} €"
```
All grammatical and punctuation decisions are made in the definition itself, so
the abstraction can give a proper translation.
NOTE: The `default` and `scope` keywords are reserved and can't be used as
variable names. If used, an `I18n::ReservedInterpolationKey` exception is raised.
If a translation expects an interpolation variable, but this has not been passed
to `#translate`, an `I18n::MissingInterpolationArgument` exception is raised.
### Adding Date/Time Formats
OK! Now let's add a timestamp to the view, so we can demo the **date/time localization** feature as well. To localize the time format you pass the Time object to `I18n.l` or (preferably) use Rails' `#l` helper. You can pick a format by passing the `:format` option - by default the `:default` format is used.
@ -618,20 +661,6 @@ class BooksController < ApplicationController
end
```
### Interpolation
Properly internationalized code will use variables in translation definitions to ensure correct translations in multiple languages. See the [Passing Variables to Translations](#passing-variables-to-translations) section for more detail on this consideration.
The I18n API provides an interpolation feature to address this need. All options besides `:default` and `:scope` that are passed to `#translate` can be interpolated in the translation:
```ruby
I18n.backend.store_translations(:en, thanks: 'Thanks %{name}!')
I18n.translate(:thanks, name: 'Jeremy')
# => 'Thanks Jeremy!'
```
If a translation uses `:default` or `:scope` as an interpolation variable, an `I18n::ReservedInterpolationKey` exception is raised. If a translation expects an interpolation variable, but this has not been passed to `#translate`, an `I18n::MissingInterpolationArgument` exception is raised.
### Pluralization
In English there are only one singular and one plural form for a given string, e.g. "1 message" and "2 messages". Other languages ([Arabic](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html#ar), [Japanese](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html#ja), [Russian](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html#ru) and many more) have different grammars that have additional or fewer [plural forms](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html). Thus, the I18n API provides a flexible pluralization feature.