`
sillycat
  • 浏览: 2482963 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Rails Study(12)I18N Overview

阅读更多
Rails Study(12)I18N Overview

1 How I18n in Ruby on Rails Works
Internationalization is a complex problem.
1.1 The Overall Architecture of the Library
The ruby I18n gem is split into two parts:
* The public API of the i18n framework
* A default backend

1.2 The Public I18n API
The most important methods of the I18n API: translate, localize

I18n.t 'store.title'
I18n.l Time.now

load_path            # announce your custom translation files
locale                  # get and set the current locale
default_locale       # get and set the default locale
exeption_hander
backend

2 Setup the Rails Application for Internationalization
2.1 Configure the I18n Module
Rails adds all *.rb and *.yml files from the config/locales directory to your translations load path.

The configuration file config/application.rb can configure this.

2.2 Optional: Custom I18n Configuration Setup
Put the configuration in one initializer:
#in config/initializers/locale.rb
I18n.load_path += Dir[Rails.root.join('lib', 'locale', '*.{rb,yml}')]
I18n.default_locale = :pt

2.3 Setting and Passing the Locale
If you want to provide support for more locales in your application, you need to set and pass the locale between requests.

Notices: Do not store the chosen locale in a session or a cookie. The locale should be transparent and a part of the URL. This way you do not break people's basic assumptions about the web itself: if you send a URL of some page to a friend, she should see the same page, same content.

In ApplicationController before_filter:

before_filter :set_locale

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

We need to pass the locale as a URL query parameter
http://example.com/books?locale=pt
http://localhost:3000?locale=pt

2.4 Setting the Locale from the Domain Name
For example, we want www.example.com to load the English (or default) locale, and www.example.es to load the Spanish locale.

We can implement it like this in ApplicationController

before_filter :set_locale

def set_locale
I18n.locale = extract_locale_from_tld || I18n.default_locale
end

#get locale from top-level domain
def extract_local_from_tld
parsed_locale = request.host.split('.').last
I18n.available_locales.include?(parsed_locale.to_sym) ? parsed_locale
end

to_sym converts a string to a symbol. For example, "a".to_sym becomes :a

or set the locale from the subdomain

def extract_locale_from_subdomain
parsed_locale = request.subdomains.first
I18n.available_locales.include?(parsed_locale.to_sym) ? parsed_locale
end

2.5 Setting the Locale from the URL Params
to get the URL like this
http://www.example.com/books?locale=ja

link_to( books_url(:locale => I18n.locale))

And we can deal with this in ApplicationController#default_url_options

#app/controllers/application_controller.rb
def default_url_options(options={})
logger.debug "default_url_options is passed options: #{options.inspect}\n"
{:locale => I18n.locale}
end

Every helper method dependent on url_for (e.g. root_path, root_url, books_path, books_url and etc.) will now automatically include the locale in the query string.

to get this kind of URL http://www.example.com/en/books
set up your routes with path_prefix option in this way:
#config/routes.rb
scope "/:locale" do
resources :books
end

To make that there is default URL and some special URL
#config/routes.rb
scope "(:locale)", :locale => /en|nl/ do
resources :books
end

And take care of the root path
#config/routes.rb
match '/:locale' => 'dashboard#index'

2.6 Setting the Locale from the Client Supplied Information
It would make sense to set the locale from client-supplied information, for example, from the users' preferred language (set in their browser).

2.6.1 Using Accept-Language
One source of client supplied information would be an Accept-Language HTTP header.

def set_locale
logger.debug "*Accept-Language: #{request.env['HTTP_ACCEPT_LANGUAGE']}"
I18n.locale = extract_locale_from_accept_language_header
logger.debug "* Locale set to '#{I18n.locale}'"
end

private

def extract_locale_from_accept_language_header
request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first
end

scan/^[a-z]{2}/ is the regex statement.

2.6.2 Using GeoIP(or Similar) Database
2.6.3 User Profile

3. Internationalizing your Application
home page controller class
class HomeController < ApplicationController
  def index
    flash[:notice] = "Hello master!"
  end
end

erb html files
<p><%= flash[:notice] %></p>

3.1 Adding Translations
To internationalize this code, replace these strings with calls to Rails' #t helper with a key that makes sense for the translation:

app/controllers/application_controller.rb
  before_filter :set_locale
 
  def set_locale
    I18n.locale = params[:locale] || I18n.default_locale
  end
 
  def default_url_options(options={})
    logger.debug "default_url_options is passed options: #{options.inspect}\n"
    {:locale => I18n.locale}
  end

home_controller.rb
  def index
    #flash[:notice] = "Hello master!"
    flash[:notice] = t(:hello_flash)
  end

erb file index.html.erb
<p><%=t :hello_world %></p>
<p><%= flash[:notice] %></p>

yml file config/locales/en.yml
en:
  hello_flash: Hello God
  hello_world: hello Hell
test:
  hello_flash: test God
  hello_world: test Hell

Actually, we can also make en.yml into 2 files en.yml and test.yml.

With the visited URL http://localhost:3000/
hello Hell
Hello God
With the visited URL http://localhost:3000/?locale=test
test Hell
test God

3.2 Adding Date/Time Formats
We can pass the Time object to I18n.l or use Rails' #l helper. You can pick a format by passing the :format option, :default for default format.

erb html file
<p><%= l Time.now, :format => :short %></p>

in the yml file
en: 
  time:
    formats:
      short: "time %H %m %s"
test: 
  time:
    formats:
      short: "time %H"

3.3 Localized Views
Rails 2.3 introduces another convenient localization feature: localized views (templates).
app/views/books/index.html.erb, but if locale is :es, it will render to index.es.html.erb.

I add a file index.cn.html.erb in the same directory with content hello Chinese! And when I access the URL
http://localhost:3000/?locale=cn, I got the content in index.cn.html.erb

3.4 Organization of Locale Files

references:
http://guides.rubyonrails.org/i18n.html
http://www.yotabanana.com/hiki/ruby-gettext-howto-rails.html
http://ruby-i18n.org/wiki
http://st-on-it.blogspot.com/2008/07/rails-gettext-crashcourse.html
https://github.com/mutoh/gettext_rails
sample URL
https://github.com/mutoh/gettext_rails/blob/master/sample/config/environment.rb
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics