diff options
author | José Valim <jose.valim@gmail.com> | 2009-07-28 09:00:33 +0200 |
---|---|---|
committer | José Valim <jose.valim@gmail.com> | 2009-07-28 09:00:33 +0200 |
commit | d9aae2b56e64a4f417eaffa99e10cca274e928e7 (patch) | |
tree | 8438f6f784df9b252c0f834bc7cb9c369103d4cd /railties/guides/source/i18n.textile | |
parent | 5025ae610f89989f3e15241ec7065e3d443614d9 (diff) | |
parent | 9533e0eca76b1df68a90e1ebe395d7b6a59d8e91 (diff) | |
download | rails-d9aae2b56e64a4f417eaffa99e10cca274e928e7.tar.gz rails-d9aae2b56e64a4f417eaffa99e10cca274e928e7.tar.bz2 rails-d9aae2b56e64a4f417eaffa99e10cca274e928e7.zip |
Merge branch 'master' of git://github.com/rails/rails
Diffstat (limited to 'railties/guides/source/i18n.textile')
-rw-r--r-- | railties/guides/source/i18n.textile | 83 |
1 files changed, 25 insertions, 58 deletions
diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile index 103ccb1c7a..b588656821 100644 --- a/railties/guides/source/i18n.textile +++ b/railties/guides/source/i18n.textile @@ -97,7 +97,7 @@ The *translations load path* (+I18n.load_path+) is just a Ruby Array of paths to 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. -The default +environment.rb+ files has instruction how to add locales from another directory and how to set a different default locale. Just uncomment and edit the specific lines. +The default +environment.rb+ files has instructions on how to add locales from another directory and how to set a different default locale. Just uncomment and edit the specific lines. <ruby> # The internationalization framework can be changed @@ -114,7 +114,7 @@ For the sake of completeness, let's mention that if you do not want to use the + To tell the I18n library where it can find your custom translation files you can specify the load path anywhere in your application - just make sure it gets run before any translations are actually looked up. You might also want to change the default locale. The simplest thing possible is to put the following into an initializer: <ruby> -# in config/initializer/locale.rb +# in config/initializers/locale.rb # tell the I18n library where to find your translations I18n.load_path << Dir[ File.join(RAILS_ROOT, 'lib', 'locale', @@ -142,61 +142,28 @@ def set_locale end </ruby> -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 Portugese 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. -IMPORTANT: The following examples rely on having available locales loaded into your application as an array of strings like +["en", "es", "gr"]+. This is not included in the current version of Rails 2.2 -- the forthcoming Rails version 2.3 will contain the easy accessor +available_locales+. (See "this commit":http://github.com/svenfuchs/i18n/commit/411f8fe7c8f3f89e9b6b921fa62ed66cb92f3af4 and background at "Rails I18n Wiki":http://rails-i18n.org/wiki/pages/i18n-available_locales.) - -So, for having available locales easily accessible in Rails 2.2, we have to include this support manually in an initializer, like this: - -<ruby> -# config/initializers/available_locales.rb -# -# Get loaded locales conveniently -# See http://rails-i18n.org/wiki/pages/i18n-available_locales -module I18n - class << self - def available_locales; backend.available_locales; end - end - module Backend - class Simple - def available_locales; translations.keys.collect { |l| l.to_s }.sort; end - end - end -end - -# You need to "force-initialize" loaded locales -I18n.backend.send(:init_translations) - -AVAILABLE_LOCALES = I18n.backend.available_locales -RAILS_DEFAULT_LOGGER.debug "* Loaded locales: #{AVAILABLE_LOCALES.inspect}" -</ruby> - -You can then wrap the constant for easy access in ApplicationController: - -<ruby> -class ApplicationController < ActionController::Base - def available_locales; AVAILABLE_LOCALES; end -end -</ruby> - h4. 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: -* The locale is an _obvious_ part of the URL -* People intuitively grasp in which language the content will be displayed -* It is very trivial to implement in Rails -* Search engines seem to like that content in different languages lives at different, inter-linked domains +* The locale is an _obvious_ part of the URL. +* People intuitively grasp in which language the content will be displayed. +* It is very trivial to implement in Rails. +* Search engines seem to like that content in different languages lives at different, inter-linked domains. -You can implement it like this in your ApplicationController: +You can implement it like this in your +ApplicationController+: <ruby> before_filter :set_locale + def set_locale I18n.locale = extract_locale_from_uri end + # Get locale from top-level domain or return nil if such locale is not available # You have to put something like: # 127.0.0.1 application.com @@ -205,7 +172,7 @@ end # in your /etc/hosts file to try this out locally def extract_locale_from_tld parsed_locale = request.host.split('.').last - (available_locales.include? parsed_locale) ? parsed_locale : nil + I18n.available_locales.include?(parsed_locale.to_sym) ? parsed_locale : nil end </ruby> @@ -218,7 +185,7 @@ We can also set the locale from the _subdomain_ in a very similar way: # in your /etc/hosts file to try this out locally def extract_locale_from_subdomain parsed_locale = request.subdomains.first - (available_locales.include? parsed_locale) ? parsed_locale : nil + I18n.available_locales.include?(parsed_locale.to_sym) ? parsed_locale : nil end </ruby> @@ -276,11 +243,11 @@ map.dashboard '/:locale', :controller => "dashboard" 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 +map.root+ declaration.) -IMPORTANT: This solution has currently one rather big *downside*. Due to the _default_url_options_ implementation, you have to pass the +:id+ option explicitely, like this: +link_to 'Show', book_url(:id => book)+ and not depend on Rails' magic in code like +link_to 'Show', book+. If this should be a problem, have a look at two plugins which simplify work with routes in this way: Sven Fuchs's "routing_filter":http://github.com/svenfuchs/routing-filter/tree/master and Raul Murciano's "translate_routes":http://github.com/raul/translate_routes/tree/master. See also the page "How to encode the current locale in the URL":http://rails-i18n.org/wiki/pages/how-to-encode-the-current-locale-in-the-url in the Rails i18n Wiki. +IMPORTANT: This solution has currently one rather big *downside*. Due to the _default_url_options_ implementation, you have to pass the +:id+ option explicitly, like this: +link_to 'Show', book_url(:id => book)+ and not depend on Rails' magic in code like +link_to 'Show', book+. If this should be a problem, have a look at two plugins which simplify work with routes in this way: Sven Fuchs's "routing_filter":http://github.com/svenfuchs/routing-filter/tree/master and Raul Murciano's "translate_routes":http://github.com/raul/translate_routes/tree/master. See also the page "How to encode the current locale in the URL":http://rails-i18n.org/wiki/pages/how-to-encode-the-current-locale-in-the-url in the Rails i18n Wiki. h4. 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' prefered 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. +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+ @@ -305,7 +272,7 @@ Of course, in a production environment you would need much more robust code, and h5. 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 prefered locale for the country/region/city returned. +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 @@ -315,7 +282,7 @@ h3. 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. -Let's _internationalize_ our application, i.e. abstract every locale-specific parts, and then _localize_ it, i.e. provide neccessary translations for these abstracts. +Let's _internationalize_ our application, i.e. abstract every locale-specific parts, and then _localize_ it, i.e. provide necessary translations for these abstracts. You most probably have something like this in one of your applications: @@ -365,12 +332,12 @@ NOTE: Rails adds a +t+ (+translate+) helper method to your views so that you do So let's add the missing translations into the dictionary files (i.e. do the "localization" part): <ruby> -# config/locale/en.yml +# config/locales/en.yml en: hello_world: Hello World hello_flash: Hello Flash -# config/locale/pirate.yml +# config/locales/pirate.yml pirate: hello_world: Ahoy World hello_flash: Ahoy Flash @@ -378,7 +345,7 @@ pirate: There you go. Because you haven't changed the default_locale, I18n will use English. Your application now shows: -!images/i18n/demo_translated_en.png(rails i18n demo translated to english)! +!images/i18n/demo_translated_en.png(rails i18n demo translated to English)! And when you change the URL to pass the pirate locale (+http://localhost:3000?locale=pirate+), you'll get: @@ -386,7 +353,7 @@ And when you change the URL to pass the pirate locale (+http://localhost:3000?lo 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 prefered 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.) +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. Adding Date/Time Formats @@ -402,7 +369,7 @@ OK! Now let's add a timestamp to the view, so we can demo the *date/time localiz And in our pirate translations file let's add a time format (it's already there in Rails' defaults for English): <ruby> -# config/locale/pirate.yml +# config/locales/pirate.yml pirate: time: formats: @@ -413,7 +380,7 @@ So that would give you: !images/i18n/demo_localized_pirate.png(rails i18n demo localized time to pirate)! -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's defaults for your locale*. See the "rails-i18n repository at Github":http://github.com/svenfuchs/rails-i18n/tree/master/rails/locale for an archive of various locale files. When you put such file(s) in +config/locale/+ 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":http://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. Localized Views @@ -425,7 +392,7 @@ h4. 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. -For example, your +config/locale+ directory could look like this: +For example, your +config/locales+ directory could look like this: <pre> |-defaults @@ -463,7 +430,7 @@ Do check the "Rails i18n Wiki":http://rails-i18n.org/wiki for list of tools avai h3. Overview of the I18n API Features -You should have good understanding of using the i18n library now, knowing all neccessary aspects of internationalizing a basic Rails application. In the following chapters, we'll cover it's features in more depth. +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. Covered are features like these: @@ -686,7 +653,7 @@ en: # will translate User attribute "login" as "Handle" </ruby> -Then +User.human_name+ will return "Dude" and +User.human_attribute_name(:login)+ will return "Handle". +Then +User.human_name+ will return "Dude" and +User.human_attribute_name("login")+ will return "Handle". h5. Error Message Scopes |