aboutsummaryrefslogtreecommitdiffstats
path: root/guides/source/i18n.md
diff options
context:
space:
mode:
authorPrem Sichanugrist <s@sikachu.com>2012-09-01 17:25:58 -0400
committerPrem Sichanugrist <s@sikac.hu>2012-09-17 15:54:22 -0400
commit872b7af337196febc516cb6218ae3d07f01a11a8 (patch)
treebc31fdc0803fff3aed26b6599cf2df7789055a41 /guides/source/i18n.md
parent7bc1ca351523949f6b4ce96018e95e61cbc7719e (diff)
downloadrails-872b7af337196febc516cb6218ae3d07f01a11a8.tar.gz
rails-872b7af337196febc516cb6218ae3d07f01a11a8.tar.bz2
rails-872b7af337196febc516cb6218ae3d07f01a11a8.zip
Convert heading tags and heading section
Diffstat (limited to 'guides/source/i18n.md')
-rw-r--r--guides/source/i18n.md110
1 files changed, 61 insertions, 49 deletions
diff --git a/guides/source/i18n.md b/guides/source/i18n.md
index f4ff52e5e1..577efe54a1 100644
--- a/guides/source/i18n.md
+++ b/guides/source/i18n.md
@@ -1,4 +1,5 @@
-h2. Rails Internationalization (I18n) API
+Rails Internationalization (I18n) API
+=====================================
The Ruby I18n (shorthand for _internationalization_) gem which is shipped with Ruby on Rails (starting from Rails 2.2) provides an easy-to-use and extensible framework for *translating your application to a single custom language* other than English or for *providing multi-language support* in your application.
@@ -18,11 +19,12 @@ In the process of _localizing_ your application you'll probably want to do the f
This guide will walk you through the I18n API and contains a tutorial on how to internationalize a Rails application from the start.
-endprologue.
+--------------------------------------------------------------------------------
NOTE: The Ruby I18n framework provides you with all necessary means for internationalization/localization of your Rails application. You may, however, use any of various plugins and extensions available, which add additional functionality or features. See the Rails "I18n Wiki":http://rails-i18n.org/wiki for more information.
-h3. How I18n in Ruby on Rails Works
+How I18n in Ruby on Rails Works
+-------------------------------
Internationalization is a complex problem. Natural languages differ in so many ways (e.g. in pluralization rules) that it is hard to provide tools for solving all problems at once. For that reason the Rails I18n API focuses on:
@@ -31,7 +33,7 @@ Internationalization is a complex problem. Natural languages differ in so many w
As part of this solution, *every static string in the Rails framework* -- e.g. Active Record validation messages, time and date formats -- *has been internationalized*, so _localization_ of a Rails application means "over-riding" these defaults.
-h4. The Overall Architecture of the Library
+### The Overall Architecture of the Library
Thus, the Ruby I18n gem is split into two parts:
@@ -42,7 +44,7 @@ As a user you should always only access the public methods on the I18n module, b
NOTE: It is possible (or even desirable) to swap the shipped Simple backend with a more powerful one, which would store translation data in a relational database, GetText dictionary, or similar. See section "Using different backends":#using-different-backends below.
-h4. The Public I18n API
+### The Public I18n API
The most important methods of the I18n API are:
@@ -70,11 +72,12 @@ backend # Use a different backend
So, let's internationalize a simple Rails application from the ground up in the next chapters!
-h3. Setup the Rails Application for Internationalization
+Setup the Rails Application for Internationalization
+----------------------------------------------------
There are just a few simple steps to get up and running with I18n support for your application.
-h4. Configure the I18n Module
+### Configure the I18n Module
Following the _convention over configuration_ philosophy, Rails will set up your application with reasonable defaults. If you need different settings, you can overwrite them easily.
@@ -105,7 +108,7 @@ The default +application.rb+ files has instructions on how to add locales from a
# config.i18n.default_locale = :de
```
-h4. Optional: Custom I18n Configuration Setup
+### Optional: Custom I18n Configuration Setup
For the sake of completeness, let's mention that if you do not want to use the +application.rb+ file for some reason, you can always wire up things manually, too.
@@ -121,7 +124,7 @@ I18n.load_path += Dir[Rails.root.join('lib', 'locale', '*.{rb,yml}')]
I18n.default_locale = :pt
```
-h4. Setting and Passing the Locale
+### Setting and Passing the Locale
If you want to translate your Rails application to a *single language other than English* (the default locale), you can set I18n.default_locale to your locale in +application.rb+ or an initializer as shown above, and it will persist through the requests.
@@ -143,7 +146,7 @@ This requires you to pass the locale as a URL query parameter as in +http://exam
Of course, you probably don't want to manually include the locale in every URL all over your application, or want the URLs look differently, e.g. the usual +http://example.com/pt/books+ versus +http://example.com/en/books+. Let's discuss the different options you have.
-h4. Setting the Locale from the Domain Name
+### Setting the Locale from the Domain Name
One option you have is to set the locale from the domain name where your application runs. For example, we want +www.example.com+ to load the English (or default) locale, and +www.example.es+ to load the Spanish locale. Thus the _top-level domain name_ is used for locale setting. This has several advantages:
@@ -196,7 +199,7 @@ assuming you would set +APP_CONFIG[:deutsch_website_url]+ to some value like +ht
This solution has aforementioned advantages, however, you may not be able or may not want to provide different localizations ("language versions") on different domains. The most obvious solution would be to include locale code in the URL params (or request path).
-h4. Setting the Locale from the URL Params
+### Setting the Locale from the 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_filter_ 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.
@@ -255,12 +258,12 @@ Do take special care about the *order of your routes*, so this route declaration
NOTE: Have a look at two plugins which simplify work with routes in this way: Sven Fuchs's "routing_filter":https://github.com/svenfuchs/routing-filter/tree/master and Raul Murciano's "translate_routes":https://github.com/raul/translate_routes/tree/master.
-h4. Setting the Locale from the Client Supplied Information
+### Setting the Locale from the Client Supplied Information
In specific cases, it would make sense to set the locale from client-supplied information, i.e. not from the URL. This information may come for example from the users' preferred language (set in their browser), can be based on the users' geographical location inferred from their IP, or users can provide it simply by choosing the locale in your application interface and saving it to their profile. This approach is more suitable for web-based applications or services, not for websites -- see the box about _sessions_, _cookies_ and RESTful architecture above.
-h5. Using +Accept-Language+
+#### Using +Accept-Language+
One source of client supplied information would be an +Accept-Language+ HTTP header. People may "set this in their browser":http://www.w3.org/International/questions/qa-lang-priorities or other clients (such as _curl_).
@@ -280,15 +283,16 @@ end
Of course, in a production environment you would need much more robust code, and could use a plugin such as Iain Hecker's "http_accept_language":https://github.com/iain/http_accept_language/tree/master or even Rack middleware such as Ryan Tomayko's "locale":https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib/locale.rb.
-h5. Using GeoIP (or Similar) Database
+#### Using GeoIP (or Similar) Database
Another way of choosing the locale from client information would be to use a database for mapping the client IP to the region, such as "GeoIP Lite Country":http://www.maxmind.com/app/geolitecountry. The mechanics of the code would be very similar to the code above -- you would need to query the database for the user's IP, and look up your preferred locale for the country/region/city returned.
-h5. User Profile
+#### User Profile
You can also provide users of your application with means to set (and possibly over-ride) the locale in your application interface, as well. Again, mechanics for this approach would be very similar to the code above -- you'd probably let users choose a locale from a dropdown list and save it to their profile in the database. Then you'd set the locale to this value.
-h3. Internationalizing your Application
+Internationalizing your Application
+-----------------------------------
OK! Now you've initialized I18n support for your Ruby on Rails application and told it which locale to use and how to preserve it between requests. With that in place, you're now ready for the really interesting stuff.
@@ -316,7 +320,7 @@ end
!images/i18n/demo_untranslated.png(rails i18n demo untranslated)!
-h4. Adding Translations
+### Adding Translations
Obviously there are *two strings that are localized to English*. In order to internationalize this code, *replace these strings* with calls to Rails' +#t+ helper with a key that makes sense for the translation:
@@ -365,7 +369,7 @@ 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.)
-h4. Passing variables to translations
+### Passing variables to translations
You can use variables in the translation messages and pass their values from the view.
@@ -378,7 +382,7 @@ en:
greet_username: "%{message}, %{user}!"
```
-h4. Adding Date/Time Formats
+### 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.
@@ -405,17 +409,17 @@ So that would give you:
TIP: Right now you might need to add some more date/time formats in order to make the I18n backend work as expected (at least for the 'pirate' locale). Of course, there's a great chance that somebody already did all the work by *translating Rails' defaults for your locale*. See the "rails-i18n repository at Github":https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale for an archive of various locale files. When you put such file(s) in +config/locales/+ directory, they will automatically be ready for use.
-h4. Inflection Rules For Other Locales
+### Inflection Rules For Other Locales
Rails 4.0 allows you to define inflection rules (such as rules for singularization and pluralization) for locales other than English. In +config/initializers/inflections.rb+, you can define these rules for multiple locales. The initializer contains a default example for specifying additional rules for English; follow that format for other locales as you see fit.
-h4. Localized Views
+### Localized Views
Rails 2.3 introduces another convenient localization feature: localized views (templates). Let's say you have a _BooksController_ in your application. Your _index_ action renders content in +app/views/books/index.html.erb+ template. When you put a _localized variant_ of this template: *+index.es.html.erb+* in the same directory, Rails will render content in this template, when the locale is set to +:es+. When the locale is set to the default locale, the generic +index.html.erb+ view will be used. (Future Rails versions may well bring this _automagic_ localization to assets in +public+, etc.)
You can make use of this feature, e.g. when working with a large amount of static content, which would be clumsy to put inside YAML or Ruby dictionaries. Bear in mind, though, that any change you would like to do later to the template must be propagated to all of them.
-h4. Organization of Locale Files
+### Organization of Locale Files
When you are using the default SimpleStore shipped with the i18n library, dictionaries are stored in plain-text files on the disc. Putting translations for all parts of your application in one file per locale could be hard to manage. You can store these files in a hierarchy which makes sense to you.
@@ -456,7 +460,8 @@ NOTE: The default locale loading mechanism in Rails does not load locale files i
Do check the "Rails i18n Wiki":http://rails-i18n.org/wiki for list of tools available for managing translations.
-h3. Overview of the I18n API Features
+Overview of the I18n API Features
+---------------------------------
You should have good understanding of using the i18n library now, knowing all necessary aspects of internationalizing a basic Rails application. In the following chapters, we'll cover it's features in more depth.
@@ -468,9 +473,9 @@ Covered are features like these:
* using safe HTML translations
* localizing dates, numbers, currency, etc.
-h4. Looking up Translations
+### Looking up Translations
-h5. Basic Lookup, Scopes and Nested Keys
+#### Basic Lookup, Scopes and Nested Keys
Translations are looked up by keys which can be both Symbols or Strings, so these calls are equivalent:
@@ -502,7 +507,7 @@ I18n.t :record_invalid, :scope => 'activerecord.errors.messages'
I18n.t :record_invalid, :scope => [:activerecord, :errors, :messages]
```
-h5. Defaults
+#### Defaults
When a +:default+ option is given, its value will be returned if the translation is missing:
@@ -520,7 +525,7 @@ I18n.t :missing, :default => [:also_missing, 'Not here']
# => 'Not here'
```
-h5. Bulk and Namespace Lookup
+#### Bulk and Namespace Lookup
To look up multiple translations at once, an array of keys can be passed:
@@ -536,7 +541,7 @@ I18n.t 'activerecord.errors.messages'
# => { :inclusion => "is not included in the list", :exclusion => ... }
```
-h5. "Lazy" Lookup
+#### "Lazy" Lookup
Rails implements a convenient way to look up the locale inside _views_. When you have the following dictionary:
@@ -553,7 +558,7 @@ you can look up the +books.index.title+ value *inside* +app/views/books/index.ht
<%= t '.title' %>
```
-h4. Interpolation
+### Interpolation
In many cases you want to abstract your translations so that *variables can be interpolated into the translation*. For this reason the I18n API provides an interpolation feature.
@@ -567,7 +572,7 @@ I18n.translate :thanks, :name => '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.
-h4. Pluralization
+### 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.
@@ -595,7 +600,7 @@ I.e. the translation denoted as +:one+ is regarded as singular, the other is use
If the lookup for the key does not return a Hash suitable for pluralization, an +18n::InvalidPluralizationData+ exception is raised.
-h4. Setting and Passing a Locale
+### Setting and Passing a Locale
The locale can be either set pseudo-globally to +I18n.locale+ (which uses +Thread.current+ like, e.g., +Time.zone+) or can be passed as an option to +#translate+ and +#localize+.
@@ -620,7 +625,7 @@ The +I18n.locale+ defaults to +I18n.default_locale+ which defaults to :+en+. The
I18n.default_locale = :de
```
-h4. Using Safe HTML Translations
+### Using Safe HTML Translations
Keys with a '_html' suffix and keys named 'html' are marked as HTML safe. Use them in views without escaping.
@@ -641,7 +646,8 @@ en:
!images/i18n/demo_html_safe.png(i18n demo html safe)!
-h3. How to Store your Custom Translations
+How to Store your Custom Translations
+-------------------------------------
The Simple backend shipped with Active Support allows you to store translations in both plain Ruby and YAML format. [2]
@@ -689,7 +695,7 @@ I18n.t :short, :scope => [:date, :formats]
Generally we recommend using YAML as a format for storing translations. There are cases, though, where you want to store Ruby lambdas as part of your locale data, e.g. for special date formats.
-h4. Translations for Active Record Models
+### Translations for Active Record Models
You can use the methods +Model.model_name.human+ and +Model.human_attribute_name(attribute)+ to transparently look up translations for your model and attribute names.
@@ -708,7 +714,7 @@ en:
Then +User.model_name.human+ will return "Dude" and +User.human_attribute_name("login")+ will return "Handle".
-h5. Error Message Scopes
+#### Error Message Scopes
Active Record validation error messages can also be translated easily. Active Record gives you a couple of namespaces where you can place your message translations in order to provide different messages and translation for certain models, attributes, and/or validations. It also transparently takes single table inheritance into account.
@@ -766,7 +772,7 @@ errors.messages.blank
This way you can provide special translations for various error messages at different points in your models inheritance chain and in the attributes, models, or default scopes.
-h5. Error Message Interpolation
+#### Error Message Interpolation
The translated model name, translated attribute name, and value are always available for interpolation.
@@ -797,7 +803,7 @@ So, for example, instead of the default error message +"can not be blank"+ you c
| numericality | :odd | :odd | -|
| numericality | :even | :even | -|
-h5. Translations for the Active Record +error_messages_for+ Helper
+#### Translations for the Active Record +error_messages_for+ Helper
If you are using the Active Record +error_messages_for+ helper, you will want to add translations for it.
@@ -814,11 +820,11 @@ en:
body: "There were problems with the following fields:"
```
-h4. Overview of Other Built-In Methods that Provide I18n Support
+### Overview of Other Built-In Methods that Provide I18n Support
Rails uses fixed strings and other localizations, such as format strings and other format information in a couple of helpers. Here's a brief overview.
-h5. Action View Helper Methods
+#### Action View Helper Methods
* +distance_of_time_in_words+ translates and pluralizes its result and interpolates the number of seconds, minutes, hours, and so on. See "datetime.distance_in_words":https://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L51 translations.
@@ -826,7 +832,7 @@ h5. Action View Helper Methods
* The +number_to_currency+, +number_with_precision+, +number_to_percentage+, +number_with_delimiter+, and +number_to_human_size+ helpers use the number format settings located in the "number":https://github.com/rails/rails/blob/master/actionpack/lib/action_view/locale/en.yml#L2 scope.
-h5. Active Model Methods
+#### Active Model Methods
* +model_name.human+ and +human_attribute_name+ use translations for model names and attribute names if available in the "activerecord.models":https://github.com/rails/rails/blob/master/activerecord/lib/active_record/locale/en.yml#L29 scope. They also support translations for inherited class names (e.g. for use with STI) as explained above in "Error message scopes".
@@ -834,13 +840,14 @@ h5. Active Model Methods
* +ActiveModel::Errors#full_messages+ prepends the attribute name to the error message using a separator that will be looked up from "errors.format":https://github.com/rails/rails/blob/master/activemodel/lib/active_model/locale/en.yml#L4 (and which defaults to +"%{attribute} %{message}"+).
-h5. Active Support Methods
+#### Active Support Methods
* +Array#to_sentence+ uses format settings as given in the "support.array":https://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml#L30 scope.
-h3. Customize your I18n Setup
+Customize your I18n Setup
+-------------------------
-h4. Using Different Backends
+### Using Different Backends
For several reasons the Simple backend shipped with Active Support only does the "simplest thing that could possibly work" _for Ruby on Rails_ [3] ... which means that it is only guaranteed to work for English and, as a side effect, languages that are very similar to English. Also, the simple backend is only capable of reading translations but can not dynamically store them to any format.
@@ -856,7 +863,7 @@ You can also use the Chain backend to chain multiple backends together. This is
I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend)
```
-h4. Using Different Exception Handlers
+### Using Different Exception Handlers
The I18n API defines the following exceptions that will be raised by backends when the corresponding unexpected conditions occur:
@@ -911,14 +918,16 @@ To do so, the helper forces +I18n#translate+ to raise exceptions no matter what
I18n.t :foo, :raise => true # always re-raises exceptions from the backend
```
-h3. Conclusion
+Conclusion
+----------
At this point you should have a good overview about how I18n support in Ruby on Rails works and are ready to start translating your project.
If you find anything missing or wrong in this guide, please file a ticket on our "issue tracker":http://i18n.lighthouseapp.com/projects/14948-rails-i18n/overview. If you want to discuss certain portions or have questions, please sign up to our "mailing list":http://groups.google.com/group/rails-i18n.
-h3. Contributing to Rails I18n
+Contributing to Rails I18n
+--------------------------
I18n support in Ruby on Rails was introduced in the release 2.2 and is still evolving. The project follows the good Ruby on Rails development tradition of evolving solutions in plugins and real applications first, and only then cherry-picking the best-of-breed of most widely useful features for inclusion in the core.
@@ -927,7 +936,8 @@ Thus we encourage everybody to experiment with new ideas and features in plugins
If you find your own locale (language) missing from our "example translations data":https://github.com/svenfuchs/rails-i18n/tree/master/rails/locale repository for Ruby on Rails, please "_fork_":https://github.com/guides/fork-a-project-and-submit-your-modifications the repository, add your data and send a "pull request":https://github.com/guides/pull-requests.
-h3. Resources
+Resources
+---------
* "rails-i18n.org":http://rails-i18n.org - Homepage of the rails-i18n project. You can find lots of useful resources on the "wiki":http://rails-i18n.org/wiki.
* "Google group: rails-i18n":http://groups.google.com/group/rails-i18n - The project's mailing list.
@@ -937,7 +947,8 @@ h3. Resources
* "Lighthouse: i18n":http://i18n.lighthouseapp.com/projects/14947-ruby-i18n/overview - Issue tracker for the i18n gem.
-h3. Authors
+Authors
+-------
* "Sven Fuchs":http://www.workingwithrails.com/person/9963-sven-fuchs (initial author)
* "Karel Minařík":http://www.workingwithrails.com/person/7476-karel-mina-k
@@ -945,7 +956,8 @@ h3. Authors
If you found this guide useful, please consider recommending its authors on "workingwithrails":http://www.workingwithrails.com.
-h3. Footnotes
+Footnotes
+---------
fn1. Or, to quote "Wikipedia":http://en.wikipedia.org/wiki/Internationalization_and_localization: _"Internationalization is the process of designing a software application so that it can be adapted to various languages and regions without engineering changes. Localization is the process of adapting software for a specific region or language by adding locale-specific components and translating text."_