aboutsummaryrefslogtreecommitdiffstats
path: root/guides/source/i18n.md
diff options
context:
space:
mode:
authorPrem Sichanugrist <s@sikachu.com>2012-09-03 21:21:24 -0400
committerPrem Sichanugrist <s@sikac.hu>2012-09-17 15:54:23 -0400
commit721afdcc4b58c65f36122b10ec998b913a147912 (patch)
treef57d8f393c4bda7180b13e32eb4182093f0f1a54 /guides/source/i18n.md
parent5a4622b8b8aad53361b281583f587a39611e7aa3 (diff)
downloadrails-721afdcc4b58c65f36122b10ec998b913a147912.tar.gz
rails-721afdcc4b58c65f36122b10ec998b913a147912.tar.bz2
rails-721afdcc4b58c65f36122b10ec998b913a147912.zip
Fix remaining formatting problems in the guide
Diffstat (limited to 'guides/source/i18n.md')
-rw-r--r--guides/source/i18n.md74
1 files changed, 42 insertions, 32 deletions
diff --git a/guides/source/i18n.md b/guides/source/i18n.md
index b15d5d2089..5cee77b1f3 100644
--- a/guides/source/i18n.md
+++ b/guides/source/i18n.md
@@ -1,9 +1,9 @@
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.
+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.
-The process of "internationalization" usually means to abstract all strings and other locale specific bits (such as date or currency formats) out of your application. The process of "localization" means to provide translations and localized formats for these bits. [1]
+The process of "internationalization" usually means to abstract all strings and other locale specific bits (such as date or currency formats) out of your application. The process of "localization" means to provide translations and localized formats for these bits.^[1](#footnote-1)
So, in the process of _internationalizing_ your Rails application you have to:
@@ -31,7 +31,7 @@ Internationalization is a complex problem. Natural languages differ in so many w
* providing support for English and similar languages out of the box
* making it easy to customize and extend everything for other languages
-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.
+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.
### The Overall Architecture of the Library
@@ -81,7 +81,7 @@ There are just a few simple steps to get up and running with I18n support for yo
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.
-Rails adds all `.rb` and `.yml` files from the `config/locales` directory to your *translations load path*, automatically.
+Rails adds all `.rb` and `.yml` files from the `config/locales` directory to your **translations load path**, automatically.
The default `en.yml` locale in this directory contains a sample pair of translation strings:
@@ -92,11 +92,11 @@ en:
This means, that in the `:en` locale, the key _hello_ will map to the _Hello world_ string. Every string inside Rails is internationalized in this way, see for instance Active Record validation messages in the [`activerecord/lib/active_record/locale/en.yml`](https://github.com/rails/rails/blob/master/activerecord/lib/active_record/locale/en.yml file or time and date formats in the [`activesupport/lib/active_support/locale/en.yml`](https://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml) file. You can use YAML or standard Ruby Hashes to store translations in the default (Simple) backend.
-The I18n library will use *English* as a *default locale*, i.e. if you don't set a different locale, `:en` will be used for looking up translations.
+The I18n library will use **English** as a **default locale**, i.e. if you don't set a different locale, `:en` will be used for looking up translations.
-NOTE: The i18n library takes a *pragmatic approach* to locale keys (after [some discussion](http://groups.google.com/group/rails-i18n/browse_thread/thread/14dede2c7dbe9470/80eec34395f64f3c?hl=en), including only the _locale_ ("language") part, like `:en`, `:pl`, not the _region_ part, like `:en-US` or `:en-GB`, which are traditionally used for separating "languages" and "regional setting" or "dialects". Many international applications use only the "language" element of a locale such as `:cs`, `:th` or `:es` (for Czech, Thai and Spanish). However, there are also regional differences within different language groups that may be important. For instance, in the `:en-US` locale you would have $ as a currency symbol, while in `:en-GB`, you would have £. Nothing stops you from separating regional and other settings in this way: you just have to provide full "English - United Kingdom" locale in a `:en-GB` dictionary. Various [Rails I18n plugins](http://rails-i18n.org/wiki) such as [Globalize2](ht)
+NOTE: The i18n library takes a **pragmatic approach** to locale keys (after [some discussion](http://groups.google.com/group/rails-i18n/browse_thread/thread/14dede2c7dbe9470/80eec34395f64f3c?hl=en), including only the _locale_ ("language") part, like `:en`, `:pl`, not the _region_ part, like `:en-US` or `:en-GB`, which are traditionally used for separating "languages" and "regional setting" or "dialects". Many international applications use only the "language" element of a locale such as `:cs`, `:th` or `:es` (for Czech, Thai and Spanish). However, there are also regional differences within different language groups that may be important. For instance, in the `:en-US` locale you would have $ as a currency symbol, while in `:en-GB`, you would have £. Nothing stops you from separating regional and other settings in this way: you just have to provide full "English - United Kingdom" locale in a `:en-GB` dictionary. Various [Rails I18n plugins](http://rails-i18n.org/wiki) such as [Globalize2](ht)
-The *translations load path* (`I18n.load_path`) is just a Ruby Array of paths to your translation files that will be loaded automatically and available in your application. You can pick whatever directory and translation file naming scheme makes sense for you.
+The **translations load path** (`I18n.load_path`) is just a Ruby Array of paths to your translation files that will be loaded automatically and available in your application. You can pick whatever directory and translation file naming scheme makes sense for you.
NOTE: The backend will lazy-load these translations when a translation is looked up for the first time. This makes it possible to just swap the backend with something else even after translations have already been announced.
@@ -126,11 +126,11 @@ I18n.default_locale = :pt
### 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.
+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.
-However, you would probably like to *provide support for more locales* in your application. In such case, you need to set and pass the locale between requests.
+However, you would probably like to **provide support for more locales** in your application. In such case, you need to set and pass the locale between requests.
-WARNING: You may be tempted to store the chosen locale in a _session_ or a <em>cookie</em>, however *do not do this*. The locale should be transparent and a part of the URL. This way you won't break people's basic assumptions about the web itself: if you send a URL to a friend, they should see the same page and content as you. A fancy word for this would be that you're being [<em>RESTful</em>](http://en.wikipedia.org/wiki/Representational_State_Transfer. Read more about the RESTful approach in [Stefan Tilkov's articles](http://www.infoq.com/articles/rest-introduction). Sometimes there are exceptions to this rule and those are discussed below.
+WARNING: You may be tempted to store the chosen locale in a _session_ or a <em>cookie</em>, however **do not do this**. The locale should be transparent and a part of the URL. This way you won't break people's basic assumptions about the web itself: if you send a URL to a friend, they should see the same page and content as you. A fancy word for this would be that you're being [<em>RESTful</em>](http://en.wikipedia.org/wiki/Representational_State_Transfer. Read more about the RESTful approach in [Stefan Tilkov's articles](http://www.infoq.com/articles/rest-introduction). Sometimes there are exceptions to this rule and those are discussed below.
The _setting part_ is easy. You can set the locale in a `before_filter` in the `ApplicationController` like this:
@@ -142,7 +142,7 @@ def set_locale
end
```
-This requires you to pass the locale as a URL query parameter as in `http://example.com/books?locale=pt`. (This is, for example, Google's approach.) So `http://localhost:3000?locale=pt` will load the Portuguese localization, whereas `http://localhost:3000?locale=de` would load the German localization, and so on. You may skip the next section and head over to the *Internationalize your application* section, if you want to try things out by manually placing the locale in the URL and reloading the page.
+This requires you to pass the locale as a URL query parameter as in `http://example.com/books?locale=pt`. (This is, for example, Google's approach.) So `http://localhost:3000?locale=pt` will load the Portuguese localization, whereas `http://localhost:3000?locale=de` would load the German localization, and so on. You may skip the next section and head over to the **Internationalize your application** section, if you want to try things out by manually placing the locale in the URL and reloading the page.
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.
@@ -205,9 +205,9 @@ The most usual way of setting (and passing) the locale would be to include it in
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.
-Getting the locale from `params` and setting it accordingly is not hard; including it in every URL and thus *passing it through the requests* is. To include an explicit option in every URL (e.g. `link_to( books_url(:locale => I18n.locale))`) would be tedious and probably impossible, of course.
+Getting the locale from `params` and setting it accordingly is not hard; including it in every URL and thus **passing it through the requests** is. To include an explicit option in every URL (e.g. `link_to( books_url(:locale => I18n.locale))`) would be tedious and probably impossible, of course.
-Rails contains infrastructure for [centralizing dynamic decisions about the URLs" in its "`ApplicationController#default_url_options`](http://api.rubyonrails.org/classes/ActionController/Base.html#M000515, which is useful precisely in this scenario: it enables us to set "defaults" for [`url_for`](http://api.rubyonrails.org/classes/ActionController/Base.html#M000503) and helper methods dependent on it (by implementing/overriding this method).
+Rails contains infrastructure for "centralizing dynamic decisions about the URLs" in its [`ApplicationController#default_url_options`](http://api.rubyonrails.org/classes/ActionController/Base.html#M000515, which is useful precisely in this scenario: it enables us to set "defaults" for [`url_for`](http://api.rubyonrails.org/classes/ActionController/Base.html#M000503) and helper methods dependent on it (by implementing/overriding this method).
We can include something like this in our `ApplicationController` then:
@@ -219,11 +219,11 @@ def default_url_options(options={})
end
```
-Every helper method dependent on `url_for` (e.g. helpers for named routes like `root_path` or `root_url`, resource routes like `books_path` or `books_url`, etc.) will now *automatically include the locale in the query string*, like this: `http://localhost:3001/?locale=ja`.
+Every helper method dependent on `url_for` (e.g. helpers for named routes like `root_path` or `root_url`, resource routes like `books_path` or `books_url`, etc.) will now **automatically include the locale in the query string**, like this: `http://localhost:3001/?locale=ja`.
You may be satisfied with this. It does impact the readability of URLs, though, when the locale "hangs" at the end of every URL in your application. Moreover, from the architectural standpoint, locale is usually hierarchically above the other parts of the application domain: and URLs should reflect this.
-You probably want URLs to look like this: `www.example.com/en/books` (which loads the English locale) and `www.example.com/nl/books` (which loads the Dutch locale). This is achievable with the [over-riding `default_url_options`" strategy from above: you just have to set up your routes with "`scoping`](http://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Scoping.html) option in this way:
+You probably want URLs to look like this: `www.example.com/en/books` (which loads the English locale) and `www.example.com/nl/books` (which loads the Dutch locale). This is achievable with the "over-riding `default_url_options`" strategy from above: you just have to set up your routes with [`scoping`](http://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Scoping.html) option in this way:
```ruby
# config/routes.rb
@@ -254,7 +254,7 @@ You would probably need to map URLs like these:
match '/:locale' => 'dashboard#index'
```
-Do take special care about the *order of your routes*, so this route declaration does not "eat" other ones. (You may want to add it directly before the `root :to` declaration.)
+Do take special care about the **order of your routes**, so this route declaration does not "eat" other ones. (You may want to add it directly before the `root :to` 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).
@@ -305,14 +305,18 @@ You most probably have something like this in one of your applications:
Yourapp::Application.routes.draw do
root :to => "home#index"
end
+```
+```ruby
# app/controllers/home_controller.rb
class HomeController < ApplicationController
def index
flash[:notice] = "Hello Flash"
end
end
+```
+```html+erb
# app/views/home/index.html.erb
<h1>Hello World</h1>
<p><%= flash[:notice] %></p>
@@ -322,7 +326,7 @@ end
### 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:
+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:
```ruby
# app/controllers/home_controller.rb
@@ -331,7 +335,9 @@ class HomeController < ApplicationController
flash[:notice] = t(:hello_flash)
end
end
+```
+```html+erb
# app/views/home/index.html.erb
<h1><%=t :hello_world %></h1>
<p><%= flash[:notice] %></p>
@@ -341,7 +347,7 @@ When you now render this view, it will show an error message which tells you tha
![rails i18n demo translation missing](images/i18n/demo_translation_missing.png)
-NOTE: Rails adds a `t` (`translate`) helper method to your views so that you do not need to spell out `I18n.t` all the time. Additionally this helper will catch missing translations and wrap the resulting error message into a `&lt;span class="translation_missing"&gt;`.
+NOTE: Rails adds a `t` (`translate`) helper method to your views so that you do not need to spell out `I18n.t` all the time. Additionally this helper will catch missing translations and wrap the resulting error message into a `<span class="translation_missing">`.
So let's add the missing translations into the dictionary files (i.e. do the "localization" part):
@@ -373,10 +379,12 @@ You may use YAML (`.yml`) or plain Ruby (`.rb`) files for storing your translati
You can use variables in the translation messages and pass their values from the view.
-```ruby
+```erb
# app/views/home/index.html.erb
<%=t 'greet_username', :user => "Bill", :message => "Goodbye" %>
+```
+```yaml
# config/locales/en.yml
en:
greet_username: "%{message}, %{user}!"
@@ -384,9 +392,9 @@ en:
### 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.
+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.
-```ruby
+```erb
# app/views/home/index.html.erb
<h1><%=t :hello_world %></h1>
<p><%= flash[:notice] %></p
@@ -407,7 +415,7 @@ So that would give you:
![rails i18n demo localized time to pirate](images/i18n/demo_localized_pirate.png)
-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.
+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.
### Inflection Rules For Other Locales
@@ -415,7 +423,7 @@ Rails 4.0 allows you to define inflection rules (such as rules for singularizati
### 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.)
+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.
@@ -552,15 +560,15 @@ es:
title: "Título"
```
-you can look up the `books.index.title` value *inside* `app/views/books/index.html.erb` template like this (note the dot):
+you can look up the `books.index.title` value **inside** `app/views/books/index.html.erb` template like this (note the dot):
-```ruby
+```erb
<%= t '.title' %>
```
### 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.
+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.
All options besides `:default` and `:scope` that are passed to `#translate` will be interpolated to the translation:
@@ -629,14 +637,16 @@ I18n.default_locale = :de
Keys with a '_html' suffix and keys named 'html' are marked as HTML safe. Use them in views without escaping.
-```ruby
+```yaml
# config/locales/en.yml
en:
welcome: <b>welcome!</b>
hello_html: <b>hello!</b>
title:
html: <b>title!</b>
+```
+```html+erb
# app/views/home/index.html.erb
<div><%= t('welcome') %></div>
<div><%= raw t('welcome') %></div>
@@ -649,7 +659,7 @@ en:
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]
+The Simple backend shipped with Active Support allows you to store translations in both plain Ruby and YAML format.^[2](#footnote-2)
For example a Ruby Hash providing translations can look like this:
@@ -850,7 +860,7 @@ Customize your I18n Setup
### 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.
+For several reasons the Simple backend shipped with Active Support only does the "simplest thing that could possibly work" _for Ruby on Rails_^[3](#footnote-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.
That does not mean you're stuck with these limitations, though. The Ruby I18n gem makes it very easy to exchange the Simple backend implementation with something else that fits better for your needs. E.g. you could exchange it with Globalize's Static backend:
@@ -960,8 +970,8 @@ If you found this guide useful, please consider recommending its authors on [wor
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."_
+[<a name="footnote-1">1</a>]: 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."_
-fn2. Other backends might allow or require to use other formats, e.g. a GetText backend might allow to read GetText files.
+[<a name="footnote-2">2</a>]: Other backends might allow or require to use other formats, e.g. a GetText backend might allow to read GetText files.
-fn3. One of these reasons is that we don't want to imply any unnecessary load for applications that do not need any I18n capabilities, so we need to keep the I18n library as simple as possible for English. Another reason is that it is virtually impossible to implement a one-fits-all solution for all problems related to I18n for all existing languages. So a solution that allows us to exchange the entire implementation easily is appropriate anyway. This also makes it much easier to experiment with custom features and extensions.
+[<a name="footnote-3">3</a>]: One of these reasons is that we don't want to imply any unnecessary load for applications that do not need any I18n capabilities, so we need to keep the I18n library as simple as possible for English. Another reason is that it is virtually impossible to implement a one-fits-all solution for all problems related to I18n for all existing languages. So a solution that allows us to exchange the entire implementation easily is appropriate anyway. This also makes it much easier to experiment with custom features and extensions.