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", default : "key") # 키가없는 경우 기본값을 지정합니다
- I18n.locale # => : en
- I18n.locale = : en
- I18n.default_locale # => : ko
- I18n.default_locale = : ko
- t ( ". key") #
I18n.t("key")
와 같지만 호출 된 action / template 범위
뷰에서 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
으로써 방금 생성 한 키를 사용하십시오 :
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
를 구현하면 쉽게 구현할 수 있습니다.
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
후자를 달성하려면 scope
추가하여 routes
를 편집해야합니다.
# config/routes.rb
scope "(:locale)", locale: /en|fr/ do
resources :products
end
이렇게하면 http://yourapplication.com/en/products
를 방문하면 로캘이 :en
설정됩니다. 대신 http://yourapplication.com/fr/products
를 방문하면 :fr
설정됩니다. 또한 http://yourapplication.com/products
가 기본 I18n 로켈을로드하므로 :locale
param이 누락되면 라우팅 오류가 발생하지 않습니다.
세션 기반 또는 지속성 기반
이것은 사용자가 버튼 / 언어 플래그를 클릭하여 언어를 변경할 수 있다고 가정합니다. 동작은 세션을 현재 언어로 설정하는 컨트롤러로 라우팅 할 수 있습니다 (사용자가 연결되어 있으면 결국 변경 사항을 데이터베이스에 유지합니다)
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
# Gemfile
gem 'geocoder'
Geocoder
는 IP 주소로 모든 HTTP 요청의 위치를 쉽게 찾을 수 있도록 표준 Rack::Request
객체에 location
및 safe_location
메소드를 추가합니다. 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!
.
이 마이그레이션을 위해 당신은 사용할 필요가 up
및 down
, 그리고 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
이 추가 된 것에 유의하십시오.
그리고 Views에서,
# ERB
<h2><%= t(:title_html, scope: [:stackoverflow, :header]) %></h2>