Rails 국제화(I18n) API
Ruby I18n(국제화의 약자) 젬은 Ruby on Rails(Rails 2.2부터 포함)와 함께 제공되며, 영어 이외의 단일 사용자 정의 언어로 애플리케이션을 번역하거나 애플리케이션에 다국어 지원을 제공하기 위한 쉽게 사용할 수 있고 확장 가능한 프레임워크를 제공합니다.
“국제화"라는 프로세스는 일반적으로 애플리케이션의 모든 문자열과 기타 지역별 부분(날짜 또는 통화 형식 등)을 추상화하는 것을 의미합니다. "지역화” 프로세스는 이러한 부분에 대한 번역과 지역화된 형식을 제공하는 것을 의미합니다.[^1]
따라서 Rails 애플리케이션을 국제화하는 과정에서 다음을 수행해야 합니다:
- I18n 지원을 확인합니다.
- Rails에 로케일 사전을 어디에서 찾을 수 있는지 알려줍니다.
- Rails에 로케일을 설정, 보존 및 전환하는 방법을 알려줍니다.
애플리케이션을 지역화하는 과정에서 다음 세 가지를 수행하고 싶을 것입니다:
- Rails의 기본 로케일을 대체하거나 보완합니다 - 예: 날짜 및 시간 형식, 월 이름, Active Record 모델 이름 등.
- 애플리케이션의 문자열을 키가 있는 사전으로 추상화합니다 - 예: 플래시 메시지, 뷰의 정적 텍스트 등.
- 결과 사전을 어딘가에 저장합니다.
이 가이드는 I18n API를 안내하고 처음부터 Rails 애플리케이션을 국제화하는 자습서를 포함합니다.
이 가이드를 읽고 나면 다음을 알게 될 것입니다:
- Ruby on Rails에서 I18n이 어떻게 작동하는지
- RESTful 애플리케이션에서 다양한 방식으로 I18n을 올바르게 사용하는 방법
- Active Record 오류 또는 Action Mailer 이메일 제목을 번역하는 방법
- 애플리케이션 번역 프로세스를 더 발전시키기 위한 기타 도구
참고: Ruby I18n 프레임워크는 Rails 애플리케이션의 국제화/지역화를 위한 모든 필요한 수단을 제공합니다. 추가 기능이나 기능을 추가하기 위해 다양한 젬을 사용할 수도 있습니다. 자세한 내용은 rails-i18n 젬을 참조하세요.
Ruby on Rails의 I18n 작동 방식
국제화는 복잡한 문제입니다. 자연어는 (예: 복수형 규칙) 많은 면에서 서로 다르기 때문에 모든 문제를 한 번에 해결할 수 있는 도구를 제공하기는 어렵습니다. 이러한 이유로 Rails I18n API는 다음에 중점을 둡니다:
- 기본적으로 영어와 유사한 언어에 대한 지원 제공
- 다른 언어에 대해 모든 것을 쉽게 사용자 정의하고 확장할 수 있게 만들기
이 솔루션의 일부로, Rails 프레임워크의 모든 정적 문자열 - 예: Active Record 유효성 검사 메시지, 날짜 및 시간 형식 - 은 국제화되었습니다. 애플리케이션의 지역화는 이러한 문자열에 대한 번역된 값을 원하는 언어로 정의하는 것을 의미합니다.
애플리케이션의 콘텐츠(예: 블로그 게시물 번역)를 저장, 업데이트하려면 모델 콘텐츠 번역 섹션을 참조하세요.
라이브러리의 전반적인 아키텍처
따라서 Ruby I18n 젬은 두 부분으로 나뉩니다:
- I18n 프레임워크의 공개 API - 라이브러리가 작동하는 방식을 정의하는 공개 메서드가 포함된 Ruby 모듈
- 이러한 메서드를 구현하는 기본 백엔드(의도적으로 Simple 백엔드라고 명명됨)
사용자로서 항상 I18n 모듈의 공개 메서드만 액세스해야 하지만, 백엔드의 기능을 알고 있는 것이 유용합니다.
참고: 제공된 Simple 백엔드를 관계형 데이터베이스, GetText 사전 또는 유사한 것을 저장하는 더 강력한 백엔드로 교체할 수 있습니다. 다른 백엔드 사용 섹션을 참조하세요.
공개 I18n API
I18n API의 가장 중요한 메서드는 다음과 같습니다:
translate # 텍스트 번역 조회 localize # 로컬 형식으로 날짜 및 시간 개체 지역화
이들에게는 #t와 #l의 별칭이 있어 다음과 같이 사용할 수 있습니다:
I18n.t 'store.title' I18n.l Time.now
또한 다음 속성에 대한 속성 리더와 작성기가 있습니다:
load_path # 사용자 정의 번역 파일 알리기 locale # 현재 로케일 가져오기 및 설정 default_locale # 기본 로케일 가져오기 및 설정 available_locales # 애플리케이션에 사용 가능한 허용된 로케일 enforce_available_locales # 로케일 권한 적용(true 또는 false) exception_handler # 다른 exception_handler 사용 backend # 다른 백엔드 사용
따라서 다음 장에서 처음부터 Rails 애플리케이션에 대한 I18n 지원을 설정해 보겠습니다!
국제화를 위한 Rails 애플리케이션 설정
I18n 지원을 위해 Rails 애플리케이션을 실행하는 데는 몇 가지 단계가 필요합니다.
I18n 모듈 구성
규약 대 구성 철학을 따라, Rails I18n은 합리적인 기본 번역 문자열을 제공합니다. 다른 번역 문자열이 필요한 경우 이를 재정의할 수 있습니다.
Rails는 config/locales
디렉토리의 모든 .rb
및 .yml
파일을 번역 로드 경로에 자동으로 추가합니다.
이 디렉토리의 기본 en.yml
로케일에는 샘플 번역 문자열 쌍이 포함되어 있습니다:
en: hello: "Hello world"
이는 :en
로케일에서 hello 키가 Hello world 문자열에 매핑된다는 의미입니다. Rails 내부의 모든 문자열은 이와 같은 방식으로 국제화됩니다. 예를 들어 Active Model 유효성 검사 메시지는 activemodel/lib/active_model/locale/en.yml
파일에, 날짜 및 시간 형식은 activesupport/lib/active_support/locale/en.yml
파일에 있습니다. YAML 또는 표준 Ruby 해시를 사용하여 기본(Simple) 백엔드에 번역을 저장할 수 있습니다.
I18n 라이브러리는 영어를 기본 로케일로 사용할 것입니다. 즉, 다른 로케일이 설정되지 않은 경우 번역 조회에 :en
이 사용됩니다.
참고: i18n 라이브러리는 일부 토론 후 로케일 키에 대해 실용적인 접근 방식을 취합니다. 즉, :en
, :pl
, :th
또는 :es
(체코어, 태국어 및 스페인어용)과 같이 로케일(언어) 부분만 포함하고 지역(지역 설정) 부분은 포함하지 않습니다. :en-US
또는 :en-GB
와 같이 “언어"와 "지역 설정” 또는 “방언"을 구분하는 전통적인 방식을 사용합니다. 그러나 다양한 언어 그룹 내에서도 중요한 지역적 차이가 있을 수 있습니다. 예를 들어 :"en-US"
로케일에서는 통화 기호로 $를 사용하지만 :"en-GB"
에서는 £를 사용합니다. 지역 및 기타 설정을 이와 같이 구분하는 것을 막지 않습니다. 단순히 :"en-GB"
사전에 전체 "영어 - 영국” 로케일을 제공하면 됩니다.
번역 로드 경로(I18n.load_path
)는 자동으로 로드될 파일의 경로 배열입니다. 이 경로를 구성하면 번역 디렉토리 구조와 파일 명명 체계를 사용자 정의할 수 있습니다.
참고: 백엔드는 번역이 처음 조회될 때 이러한 번역을 지연 로드합니다. 이 백엔드는 번역이 이미 알려진 후에도 다른 것으로 교체할 수 있습니다.
기본 로케일과 번역 로드 경로를 config/application.rb
에서 다음과 같이 변경할 수 있습니다:
config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')] config.i18n.default_locale = :de
로드 경로는 번역을 조회하기 전에 지정되어야 합니다. 초기화기 대신 config/application.rb
에서 기본 로케일을 변경하려면:
# config/initializers/locale.rb # I18n 라이브러리가 번역 파일을 검색할 위치 I18n.load_path += Dir[Rails.root.join('lib', 'locale', '*.{rb,yml}')] # 애플리케이션에 허용되는 로케일 I18n.available_locales = [:en, :pt] # 기본 로케일을 :en 이외의 것으로 설정 I18n.default_locale = :pt
I18n.load_path
에 직접 추가하는 것이 아니라 애플리케이션의 구성된 I18n에 추가하는 것에 유의하세요. 그렇지 않으면 외부 젬의 번역을 재정의하지 않습니다.
요청 간 로케일 관리
다국어 애플리케이션은 여러 로케일을 지원해야 할 것입니다. 이를 달성하려면 모든 문자열이 해당 요청의 수명 동안 원하는 로케일을 사용하여 번역되도록 각 요청 시작 시 로케일을 설정해야 합니다.
기본 로케일은 I18n.locale=
또는 I18n.with_locale
을 사용하지 않는 한 모든 번역에 사용됩니다.
I18n.locale
은 모든 컨트롤러에서 일관되게 설정되지 않으면 동일한 스레드/프로세스에서 후속 요청으로 누출될 수 있습니다. 예를 들어 한 POST 요청에서 I18n.locale = :es
를 실행하면 로케일을 설정하지 않는 모든 후속 컨트롤러 요청에 영향을 미치지만 해당 특정 스레드/프로세스에서만 그렇습니다. 따라서 I18n.locale =
대신 I18n.with_locale
을계속:
ApplicationController
에서 around_action
을 사용하여 로케일을 설정할 수 있습니다:
around_action :switch_locale def switch_locale(&action) locale = params[:locale] || I18n.default_locale I18n.with_locale(locale, &action) end
이 예제는 URL 쿼리 매개변수를 사용하여 로케일을 설정하는 방법을 보여줍니다(예: http://example.com/books?locale=pt
). 이 접근 방식을 사용하면 http://localhost:3000?locale=pt
는 포르투갈어 지역화를, http://localhost:3000?locale=de
는 독일어 지역화를 로드합니다.
로케일은 여러 가지 다른 접근 방식을 사용하여 설정할 수 있습니다.
도메인 이름에서 로케일 설정
옵션 중 하나는 애플리케이션이 실행되는 도메인 이름에서 로케일을 설정하는 것입니다. 예를 들어 www.example.com
에서는 영어(또는 기본) 로케일을 로드하고 www.example.es
에서는 스페인어 로케일을 로드하고 싶습니다. 따라서 최상위 도메인 이름이 로케일 설정에 사용됩니다. 이에는 여러 가지 장점이 있습니다:
- 로케일이 URL의 명확한 부분입니다.
- 콘텐츠가 어떤 언어로 표시되는지 사람들이 직관적으로 이해할 수 있습니다.
- Rails에서 구현하기가 매우 간단합니다.
- 검색 엔진은 다른 언어의 콘텐츠가 서로 연결된 다른 도메인에 있는 것을 좋아하는 것 같습니다.
ApplicationController
에서 다음과 같이 구현할 수 있습니다:
around_action :switch_locale def switch_locale(&action) locale = extract_locale_from_tld || I18n.default_locale I18n.with_locale(locale, &action) end # TLD에서 로케일을 가져오거나 해당 로케일을 사용할 수 없는 경우 +nil+ 반환 # 로컬에서 이것을 시도하려면 /etc/hosts 파일에 다음과 같은 내용을 추가해야 합니다: # 127.0.0.1 application.com # 127.0.0.1 application.it # 127.0.0.1 application.pl def extract_locale_from_tld parsed_locale = request.host.split('.').last I18n.available_locales.map(&:to_s).include?(parsed_locale) ? parsed_locale : nil end
하위 도메인에서 로케일을 설정할 수도 있습니다:
# 요청 하위 도메인에서 로케일 코드 가져오기(예: http://it.application.local:3000) # 로컬에서 이것을 시도하려면 /etc/hosts 파일에 다음과 같은 내용을 추가해야 합니다: # 127.0.0.1 gr.application.local def extract_locale_from_subdomain parsed_locale = request.subdomains.first I18n.available_locales.map(&:to_s).include?(parsed_locale) ? parsed_locale : nil end
애플리케이션에 로케일 전환 메뉴가 포함된 경우 다음과 같이 표시할 수 있습니다:
link_to("Deutsch", "#{APP_CONFIG[:deutsch_website_url]}#{request.env['PATH_INFO']}")
이 솔루션에는 앞서 언급한 장점이 있지만 다른 도메인에서 다른 지역화(“언어 버전”)를 제공할 수 없거나 제공하고 싶지 않을 수 있습니다. 가장 명확한 솔루션은 URL 매개변수(또는 요청 경로)에 로케일 코드를 포함하는 것입니다.
URL 매개변수에서 로케일 설정
로케일을 설정(및 전달)하는 가장 일반적인 방법은 URL 매개변수에 포함하는 것입니다. 첫 번째 예에서 I18n.with_locale(params[:locale], &action)
aroundaction_과 같이 했습니다. 이 경우 www.example.com/books?locale=ja
또는 www.example.com/ja/books
와 같은 URL을 원할 것입니다.
이 접근 방식은 도메인 이름에서 로케일을 설정하는 것과 거의 같은 장점 집합을 가집니다. 즉, RESTful하고 World Wide Web의 나머지 부분과 일치합니다. 그러나 구현하는 데 약간 더 많은 작업이 필요합니다.
params
에서 로케일을 가져오고 이에 따라 설정하는 것은 어렵지 않습니다. 그러나 모든 URL에 명시적 옵션을 포함하고 따라서 요청을 통해 전달하는 것은 지루하고 거의 불가능할 것입니다.
Rails에는 ApplicationController#default_url_options
에서 “URL에 대한 동적 결정을 중앙 집중화"하는 인프라가 있으며, 이는 이 시나리오에서 정확히 유용합니다. 즉, url_for
및 이에 의존하는 헬퍼 메서드에 대한 "기본값"을 설정할 수 있습니다(default_url_options
구현/재정의).
그런 다음 ApplicationController
에 다음과 같은 내용을 포함할 수 있습니다:
# app/controllers/application_controller.rb def default_url_options { locale: I18n.locale } end
url_for
에 의존하는 모든 헬퍼 메서드(예: 명명된 경로 헬퍼 root_path
또는 root_url
, 리소스 경로 헬퍼 books_path
또는 books_url
등)는 이제 자동으로 쿼리 문자열에 로케일을 포함합니다. 예: http://localhost:3001/?locale=ja
.
이 방법으로 만족할 수 있습니다. 그러나 로케일이 모든 URL의 끝에 "매달려” 있어 URL 가독성에 영향을 미칩니다. 또한 아키텍처 관점에서 로케일은 일반적으로 애플리케이션 도메인의 다른 부분보다 계층적으로 높습니다. URL은 이를 반영해야 합니다.
다음과 같은 URL을 원할 것입니다: http://www.example.com/en/books
(영어 로케일 로드) 및 http://www.example.com/nl/books
(네덜란드어 로케일 로드). 위의 “defaulturloptions 재정의” 전략으로 이를 달성할 수 있습니다. 단순히 scope
를 사용하여 경로를 설정하면 됩니다:
# config/routes.rb scope "/:locale" do resources :books end
이제 books_path
메서드를 호출하면 기본 로케일의 "/en/books"
를 얻게 됩니다. http://localhost:3001/nl/books
와 같은 URL은 네덜란드어 로케일을 로드하고 이후 books_path
호출은 "/nl/books"
를 반환합니다(로케일이 변경되었기 때문).
경고. default_url_options
의 반환 값은 요청별로 캐시되므로, 각 반복에서 해당 I18n.locale
을 설정하는 루프에서 도우미를 호출하여 선택기의 URL을 생성할 수 없습니다. 대신 I18n.locale
을 변경하지 않고 명시적 :locale
옵션을 도우미에 전달하거나 request.original_fullpath
를 편집하세요.
경로에 로케일 사용을 강제하고 싶지 않은 경우 선택적 경로 범위(괄호로 표시)를 사용할 수 있습니다:
# config/routes.rb scope "(:locale)", locale: /en|nl/ do resources :books end
이 접근 방식을 사용하면 http://localhost:3001/books
와 같이 로케일을 지정하지 않고 리소스에 액세스할 때 Routing Error
가 발생하지 않습니다. 기본 로케일을 지정하지 않은 경우 사용하는 데 유용합니다.
물론 애플리케이션의 루트 URL(일반적으로 “홈페이지” 또는 “대시보드”)에 대해 특별한 주의를 기울여야 합니다. http://localhost:3001/nl
과 같은 URL은 자동으로 작동하지 않습니다. 왜냐하면 routes.rb
의 root to: "dashboard#index"
선언은 로케일을 고려하지 않기 때문입니다. (그리고 그렇게 해야 합니다: 루트 URL은 하나뿐입니다.)
다음과 같은 URL을 매핑해야 할 것입니다:
# config/routes.rb get '/:locale' => 'dashboard#index'
경로 순서에 특별히 주의를 기울이세요. 이 경로 선언이 다른 경로를 “먹어버리지” 않도록 해야 합니다. (이를 root :to
선언 바로 앞에 추가하는 것이 좋습니다.)
참고: 경로 작업을 단순화하는 다양한 젬을 살펴보세요: routing_filter, route_translator.
사용자 기본 설정에서 로케일 설정
인증된 사용자가 있는 애플리케이션은 사용자가 애플리케이션 인터페이스를 통해 로케일 기본 설정을 설정할 수 있도록 허용할 수 있습니다. 이 접근 방식에서는 사용자가 선택한 로케일 기본 설정이 데이터베이스에 저장되고 해당 사용자의 인증된 요청에 사용됩니다.
around_action :switch_locale def switch_locale(&action) locale = current_user.try(:locale) || I18n.default_locale I18n.with_locale(locale, &action) end
암시적 로케일 선택
요청에 명시적 로케일이 설정되지 않은 경우(위의 방법 중 하나를 통해) 애플리케이션은 원하는 로케일을 추론하려고 시도해야 합니다.
Accept-Language 헤더에서 로케일 추론
Accept-Language
HTTP 헤더는 요청 응답에 대한 선호 언어를 나타냅니다. 브라우저는 사용자의 언어 기본 설정에 따라 이 헤더 값을 설정하므로 로케일을 추론할 때 첫 번째 선택이 됩니다.
Accept-Language
헤더를 사용하는 간단한 구현은 다음과 같습니다:
def switch_locale(&action) logger.debug "* Accept-Language: #{request.env['HTTP_ACCEPT_LANGUAGE']}" locale = extract_locale_from_accept_language_header logger.debug "* Locale set to '#{locale}'" I18n.with_locale(locale, &action) end private def extract_locale_from_accept_language_header request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first end
실제로는 이 문제를 안정적으로 해결하기 위해 더 강력한 코드가 필요합니다. Iain Hecker의 httpacceptlanguage 라이브러리 또는 Ryan Tomayko의 locale Rack 미들웨어가 이 문제에 대한 솔루션을 제공합니다.
IP 지오로케이션에서 로케일 추론
요청을 보내는 클라이언트의 IP 주소를 사용하여 클라이계속:
IP 지오로케이션에서 로케일 추론
요청을 보내는 클라이언트의 IP 주소를 사용하여 클라이언트의 지역을 추론하고 따라서 해당 로케일을 추론할 수 있습니다. GeoLite2 Country 서비스 또는 geocoder 젬과 같은 서비스를 사용하여 이 접근 방식을 구현할 수 있습니다.
일반적으로 이 접근 방식은 언어 헤더를 사용하는 것보다 훨씬 신뢰할 수 없으며 대부분의 웹 애플리케이션에 권장되지 않습니다.
세션 또는 쿠키에서 로케일 저장
경고: 선택한 로케일을 세션 또는 쿠키에 저장하고 싶을 수 있습니다. 그러나 이렇게 하지 마세요. 로케일은 투명해야 하며 URL의 일부여야 합니다. 그렇지 않으면 웹 자체에 대한 기본 가정을 깨뜨리게 됩니다. 즉, 친구에게 URL을 보내면 동일한 페이지와 콘텐츠를 볼 수 있어야 합니다. 이를 RESTful이라고 하는 fancy 단어가 있습니다. *Stefan Tilkov의 기사에서 RESTful 접근 방식에 대해 자세히 알아보세요. 때로는 이 규칙의 예외가 있으며 아래에서 논의됩니다.
국제화 및 지역화
좋습니다! 이제 Ruby on Rails 애플리케이션에 대한 I18n 지원을 초기화하고 어떤 로케일을 사용할지, 요청 간에 어떻게 보존할지 알려주었습니다.
다음으로 모든 로케일 특정 요소를 추상화하여 Rails 애플리케이션을 국제화해야 합니다. 마지막으로 이러한 추상화에 대한 필요한 번역을 제공하여 지역화해야 합니다.
다음 예를 고려해 보겠습니다:
# config/routes.rb Rails.application.routes.draw do root to: "home#index" end
# app/controllers/application_controller.rb class ApplicationController < ActionController::Base around_action :switch_locale def switch_locale(&action) locale = params[:locale] || I18n.default_locale I18n.with_locale(locale, &action) end end
# app/controllers/home_controller.rb class HomeController < ApplicationController def index flash[:notice] = "Hello Flash" end end
<!-- app/views/home/index.html.erb --> <h1>Hello World</h1> <p><%= flash[:notice] %></p>
지역화된 코드 추상화
우리의 코드에는 응답에 렌더링될 두 개의 영어 문자열(“Hello Flash” 및 “Hello World”)이 있습니다. 이 코드를 국제화하려면 이러한 문자열을 각 문자열에 적절한 키를 사용하여 Rails의 #t
헬퍼로 대체해야 합니다:
# app/controllers/home_controller.rb class HomeController < ApplicationController def index flash[:notice] = t(:hello_flash) end end
<!-- app/views/home/index.html.erb --> <h1><%= t :hello_world %></h1> <p><%= flash[:notice] %></p>
이제 이 뷰가 렌더링되면 :hello_world
및 :hello_flash
키에 대한 번역이 누락되었다는 오류 메시지가 표시됩니다.
참고: Rails는 t
(translate
) 헬퍼 메서드를 뷰에 추가하므로 I18n.t
를 모두 작성할 필요가 없습니다. 또한 이 헬퍼는 누락된 번역을 캐치하고 결과 오류 메시지를 <span class="translation_missing">
으로 래핑합니다.
국제화된 문자열에 대한 번역 제공
번역 사전 파일에 누락된 번역을 추가합니다:
# config/locales/en.yml en: hello_world: Hello world! hello_flash: Hello flash!
# config/locales/pirate.yml pirate: hello_world: Ahoy World hello_flash: Ahoy Flash
default_locale
이 변경되지 않았기 때문에 번역은 :en
로케일을 사용하고 응답은 영어 문자열을 렌더링합니다:
URL을 통해 로케일을 해적 로케일(http://localhost:3000?locale=pirate
)로 설정하면 응답이 해적 문자열을 렌더링합니다:
참고: 새 로케일 파일을 추가할 때는 서버를 다시 시작해야 합니다.
YAML(.yml
) 또는 일반 Ruby(.rb
) 파일을 사용하여 SimpleStore에 번역을 저장할 수 있습니다. Rails 개발자 사이에서 YAML이 선호되는 옵션입니다. 그러나 큰 단점이 있습니다. YAML은 공백과 특수 문자에 매우 민감하므로 애플리케이션이 사전을 제대로 로드하지 못할 수 있습니다. Ruby 파일은 첫 번째 요청에 애플리케이션을 충돌시킬 것이므로 무엇이 잘못되었는지 쉽게 찾을 수 있습니다. (YAML 사전에서 “이상한 문제"가 발생하는 경우 관련 부분을 Ruby 파일에 넣어보세요.)
번역이 YAML 파일에 저장된 경우 특정 키는 이스케이프해야 합니다. 그것들은:
- true, on, yes
- false, off, no
예:
# config/locales/en.yml en: success: 'true': 'True!' 'on': 'On!' 'false': 'False!' failure: true: 'True!' off: 'Off!' false: 'False!'
I18n.t 'success.true' # => 'True!' I18n.t 'success.on' # => 'On!' I18n.t 'success.false' # => 'False!' I18n.t 'failure.false' # => Translation Missing I18n.t 'failure.off' # => Translation Missing I18n.t 'failure.true' # => Translation Missing
번역에 변수 전달
애플리케이션을 성공적으로 국제화하는 데 고려해야 할 핵심 사항 중 하나는 지역화된 코드를 추상화할 때 문법 규칙에 대한 잘못된 가정을 하지 않는 것입니다. 한 로케일에서 기본적으로 보이는 문법 규칙은 다른 로케일에서는 적용되지 않을 수 있습니다.
부적절한 추상화는 다음 예에서 보여줍니다. 여기서는 번역의 다양한 부분에 대한 순서 가정을 하고 있습니다. Rails는 다음 경우를 처리하기 위해 number_to_currency
헬퍼를 제공합니다.
<!-- app/views/products/show.html.erb --> <%= "#{t('currency')}#{@product.price}" %>
# config/locales/en.yml en: currency: "$"
# config/locales/es.yml es: currency: "€"
제품 가격이 10인 경우 스페인어에 대한 올바른 번역은 "10 €"이지만 추상화로는 이를 제공할 수 없습니다.
적절한 추상화를 위해 I18n 젬은 변수 보간이라는 기능을 제공합니다. 이를 통해 번역 정의에 변수를 사용하고 이러한 변수의 값을 번역 메서드에 전달할 수 있습니다.
적절한 추상화는 다음 예에서 보여줍니다:
<!-- app/views/products/show.html.erb --> <%= t('product_price', price: @product.price) %>
# config/locales/en.yml en: product_price: "$%{price}"
# config/locales/es.yml es: product_price: "%{price} €"
모든 문법 및 구두점 결정은 정의 자체에서 이루어지므로 추상화가 올바른 번역을 제공할 수 있습니다.
참고: default
및 scope
키워드는 예약되어 있으며 변수 이름으로 사용할 수 없습니다. 사용하면 I18n::ReservedInterpolationKey
예외가 발생합니다. 번역에 보간 변수가 필요하지만 #translate
에 전달되지 않은 경우 I18n::MissingInterpolationArgument
예외가 발생합니다.
날짜/시간 형식 추가
좋습니다! 이제 뷰에 타임스탬프를 추가하여 날짜/시간 지역화 기능도 데모할 수 있습니다. Time 개체를 I18n.l
또는(선호) #l
헬퍼에 전달하여 시간 형식을 지역화할 수 있습니다. :format
옵션을 전달하여 형식을 선택할 수 있습니다. 기본적으로 :default
형식이 사용됩니다.
<!-- app/views/home/index.html.erb --> <h1><%= t :hello_world %></h1> <p><%= flash[:notice] %></p> <p><%= l Time.now, format: :short %></p>
그리고 우리의 해적 번역 파일에 시간 형식을 추가해 보겠습니다(영어의 기본값에 이미 있습니다):
# config/locales/pirate.yml pirate: time: formats: short: "arrrround %H'ish"
그러면 다음과 같이 표시됩니다:
팁: 지금은 I18n 백엔드가 예상대로 작동하려면 다른 날짜/시간 형식을 더 추가해야 할 수 있습니다(적어도 ‘pirate’ 로케일의 경우). 물론 누군가가 이미 다양한 로케일에 대한 Rails의 기본값을 번역했을 가능성이 높습니다. GitHub의 rails-i18n 리포지토리에서 다양한 로케일 파일을 찾을 수 있습니다. config/locales/
디렉토리에 이러한 파일을 넣으면 자동으로 사용할 준비가 됩니다.
다른 로케일에 대한 변화 규칙
Rails를 통해 영어 이외의 로케일에 대한 변화 규칙(예: 단수화 및 복수화)을 정의할 수 있습니다. config/initializers/inflections.rb
에서 이러한 규칙을 여러 로케일에 대해 정의할 수 있습니다. 이 초기화기에는 영어에 대한 추가 규칙의 기본 예가 포함되어 있습니다. 필요에 따라 다른 로케일에 대해 해당 형식을 따르세요.
지역화된 뷰
BooksController가 애플리케이션에 있다고 가정해 보겠습니다. index 작업은 app/views/books/index.html.erb
템플릿에서 콘텐츠를 렌더링합니다. 이 템플릿의 지역화된 변형인 index.es.html.erb
를 동일한 디렉토리에 배치하면 로케일이 :es
로 설정된 경우 이 템플릿의 콘텐츠가 렌더링됩니다. 로케일이 기본 로케일로 설계속:
지역화된 뷰
BooksController가 애플리케이션에 있다고 가정해 보겠습니다. index 작업은 app/views/books/index.html.erb
템플릿에서 콘텐츠를 렌더링합니다. 이 템플릿의 지역화된 변형인 index.es.html.erb
를 동일한 디렉토리에 배치하면 로케일이 :es
로 설정된 경우 이 템플릿의 콘텐츠가 렌더링됩니다. 로케일이 기본 로케일로 설정된 경우 일반 index.html.erb
뷰가 사용됩니다. (향후 Rails 버전에서는 이 자동 지역화를 public
의 자산에도 적용할 수 있습니다.)
이 기능을 사용하면 예를 들어 정적 콘텐츠가 많은 경우 YAML 또는 Ruby 사전 내부에 넣는 것보다 편리할 수 있습니다. 그러나 나중에 템플릿을 변경하려면 모두에게 변경 사항을 전파해야 한다는 점을 유의하세요.
로케일 파일 구성
기본 SimpleStore와 함께 제공되는 i18n 라이브러리를 사용하는 경우 사전은 디스크의 일반 텍스트 파일에 저장됩니다. 애플리케이션의 모든 부분에 대한 번역을 하나의 파일에 넣는 것은 관리하기 어려울 수 있습니다. 의미 있는 계층 구조로 이러한 파일을 저장할 수 있습니다.
예를 들어 config/locales
디렉토리는 다음과 같이 보일 수 있습니다:
|-defaults |---es.yml |---en.yml |-models |---book |-----es.yml |-----en.yml |-views |---defaults |-----es.yml |-----en.yml |---books |-----es.yml |-----en.yml |---users |-----es.yml |-----en.yml |---navigation |-----es.yml |-----en.yml
이렇게 하면 모델 및 모델 속성 이름을 뷰 내부의 텍스트와 구분할 수 있고 이 모두를 "기본값”(예: 날짜 및 시간 형식)과 구분할 수 있습니다. i18n 라이브러리의 다른 저장소는 이러한 구분을 제공할 수 있는 다른 수단을 제공할 수 있습니다.
참고: Rails의 기본 로케일 로드 메커니즘은 여기와 같이 중첩된 사전을 로드하지 않습니다. 따라서 이 작업을 수행하려면 Rails에 명시적으로 추가해야 합니다:
# config/application.rb config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
I18n API 기능 개요
이제 i18n 라이브러리 사용에 대한 좋은 이해가 있고 기본 Rails 애플리케이션을 국제화하는 방법을 알고 있습니다. 다음 장에서는 이 기능을 더 자세히 다룰 것입니다.
이러한 장에서는 I18n.translate
메서드와 translate
뷰 헬퍼 메서드의 예를 모두 보여줄 것입니다(뷰 헬퍼 메서드가 제공하는 추가 기능 참고).
다음과 같은 기능이 다루어집니다:
- 번역 조회
- 번역에 데이터 보간
- 번역 복수화
- 안전한 HTML 번역 사용(뷰 헬퍼 메서드만)
- 날짜, 숫자, 통화 등 지역화
번역 조회
기본 조회, 범위 및 중첩 키
번역은 기호 또는 문자열 키로 조회할 수 있으므로 이러한 호출은 동등합니다:
I18n.t :message I18n.t 'message'
translate
메서드는 또한 번역 키에 대한 “네임스페이스” 또는 범위를 지정하는 데 사용할 수 있는 :scope
옵션을 받습니다:
I18n.t :record_invalid, scope: [:activerecord, :errors, :messages]
이는 Active Record 오류 메시지의 :record_invalid
메시지를 조회합니다.
또한 키와 범위를 모두 점으로 구분된 키로 지정할 수 있습니다:
I18n.translate "activerecord.errors.messages.record_invalid"
따라서 다음 호출은 모두 동등합니다:
I18n.t 'activerecord.errors.messages.record_invalid' I18n.t 'errors.messages.record_invalid', scope: :activerecord I18n.t :record_invalid, scope: 'activerecord.errors.messages' I18n.t :record_invalid, scope: [:activerecord, :errors, :messages]
기본값
:default
옵션이 제공되면 번역이 누락된 경우 해당 값이 반환됩니다:
I18n.t :missing, default: 'Not here' # => 'Not here'
:default
값이 기호인 경우 키로 사용되어 번역됩니다. 기본값으로 여러 값을 제공할 수 있습니다. 결과가 값인 첫 번째 항목이 반환됩니다.
예를 들어 다음은 먼저 :missing
키를 번역하려 하고 그 다음 :also_missing
을 번역하려 합니다. 둘 다 결과를 내지 않으므로 “Not here” 문자열이 반환됩니다:
I18n.t :missing, default: [:also_missing, 'Not here'] # => 'Not here'
벌크 및 네임스페이스 조회
여러 번역을 한 번에 조회하려면 키 배열을 전달할 수 있습니다:
I18n.t [:odd, :even], scope: 'errors.messages' # => ["must be odd", "must be even"]
또한 키가 (잠재적으로 중첩된) 그룹화된 번역 해시로 번역될 수 있습니다. 예를 들어 다음과 같이 모든 Active Record 오류 메시지를 해시로 받을 수 있습니다:
I18n.t 'errors.messages' # => {:inclusion=>"is not included in the list", :exclusion=> ... }
벌크 번역 해시에 보간을 수행하려면 deep_interpolation: true
매개변수를 전달해야 합니다. 다음과 같은 사전이 있는 경우:
en: welcome: title: "Welcome!" content: "Welcome to the %{app_name}"
설정 없이는 중첩 보간이 무시됩니다:
I18n.t 'welcome', app_name: 'book store' # => {:title=>"Welcome!", :content=>"Welcome to the %{app_name}"} I18n.t 'welcome', deep_interpolation: true, app_name: 'book store' # => {:title=>"Welcome!", :content=>"Welcome to the book store"}
“게으른” 조회
Rails는 뷰 내부에서 로케일을 조회하는 편리한 방법을 구현합니다. 다음과 같은 사전이 있는 경우:
es: books: index: title: "Título"
app/views/books/index.html.erb
템플릿 내부에서 books.index.title
값을 다음과 같이 조회할 수 있습니다(점 사용):
<%= t '.title' %>
참고: 부분별 자동 번역 범위 지정은 translate
뷰 헬퍼 메서드에서만 사용할 수 있습니다.
“게으른” 조회는 컨트롤러에서도 사용할 수 있습니다:
en: books: create: success: Book created!
이는 플래시 메시지를 설정하는 등에 유용합니다:
class BooksController < ApplicationController def create # ... redirect_to books_url, notice: t('.success') end end
복수화
많은 언어 - 영어를 포함 - 에는 주어진 문자열에 대해 단수와 복수의 두 가지 형태만 있습니다. 예를 들어 “1 message"와 "2 messages"입니다. 다른 언어(아랍어, 일본어, 러시아어 등)에는 복수 형태가 추가되거나 더 적습니다. 따라서 I18n API는 유연한 복수화 기능을 제공합니다.
:count
보간 변수는 번역에 보간되고 복수화 백엔드에 정의된 복수화 규칙에 따라 번역을 선택하는 데 특별한 역할을 합니다. 기본적으로 영어 복수화 규칙만 적용됩니다.
I18n.backend.store_translations :en, inbox: { zero: 'no messages', # optional one: 'one message', other: '%{count} messages' } I18n.translate :inbox, count: 2 # => '2 messages' I18n.translate :inbox, count: 1 # => 'one message' I18n.translate :inbox, count: 0 # => 'no messages'
:en
의 복수화 알고리즘은 다음과 같이 간단합니다:
lookup_key = :zero if count == 0 && entry.has_key?(:zero) lookup_key ||= count == 1 ? :one : :other entry[lookup_key]
:one
로 표시된 번역은 단수로, :other
는 복수로 간주됩니다. 카운트가 0이고 :zero
항목이 있는 경우 :other
대신 사용됩니다.
키 조회가 복수화에 적합한 해시를 반환하지 않으면 I18n::InvalidPluralizationData
예외가 발생합니다.
로케일 별 규칙
I18n 젬은 로케일별 규칙을 사용할 수 있는 Pluralization 백엔드를 제공합니다. 이를 Simple 백엔드에 포함하고 번역 저장소에 로컬화된 복수화 알고리즘을 i18n.plural.rule
로 추가합니다.
I18n::Backend::Simple.include(I18n::Backend::Pluralization) I18n.backend.store_translations :pt, i18n: { plural: { rule: lambda { |n| [0, 1].include?(n) ? :one : :other } } } I18n.backend.store_translations :pt, apples: { one: 'one or none', other: 'more than one' } I18n.t :apples, count: 0, locale: :pt # => 'one or none'
또는 rails-i18n 별도의 젬을 사용하여 더 완전한 로케일별 복수화 규칙을 제공할 수 있습니다.
로케일 설정 및 전달
로케일은 I18n.locale
에 의사-전역적으로 설정되거나(이는 Time.zone
과 같은 방식으로 Thread.current
를 사용합니다) #translate
및 #localize
에 옵션으로 전달될 수 있습니다.
로케일이 전달되지 않으면 I18n.locale
이 사용됩니다:
I18n.locale = :de I18n.t :foo I18n.l Time.now
명시적으로 로케일 전달:
I18n.t :foo, locale: :de I18n.l Time.now, locale: :de
I18n.locale
은 기본적으로 I18n.default_locale
(기본값: :en
)로 설정됩니다. 기본 로케일은 다음과 같이 설정할 수 있습니다:
I18n.default_locale = :de
안전한 HTML 번역 사용
‘_html’ 접미사가 있는 키와 ‘html'이라는 이름의계속:
안전한 HTML 번역 사용
’_html’ 접미사가 있는 키와 ‘html'이라는 이름의 키는 HTML 안전으로 표시됩니다. 이를 뷰에서 사용하면 HTML이 이스케이프되지 않습니다.
# config/locales/en.yml en: welcome: <b>welcome!</b> hello_html: <b>hello!</b> title: html: <b>title!</b>
<!-- app/views/home/index.html.erb --> <div><%= t('welcome') %></div> <div><%= raw t('welcome') %></div> <div><%= t('hello_html') %></div> <div><%= t('title.html') %></div>
보간은 필요한 경우 이스케이프됩니다. 예를 들어 다음과 같은 경우:
en: welcome_html: "<b>Welcome %{username}!</b>"
사용자가 설정한 사용자 이름을 안전하게 전달할 수 있습니다:
<%# 이것은 안전합니다. 필요한 경우 이스케이프됩니다. %> <%= t('welcome_html', username: @current_user.username) %>
반면 안전한 문자열은 문자 그대로 보간됩니다.
참고: 번역 텍스트를 자동으로 HTML 안전으로 변환하는 기능은 translate
(또는 t
) 헬퍼 메서드에서만 사용할 수 있습니다. 이는 뷰와 컨트롤러에서 작동합니다.
Active Record 모델에 대한 번역
Model.model_name.human
및 Model.human_attribute_name(attribute)
를 사용하여 모델 및 속성 이름에 대한 번역을 투명하게 조회할 수 있습니다.
예를 들어 다음과 같은 번역을 추가하면:
en: activerecord: models: user: Customer attributes: user: login: "Handle" # User 속성 "login"을 "Handle"로 번역합니다.
그러면 User.model_name.human
은 "Customer"를, User.human_attribute_name("login")
은 "Handle"을 반환합니다.
모델 이름의 복수형도 설정할 수 있습니다. 다음과 같이 추가하면 됩니다:
en: activerecord: models: user: one: Customer other: Customers
그러면 User.model_name.human(count: 2)
는 "Customers"를, User.model_name.human(count: 1)
또는 매개변수 없이는 "Customer"를 반환합니다.
주어진 모델 내의 중첩 속성에 액세스해야 하는 경우 모델 수준의 번역 파일에서 model/attribute
아래에 이를 중첩해야 합니다:
en: activerecord: attributes: user/role: admin: "Admin" contributor: "Contributor"
그러면 User.human_attribute_name("role.admin")
은 "Admin"을 반환합니다.
참고: ActiveModel
을 포함하고 ActiveRecord::Base
를 상속하지 않는 클래스를 사용하는 경우 위의 키 경로에서 activerecord
를 activemodel
로 바꾸세요.
오류 메시지 범위
Active Record 유효성 검사 오류 메시지도 쉽게 번역할 수 있습니다. Active Record는 모델, 속성 및/또는 유효성 검사에 대한 다른 메시지를 제공할 수 있도록 번역을 배치할 수 있는 몇 가지 네임스페이스를 제공합니다. 또한 단일 테이블 상속을 투명하게 고려합니다.
이를 통해 메시지를 애플리케이션의 요구 사항에 맞게 유연하게 조정할 수 있는 강력한 수단을 제공합니다.
다음과 같은 유효성 검사가 있는 User 모델을 고려해 보겠습니다:
class User < ApplicationRecord validates :name, presence: true end
이 경우 오류 메시지의 키는 :blank
입니다. 따라서 이 예에서는 다음 키를 순서대로 시도하고 첫 번째 결과를 반환합니다:
activerecord.errors.models.user.attributes.name.blank activerecord.errors.models.user.blank activerecord.errors.messages.blank errors.attributes.name.blank errors.messages.blank
더 추상적으로 설명하면 다음 목록의 첫 번째 일치하는 키를 반환합니다.
activerecord.errors.models.[model_name].attributes.[attribute_name].[key] activerecord.errors.models.[model_name].[key] activerecord.errors.messages.[key] errors.attributes.[attribute_name].[key] errors.messages.[key]
모델이 상속을 사용하는 경우 메시지는 상속 체인에서 조회됩니다.
예를 들어 Admin 모델이 User를 상속한다고 가정해 보겠습니다:
class Admin < User validates :name, presence: true end
그러면 Active Record는 다음 순서로 메시지를 찾습니다:
activerecord.errors.models.admin.attributes.name.blank activerecord.errors.models.admin.blank activerecord.errors.models.user.attributes.name.blank activerecord.errors.models.user.blank activerecord.errors.messages.blank errors.attributes.name.blank errors.messages.blank
이렇게 하면 모델 상속 체인의 다른 지점에서 다양한 오류 메시지에 대한 특별한 번역을 제공할 수 있습니다.
오류 메시지 보간
번역된 모델 이름, 번역된 속성 이름 및 값은 각각 model
, attribute
및 value
로 보간할 수 있습니다.
따라서 기본 오류 메시지 "cannot be blank"
대신 다음과 같이 속성 이름을 사용할 수 있습니다: "Please fill in your %{attribute}"
.
count
는 사용 가능한 경우 복수화에 사용할 수 있습니다:
유효성 검사 | 옵션 포함 | 메시지 | 보간 |
---|---|---|---|
confirmation | - | :confirmation | attribute |
acceptance | - | :accepted | - |
presence | - | :blank | - |
absence | - | :present | - |
length | :within, :in | :too_short | count |
length | :within, :in | :too_long | count |
length | :is | :wrong_length | count |
length | :minimum | :too_short | count |
length | :maximum | :too_long | count |
uniqueness | - | :taken | - |
format | - | :invalid | - |
inclusion | - | :inclusion | - |
exclusion | - | :exclusion | - |
associated | - | :invalid | - |
non-optional association | - | :required | - |
numericality | - | :notanumber | - |
numericality | :greater_than | :greater_than | count |
numericality | :greaterthanorequalto | :greaterthanorequalto | count |
numericality | :equal_to | :equal_to | count |
numericality | :less_than | :less_than | count |
numericality | :lessthanorequalto | :lessthanorequalto | count |
numericality | :other_than | :other_than | count |
numericality | :only_integer | :notaninteger | - |
numericality | :in | :in | count |
numericality | :odd | :odd | - |
numericality | :even | :even | - |
comparison | :greater_than | :greater_than | count |
comparison | :greaterthanorequalto | :greaterthanorequalto | count |
comparison | :equal_to | :equal_to | count |
comparison | :less_than | :less_than | count |
comparison | :lessthanorequalto | :lessthanorequalto | count |
comparison | :other_than | :other_than | count |
Action Mailer 이메일 제목에 대한 번역
mail
메서드에 제목을 전달하지 않으면 Action Mailer가 번역에서 찾으려고 시도합니다. 수행되는 조회는 <mailer_scope>.<action_name>.subject
패턴을 사용하여 키를 구성합니다.
# user_mailer.rb class UserMailer < ActionMailer::Base def welcome(user) #... end end
en: user_mailer: welcome: subject: "Welcome to Rails Guides!"
보간 매개변수를 전송하려면 메일러에서 default_i18n_subject
메서드를 사용합니다.
# user_mailer.rb class UserMailer < ActionMailer::Base def welcome(user) mail(to: user.email, subject: default_i18n_subject(user: user.name)) end end
en: user_mailer: welcome: subject: "%{user}, welcome to Rails Guides!"
국제화 지원을 제공하는 기타 기본 제공 메서드 개요
Rails는 고정 문자열 및 기타 지역화된 정보(예: 형식 문자열 및 기타 형식 정보)를 몇 가지 헬퍼에서 사용합니다. 간단한 개요는 다음과 같습니다.
Action View 헬퍼 메서드
distance_of_time_in_words
는 결과를 번역하고 복수화하며 초, 분, 시간 등의 수를 보간합니다. datetime.distanceinwords 번역을 참조하세요.datetime_select
및select_month
는 결과 선택 태그를 채우기 위해 번역된 월 이름을 사용합니다. date.month_names의 번역을 참조하세요.datetime_select
는 또한 date.order에서 순서 옵션을 조회합니다(명시적으로 옵션을 전달하지 않는 경우). 모든 날짜 선택 헬퍼는 datetime.prompts 범위의 번역을 사용하여 프롬프트를 번역합니다.number_to_currency
,number_with_precision
,number_to_percentage
,number_with_delimiter
및number_to_human_size
헬퍼는 number 범위의 숫자 형식 설정을 사용합니다.
Active Model 메서드
model_name.human
및human_attribute_name
은 activerecord.models 범위에 있는 모델 이름 및 속성 이름 번역을 사용합니다. 또한 위의 "오류 메시지 범위"에서 설명한 대로 상속 클래스 이름에 대한 번역을 지원합니다.ActiveModel::Errors#generate_message
(Active Model 유효성 검사에서 사용되지만 수동으로도 사용할 수 있음)는model_name.human
및human_attribute_name
(위 참조)을 사용합니다. 또한 오류 메시지를 번역하고 상속 클래스 이름에 대한 번역을 지원합니다.ActiveModel::Error#full_message
및ActiveModel::Errors#full_messages
는errors.format
(기본값:"%{attribute} %{message}"
)에서 조회한 형식을 사용하여 속성 이름을 오류 메시지에 접두사로 추가합니다. 기본 형식을 앱의 로케일 파일에서 재정의할 수 계속:ActiveModel::Error#full_message
및ActiveModel::Errors#full_messages
는errors.format
(기본값:"%{attribute} %{message}"
)에서 조회한 형식을 사용하여 속성 이름을 오류 메시지에 접두사로 추가합니다. 기본 형식을 앱의 로케일 파일에서 재정의할 수 있습니다. 모델 또는 속성별로 형식을 사용자 정의하려면config.active_model.i18n_customize_full_message
)를 참조하세요.
Active Support 메서드
Array#to_sentence
는 support.array 범위에 있는 형식 설정을 사용합니다.
사용자 정의 번역 저장
Active Support와 함께 제공되는 Simple 백엔드를 사용하면 번역을 일반 Ruby와 YAML 형식으로 모두 저장할 수 있습니다.[^2]
예를 들어 번역을 제공하는 Ruby 해시는 다음과 같이 보일 수 있습니다:
{ pt: { foo: { bar: "baz" } } }
동등한 YAML 파일은 다음과 같습니다:
pt: foo: bar: baz
보시다시피 두 경우 모두 최상위 키는 로케일입니다. :foo
는 네임스페이스 키이고 :bar
는 "baz” 번역에 대한 키입니다.
Active Support en.yml
번역 YAML 파일의 “실제” 예는 다음과 같습니다:
en: date: formats: default: "%Y-%m-%d" short: "%b %d" long: "%B %d, %Y"
따라서 다음과 같은 모든 등가 조회는 :short
날짜 형식 "%b %d"
를 반환합니다:
I18n.t 'date.formats.short' I18n.t 'formats.short', scope: :date I18n.t :short, scope: 'date.formats' I18n.t :short, scope: [:date, :formats]
일반적으로 YAML을 번역 저장 형식으로 사용하는 것이 좋습니다. 그러나 때로는 로케일 데이터의 일부로 Ruby 람다를 저장하려는 경우가 있습니다. 예를 들어 특수 날짜 형식의 경우 등입니다.
I18n 설정 사용자 정의
다른 백엔드 사용
여러 가지 이유로 Active Support와 함께 제공되는 Simple 백엔드는 Ruby on Rails에 대해 “가능한 가장 단순한 작업"만 수행합니다.[^3] 즉, 영어와 영어와 매우 유사한 언어에 대해서만 보장됩니다. 또한 Simple 백엔드는 번역을 동적으로 저장할 수 없고 읽기만 할 수 있습니다.
그렇다고 해서 이러한 제한에 갇혀 있는 것은 아닙니다. Ruby I18n 젬은 I18n.backend=
세터를 통해 Simple 백엔드 구현을 다른 것으로 쉽게 교체할 수 있게 해줍니다.
예를 들어 Simple 백엔드를 Chain 백엔드로 대체하여 여러 백엔드를 체인할 수 있습니다. 이는 표준 번역을 Simple 백엔드와 함께 사용하고 사용자 정의 애플리케이션 번역을 데이터베이스 또는 다른 백엔드에 저장하려는 경우 유용합니다.
Chain 백엔드를 사용하면 Active Record 백엔드를 사용하고 (기본) Simple 백엔드로 폴백할 수 있습니다:
I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend)
다른 예외 처리기 사용
I18n API는 해당 예기치 않은 조건이 발생할 때 백엔드에서 발생시킬 다음과 같은 예외를 정의합니다:
예외 | 이유 |
---|---|
I18n::MissingTranslationData |
요청된 키에 대한 번역이 없습니다 |
I18n::InvalidLocale |
I18n.locale 에 설정된 로케일이 잘못되었습니다(예: nil ) |
I18n::InvalidPluralizationData |
카운트 옵션이 전달되었지만 번역 데이터가 복수화에 적합하지 않습니다 |
I18n::MissingInterpolationArgument |
번역에 전달되지 않은 보간 인수가 필요합니다 |
I18n::ReservedInterpolationKey |
번역에 예약된 보간 변수 이름(즉, scope , default 중 하나)이 포함되어 있습니다 |
I18n::UnknownFileType |
백엔드가 I18n.load_path 에 추가된 파일 유형을 처리하는 방법을 모릅니다 |
I18n::MissingTranslationData
처리 방식 사용자 정의
config.i18n.raise_on_missing_translations
가 true
이면 I18n::MissingTranslationData
오류가 발생합니다. 누락된 번역이 요청되는 곳을 캐치할 수 있도록 테스트 환경에서 이 옵션을 켜는 것이 좋습니다.
config.i18n.raise_on_missing_translations
가 false
(모든 환경의 기본값)이면 예외의 오류 메시지가 인쇄됩니다. 이에는 누락된 키/범위가 포함되므로 코드를 수정할 수 있습니다.
이 동작을 더 사용자 정의하려면 config.i18n.raise_on_missing_translations = false
로 설정하고 I18n.exception_handler
를 구현해야 합니다. 사용자 정의 예외 처리기는 프로시저 또는 call
메서드가 있는 클래스일 수 있습니다:
# config/initializers/i18n.rb module I18n class RaiseExceptForSpecificKeyExceptionHandler def call(exception, locale, key, options) if key == "special.key" "translation missing!" # 이것을 반환하고 발생시키지 마세요 elsif exception.is_a?(MissingTranslation) raise exception.to_exception else raise exception end end end end I18n.exception_handler = I18n::RaiseExceptForSpecificKeyExceptionHandler.new
이렇게 하면 I18n.t("special.key")
의 경우를 제외하고 기본 처리기와 동일한 방식으로 모든 예외가 발생합니다.
모델 콘텐츠 번역
이 가이드에서 설명한 I18n API는 주로 인터페이스 문자열을 번역하는 데 사용됩니다. 모델 콘텐츠(예: 블로그 게시물)를 번역하려면 다른 솔루션이 필요합니다.
이 작업을 돕는 여러 젬이 있습니다:
- Mobility: 번역 테이블, JSON 열(PostgreSQL) 등 다양한 형식으로 번역을 저장할 수 있는 지원을 제공합니다.
- Traco: 모델 테이블 자체에 저장된 번역 가능한 열
결론
이 시점에서 Ruby on Rails의 I18n 지원이 어떻게 작동하는지 잘 알고 있으며 프로젝트 번역을 시작할 준비가 되었습니다.
Rails I18n에 기여
Ruby on Rails의 I18n 지원은 2.2 릴리스에 도입되었으며 여전히 발전 중입니다. 이 프로젝트는 Ruby on Rails 개발의 좋은 전통을 따라 실제 애플리케이션에서 먼저 솔루션을 발전시키고 가장 널리 유용한 기능만 핵심에 포함시킵니다.
따라서 우리는 모든 사람이 젬이나 다른 라이브러리에서 새로운 아이디어와 기능을 실험하고 이를 커뮤니티에 공개하도록 권장합니다. (우리의 메일링 리스트에 발표하는 것을 잊지 마세요!)
Ruby on Rails에 대한 예제 번역 데이터 리포지토리에 귀하의 로케일(언어)이 누락된 경우 fork하고 데이터를 추가한 다음 pull request를 보내주세요.
리소스
- Google 그룹: rails-i18n - 프로젝트의 메일링 리스트입니다.
- GitHub: rails-i18n - rails-i18n 프로젝트의 코드 리포지토리 및 이슈 트래커. 가장 중요한 것은 대부분의 경우 애플리케이션에 작동할 수 있는 많은 예제 번역을 찾을 수 있다는 것입니다.
- GitHub: i18n - i18n 젬의 코드 리포지토리 및 이슈 트래커.
저자
- Sven Fuchs(초기 저자)
- Karel Minařík
각주
[^1]: 또는 Wikipedia에서 인용하면: "국제화는 소프트웨어 애플리케이션을 설계하여 엔지니어링 변경 없이 다양한 언어와 지역에 적응할 수 있게 하는 프로세스입니다. 지역화는 로케일별 구성 요소를 추가하고 텍스트를 번역하여 특정 지역 또는 언어에 맞게 애플리케이션을 적응시키는 프로세스입니다.”
[^2]: 다른 백엔드는 다른 형식을 허용하거나 요구할 수 있습니다. 예를 들어 GetText 백엔드는 GetText 파일을 읽을 수 있습니다.
[^3]: 이러한 이유 중 하나는 국제화 기능이 필요하지 않은 애플리케이션에 대해 불필요한 부하를 발생시키지 않도록 I18n 라이브러리를 가능한 한 단순하게 유지해야 한다는 것입니다. 다른 이유는 모든 언어에 대한 모든 I18n 관련 문제를 한 번에 해결할 수 있는 솔루션을 구현하는 것이 사실상 불가능하다는 것입니다. 따라서 전체 구현을 쉽게 교체할 수 있는 솔루션이 적절합니다. 이렇게 하면 사용자 정의 기능 및 확장을 실험하기도 훨씬 쉽습니다.