锁定老帖子 主题:Rails每周一题(十): i18n
精华帖 (0) :: 良好帖 (13) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-06-14
最后修改:2009-08-08
所谓的国际化:就是根据特定的locale信息,提取相应的字符串和其它一些东西(比如时间和货币的格式)等等。
显然,有三个问题需要解决:
1. 如何确定locale。
2. 如何保存这些locale相关的字符串和其它信息。
3. 如何根据locale提取字符串和其它相应的信息。
让我们来看看rails如何处理国际化。(指rails2.2之后)
首先看看第一点,如何确定locale
可以通过几种不同的方法来确定locale。
a. url参数
http://www.example.com?locale=cn 或者 http://www.example.com/cn
在服务器端可以通过在before_filter中获取locale信息:
# 通过before_filter before_filter :set_locale def set_locale I18n.locale = extract_locale_from_uri end
要注意的是,如果通过此种方法来确定locale,那么所有的url都得附上locale参数。我们可以通过重载以下方法(url_for等方法均依赖于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
或者通过设置routes在所有的url中加上prefix:
# routes.rb map.resources :books, :path_prefix => '/:locale' b. 域名
http://www.example.cn 对域名方式,同样在before_filter中获取locale信息。只不过修改一下extract方法:
def extract_locale_from_subdomain parsed_locale = request.subdomains.first (available_locales.include? parsed_locale) ? parsed_locale : nil end c. 客户端提供的信息
客户端可以提供一些信息告诉服务端它所接受和期望的语言是什么。可以有以下几种方式来告知:
c.1. Accept-Language
通过在浏览器中设置Accept-Language,服务器端通过获取此http header的信息来确定。
def extract_locale_from_accept_language_header request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first end c.2. ip地址
根据ip地址来分析用户的locale信息。
c.3. profile
注册用户可以把locale信息保存在个人档案中。
接下来让我们看看rails如何解决第二个问题
如何保存locale相关的字符串和其它信息
rails必须知道,本地化的信息被放置何处。在Rails中有几种方法来保存locale信息。
a. yml
# config/locale/en.yml en: hello_world: Hello World hello_flash: Hello Flash # config/locale/pirate.yml pirate: hello_world: Ahoy World hello_flash: Ahoy Flash
b. 本地化view
一般我们的view template文件是这样的:
app/views/somethings/index.html.erb 当在同个目录下放置一个加上本地化变量的template文件,比如:
app/views/somethings/index.cn.html.erb 当本地locale是cn时,便会render这个文件。
c. 对本地化文件的管理
把所有本地化信息都放置在一个文件中必然会导致混乱,我们可以按照自己的方式来管理这些本地文件,比如:
|-defaults |---es.rb |---en.rb |-models |---book |-----es.rb |-----en.rb |-views |---defaults |-----es.rb |-----en.rb |---books |-----es.rb |-----en.rb |---users |-----es.rb |-----en.rb |---navigation |-----es.rb |-----en.rb 要注意的是,rails默认不会load层级目录中的文件,所以需要:
# config/environment.rb config.i18n.load_path += Dir[File.join(RAILS_ROOT, 'config', 'locales', '**', '*.{rb,yml}')]
好了,我们已经知道如何放置本地化信息,最后来看一下rails如何根据locale获取这些信息。其实,这里要讲的就是rails国际化API。
提取信息
rails提供了一下几个API:
translate # Lookup text translations localize # Localize Date and Time objects to local formats
以及它们的alias:
I18n.t 'store.title' I18n.l Time.now
在需要本地化的地方,只需要这样使用:
# app/views/home/index.html.erb <h1><%=t :hello_world %></h1> <p><%= flash[:notice] %></p <p><%= l Time.now, :format => :short %></p>
好了,本文匆匆到此结束。
如果想跟进一步的了解rails的i18n,可以看一下这篇文章:http://guides.rubyonrails.org/i18n.html
例子:
http://github.com/svenfuchs/rails-i18n/tree/master/rails/locale
http://github.com/rails/rails/blob/master/activerecord/lib/active_record/locale/en.yml 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-07-21
感谢您的总结. 近日使用i18n, 补充一点在官方guides里面也没提到的问题, 关于"复数形式".
Guides的4.3 Pluralization中提到复数可以这样设置和使用: I18n.backend.store_translations :en, :inbox => { :one => '1 message', :other => '{{count}} messages' } I18n.translate :inbox, :count => 2 # => '2 messages' 其实设置只需要在Locale yml文件里面加上这样一段即可, 效果是一样的: en: inbox: one: '1 message' other: '{{count}} messages' |
|
返回顶楼 | |
浏览 3789 次