Ruby on Rails
I18n - 国際化
サーチ…
構文
- I18n.t( "キー")
- I18n.translate( "key")#
I18n.t("key")
相当するI18n.t("key")
- I18n.t(「キー」、カウント:4)
- I18n.t( "key"、param1: "Something"、param2: "Else")
- I18n.t( "doesnt_exist"、デフォルト: "key")#キーがない場合のデフォルトを指定する
- I18n.locale#=>:en
- I18n.locale =:en
- I18n.default_locale#=>:en
- I18n.default_locale =:en
- t( "
I18n.t("key")
")#I18n.t("key")
と同じですが、呼び出されたアクション/テンプレートのスコープ
ビューでI18nを使用する
このYAMLロケールファイルがあると仮定します:
# config/locales/en.yml
en:
header:
title: "My header title"
あなたのタイトル文字列を表示したい場合は、これを行うことができます
# in ERB files
<%= t('header.title') %>
# in SLIM files
= t('header.title')
引数付きのI18n
あなたは、 国際化にパラメータを渡すことができますt
方法:
# Example config/locales/en.yml
en:
page:
users: "%{users_count} users currently online"
# In models, controller, etc...
I18n.t('page.users', users_count: 12)
# In views
# ERB
<%= t('page.users', users_count: 12) %>
#SLIM
= t('page.users', users_count: 12)
# Shortcut in views - DRY!
# Use only the dot notation
# Important: Consider you have the following controller and view page#users
# ERB Example app/views/page/users.html.erb
<%= t('.users', users_count: 12) %>
そして次の出力を得る:
"12 users currently online"
複数化
あなたはI18nがあなたのために複数化を扱えるようにすることができます。単にcount
引数を使います。
ロケールファイルを次のように設定する必要があります:
# config/locales/en.yml
en:
online_users:
one: "1 user is online"
other: "%{count} users are online"
次に、 count
引数をI18n.t
ヘルパーに渡して、作成したばかりのキーを使用します。
I18n.t("online_users", count: 1)
#=> "1 user is online"
I18n.t("online_users", count: 4)
#=> "4 users are online"
リクエストによるロケールの設定
ほとんどの場合、 I18n
ロケールを設定することができます。現在のセッション、現在のユーザ、またはURLパラメータに基づいてロケールを設定することができます。コントローラのいずれかにbefore_action
を実装するか、 ApplicationController
ですべてのコントローラにbefore_action
を実装すると簡単に実現できます。
class ApplicationController < ActionController::Base
before_action :set_locale
protected
def set_locale
# Remove inappropriate/unnecessary ones
I18n.locale = params[:locale] || # Request parameter
session[:locale] || # Current session
(current_user.preferred_locale if user_signed_in?) || # Model saved configuration
extract_locale_from_accept_language_header || # Language header - browser config
I18n.default_locale # Set in your config files, english by super-default
end
# Extract language from request header
def extract_locale_from_accept_language_header
if request.env['HTTP_ACCEPT_LANGUAGE']
lg = request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first.to_sym
lg.in?([:en, YOUR_AVAILABLE_LANGUAGES]) ? lg : nil
end
end
URLベース
locale
パラメータは次のようなURLから来る可能性があります
http://yourapplication.com/products?locale=en
または
http://yourapplication.com/en/products
後者を達成するには、 routes
を編集してscope
追加する必要があります。
# config/routes.rb
scope "(:locale)", locale: /en|fr/ do
resources :products
end
これを行うことで、 http://yourapplication.com/en/products
:en
http://yourapplication.com/en/products
にアクセスすると、あなたのロケールは:en
設定されます。代わりにhttp://yourapplication.com/fr/products
にアクセスすると、 :fr
設定され:fr
。不足しているときさらに、あなたは、ルーティングエラーを取得することはできません:locale
PARAMを訪問して、 http://yourapplication.com/products
デフォルトのI18nロケールをロードします。
セッションベースまたはパーシスタンスベース
これは、ユーザが言語を変更するためにボタン/言語フラグをクリックできることを前提としています。このアクションは、セッションを現在の言語に設定するコントローラにルーティングできます(ユーザーが接続されている場合は、最終的に変更をデータベースに保持します)
class SetLanguageController < ApplicationController
skip_before_filter :authenticate_user!
after_action :set_preferred_locale
# Generic version to handle a large list of languages
def change_locale
I18n.locale = sanitize_language_param
set_session_and_redirect
end
使用可能な言語のリストを使用してsanitize_language_paramを定義し、言語が存在しない場合のエラーを処理する必要があります。
言語がごくわずかな場合は、代わりに次のように定義する価値があります。
def fr
I18n.locale = :fr
set_session_and_redirect
end
def en
I18n.locale = :en
set_session_and_redirect
end
private
def set_session_and_redirect
session[:locale] = I18n.locale
redirect_to :back
end
def set_preferred_locale
if user_signed_in?
current_user.preferred_locale = I18n.locale.to_s
current_user.save if current_user.changed?
end
end
end
注: change_language
アクションにいくつかのルートを追加することを忘れないでください
デフォルトロケール
アプリケーションのデフォルトのロケールを設定する必要があることに注意してください。 config/application.rb
設定するか、
config.i18n.default_locale = :de
またはconfig/initializers
フォルダにイニシャライザを作成します。
# config/initializers/locale.rb
I18n.default_locale = :it
HTTPリクエストからロケールを取得する
要求IPに基づいてアプリケーションロケールを設定すると便利な場合があります。これはGeocoder
を使用して簡単に実現できます。 Geocoder
が行う多くの機能の中でも、 request
location
を示すことができます。
まず、 Geocoder
をGemfile
追加します
# Gemfile
gem 'geocoder'
Geocoder
は、標準のRack::Request
オブジェクトにlocation
およびsafe_location
メソッドを追加するので、IPアドレスによるHTTPリクエストの場所を簡単に検索できます。 ApplicationController
before_action
でこのメソッドを使用できます:
class ApplicationController < ActionController::Base
before_action :set_locale_from_request
def set_locale_from_request
country_code = request.location.data["country_code"] #=> "US"
country_sym = country_code.underscore.to_sym #=> :us
# If request locale is available use it, otherwise use I18n default locale
if I18n.available_locales.include? country_sym
I18n.locale = country_sym
end
end
0.0.0.0
やlocalhost
ようなものは有効な有効なインターネットIPアドレスなので、これはdevelopment
環境やtest
環境では動作しないことに注意してください。
制限と代替
Geocoder
は非常に強力で柔軟性がありますが、 ジオコーディングサービスを使用するように構成する必要があります(詳細はこちらを参照 )。その多くは用途に制限を設けています。すべてのリクエストに対して外部サービスを呼び出すと、パフォーマンスに影響を与える可能性があります。
これらに対処するには、次のことも検討する価値があります。
1.オフラインソリューション
GeoIP
( ここを参照)のような宝石を使用すると、ローカルデータファイルに対して検索を行うことができます。これらのデータファイルを最新の状態に保つ必要があるため、正確性の面でトレードオフがあります。
2. CloudFlareを使用する
CloudFlareを介して提供されるページには、国コードがヘッダ( HTTP_CF_IPCOUNTRY
)に追加され、透明にジオコードされるオプションがあります。詳細はこちらをご覧ください 。
ActiveRecordモデル属性の翻訳
globalize
gemは、 ActiveRecord
モデルに翻訳を追加するのに最適なソリューションです。これをGemfile
追加してインストールすることができます:
gem 'globalize', '~> 5.0.0'
Rails 5
を使用している場合は、 activemodel-serializers-xml
も追加する必要があります
gem 'activemodel-serializers-xml'
モデル変換を使用すると、モデルの属性値を変換できます。たとえば、次のようになります。
class Post < ActiveRecord::Base
translates :title, :text
end
I18n.locale = :en
post.title # => Globalize rocks!
I18n.locale = :he
post.title # => גלובאלייז2 שולט!
変換が必要なモデル属性を定義したら、マイグレーションによって変換テーブルを作成する必要があります。 globalize
はcreate_translation_table!
提供しcreate_translation_table!
とdrop_translation_table!
。
この移行では、 down
に使用up
必要があり、 change
する必要はありません 。また、この移行を正常に実行するには、上に示したように、変換された属性をモデルで最初に定義する必要があります。以前のPost
モデルの適切な移行は次のとおりです。
class CreatePostsTranslationTable < ActiveRecord::Migration
def up
Post.create_translation_table! title: :string, text: :text
end
def down
Post.drop_translation_table!
end
end
特定のオプションのオプションを渡すこともできます:
class CreatePostsTranslationTable < ActiveRecord::Migration
def up
Post.create_translation_table! title: :string,
text: { type: :text, null: false, default: "Default text" }
end
def down
Post.drop_translation_table!
end
end
必要な翻訳カラムに既に既存のデータがある場合は、移行を調整して簡単に翻訳テーブルに移行することができます。
class CreatePostsTranslationTable < ActiveRecord::Migration
def up
Post.create_translation_table!({
title: :string,
text: :text
}, {
migrate_data: true
})
end
def down
Post.drop_translation_table! migrate_data: true
end
end
すべてのデータが安全に移行されたら、親テーブルから変換された列を削除してください。データ移行後に親テーブルから変換された列を自動的に削除するには、 remove_source_columns
オプションを移行に追加します。
class CreatePostsTranslationTable < ActiveRecord::Migration
def up
Post.create_translation_table!({
title: :string,
text: :text
}, {
migrate_data: true,
remove_source_columns: true
})
end
def down
Post.drop_translation_table! migrate_data: true
end
end
以前に作成した翻訳テーブルに新しいフィールドを追加することもできます:
class Post < ActiveRecord::Base
# Remember to add your attribute here too.
translates :title, :text, :author
end
class AddAuthorToPost < ActiveRecord::Migration
def up
Post.add_translation_fields! author: :text
end
def down
remove_column :post_translations, :author
end
end
HTMLタグと記号でI18nを使用する
# config/locales/en.yml
en:
stackoverflow:
header:
title_html: "Use <strong>I18n</strong> with Tags & Symbols"
名前のtitle
後に追加の_html
が追加されていることに注意してください。
ビューでは、
# ERB
<h2><%= t(:title_html, scope: [:stackoverflow, :header]) %></h2>