Ruby i18n - internationalization for ruby

26
INTERNATIONALIZATION FOR RUBY https://lingohub.com MADE WITH BY LINGOHUB RUBY i18n

Transcript of Ruby i18n - internationalization for ruby

Page 1: Ruby i18n - internationalization for ruby

INTERNATIONALIZATION FOR RUBY

https://lingohub.com MADE WITH BY LINGOHUB

RUBY i18n

Page 2: Ruby i18n - internationalization for ruby

INTERNATIONALIZATION FOR PLAIN RUBY: THE RUBY i18n GEM

− Ruby i18n allows translation and localization, interpolation of values to translations,

pluralization, customizable transliteration to ASCII, flexible defaults, bulk lookup, lambdas

as translation data, custom key/scope separator, and custom exception handlers.

− The gem is split in two parts:

− Public API

− Default backend

− YAML (.yml) or plain Ruby (.rb) files are used for storing translations in SimpleStore, still

YAML is the preferred option among Ruby developers.

https://lingohub.com MADE WITH BY LINGOHUB

Page 3: Ruby i18n - internationalization for ruby

INTERNATIONALIZATION AND THE YAML RESOURCE FILE FORMAT

KEY FEATURES OF YAML

− Information is stored in key-value pairs delimited with colon ( : )

− Keys can be nested (scoped)

− i18n expects the root key to correspond to the locale of the content

− The “leaf key” has to have a value

− Values can be escaped

− Correct and consistent line indentation is important for preserving the key hierarchy

https://lingohub.com MADE WITH BY LINGOHUB

Page 4: Ruby i18n - internationalization for ruby

INTERNATIONALIZATION AND THE YAML RESOURCE FILE FORMAT

KEY FEATURES OF YAML

− Lines starting with a hash tag sign ( # ) preceded with any number of white-space are

ignored by the parser (treated as a comment)

− Place-holder syntax is: %{name}, where “name” can consist of multiple non-white-space

characters

− UTF-8 encoding is usually used for YAML resource files

https://lingohub.com MADE WITH BY LINGOHUB

Page 5: Ruby i18n - internationalization for ruby

EXAMPLE YAML FILE

https://lingohub.com MADE WITH BY LINGOHUB

Page 6: Ruby i18n - internationalization for ruby

INSTALLATION AND SETUP

1. gem installation

2. Change the directory to the location

where the sample YAML file was saved

and start the irb (interactive ruby shell).

3. Check the current locale. (By default it

is English)

4. Changing it something else is easy.

gem  install  i18n

2.0.0p247  :001  >  require  ‘i18n’

=>  true

2.0.0p247  :002  >  I18n.locale

=>  :en

2.0.0p247  :003  >  I18n.locale  =  :de

=>  :de

https://lingohub.com MADE WITH BY LINGOHUB

Page 7: Ruby i18n - internationalization for ruby

TRANSALTION LOOKUP

− Lookup one of the phrases from our

YAML file example

− The translation is missing because we

haven’t loaded the file. Load all .yml and

.rb files in the current directory.

− Retry accessing the English translation

with the key ‘world’

2.0.0p247  :004  >  I18n.translate  :world,  

:scope  =>  ‘greetings.hello’

=>  “translation  missing:  en.hello.world”

2.0.0p247  :005  >  I18n.load_path  =  

Dir[‘./*.yml,  ‘./*.rb’]

=>  [“./en.yml”]

2.0.0p247  :006  >  I18n.translate  :world,  

:scope  =>  ‘greetings.hello’

=>  “Hello  world!”

https://lingohub.com MADE WITH BY LINGOHUB

Page 8: Ruby i18n - internationalization for ruby

TRANSALTION LOOKUP

− A local can also be explicitly passed

− When passing the phrase key, a symbol or

string can be used, and a scope can be an

array or dot-separated. Combinations of

them are valid too.

2.0.0p247   :007  >  I18n.translate   :world,  :scope  

=>  ‘greetings.hello’,   :locale  =>  :en

=>  “Hello  world!”

I18n.translate   ‘greetings.hello.world’

I18n.translate   ‘hello.world’,   :scope  =>  

:greetings

I18n.translate   ‘hello.world’,   :scope  =>  

‘greetings’

I18n.translate   :world,  :scope  =>  

‘greetings.hello’

I18n.translate   :world,  scope:  [:greetings,  

:hello]

https://lingohub.com MADE WITH BY LINGOHUB

Page 9: Ruby i18n - internationalization for ruby

TRANSALTION LOOKUP

− Translate the key :missing and the key

:also_missing

− Variables can be interpolated to the

translation

− Pass an array of keys to look up multiple

translations at once

− A key can translate to a hash of grouped

translations

2.0.0p247   :008  >  I18n.translate   :missing,  default:  [:also_missing,   ‘Not  here’]=>  ‘Not  here’

2.0.0p247   :009  >  I18n.translate   :user,  :scope  =>  [:greetings,   :hello],  :user  =>  ‘Ela’=>  “Hello  Ela!”

2.0.0p247   :010  >  I18n.translate   [:world,  :friend],   :scope  =>  [:greetings,   :hello]=>  [“Hello  World!”,  “Hello  Friend!”]

2.0.0p247   :011  >  I18n.translate   :hello,  :scope  =>  [:greetings]   =>  {:world=>”Hello   World!”,  :user=>”Hello   %{user}”,  :friend=>”Hello  Friend!”}

https://lingohub.com MADE WITH BY LINGOHUB

Page 10: Ruby i18n - internationalization for ruby

PLUARLIZATION OPTION IN i18n FOR RUBY

− The i18n API provides a flexible

pluralization feature adapting to the

different grammar of languages.

− The :count interpolation is interpolated to

the translation and used to pick a

pluralization from the translations

2.0.0p247  :012  >  I18n.translate  :messages,  

:scope  =>  :inbox,  :count  =>  1

=>  “You  have  one  message  in  your  inbox.”

2.0.0p247  :013  >  I18n.translate  :messages,  

:scope  =>  :inbox,  :count  =>  39

=>  “You  have  39  messages  in  your  inbox.”

https://lingohub.com MADE WITH BY LINGOHUB

Page 11: Ruby i18n - internationalization for ruby

SETTING UP DATE AND TIME LOCALIZATION

− Pass the Time object to I18n.localize to

localize the time format. Pick a format by

passing the :format option

2.0.0p247  :014  >  I18n.localize  Time.now

=>  “Wed,  14  Aug  2013  13:34:49  +0200”

2.0.0p247  :015  >  I18n.localize  Time.now,  

:format  =>  :short

=>  “14  Aug  13:34”

https://lingohub.com MADE WITH BY LINGOHUB

⟶ Instead of I18n.localize, a shorter alias can be used: I18n.l.

Page 12: Ruby i18n - internationalization for ruby

i18n – THE DEFAULT INTERNATIONALIZATION SOLUTION FOR RUBY ON RAILS

− Ruby adds all .rb and .yml files from the config/locales directory to translations load path

automatically.

− By default, Rials expects that all the resource files are kept in config/locales.

− You can change some settings by overriding the defaults in application.rb

− Organize the resource files in subdirectories

− Set :de as the default locale

− Set :en, :de and :fr as available locales

https://lingohub.com MADE WITH BY LINGOHUB

Config.i18n.load_path  +=  

Dir[Rails.root.join(‘config/locales/**/*.{rb,ym

l}’]

config.i18n.default_locale  =  :de

Config.i18n.available_locales  =  [:en,  :de,  :fr]

Page 13: Ruby i18n - internationalization for ruby

PASSING THE LOCALE AS A QUERY PARAMETER WITHIN THE URL

− Set the locale in before_action in the

ApplicationController

− This requires passing the locale as a URL

query parameter and adding it to all the

links within the application.

− Rails comes with a helper method that

can be overridden

before_action :set_locale

Def set_locale

I18n.locale  =  params[:locale]  ||  

I18n.default_locale

end

#  app/controllers/application_controller.rb

def default_url_options(options={})

{  :locale  =>  I18n.locale  }

end

https://lingohub.com MADE WITH BY LINGOHUB

Page 14: Ruby i18n - internationalization for ruby

PASSING THE LOCALE AS A PART OF THE URL PATH

It is cleaner to have the locale information

at the beginning of the path instead of the

end:

http://localhost:3000/sr/ vs http://localhost:

3000/?locale=sr.

You can do so with the “over-riding

default_url_options” strategy. Just set up the

routes with the scoping option.

#  config/routes.rb

scope  “(:locale)”,  locale:  /en|sr/  do

resources  :books

end

https://lingohub.com MADE WITH BY LINGOHUB

Page 15: Ruby i18n - internationalization for ruby

PASSING THE LOCALE AS A DOMAIN NAME OR A SUBDOMAIN

− Setting the locale from the domain name

or subdomain makes the locale very

obvious and search engines like this

approach too.

− Do so by adding a before_action to the

ApplicationController.

before_action :set_locale

def set_locale

#extracting from the domain name

I18n.locale  =  extract_locale_from_tld ||  I18n.default_locale  

#extracting from subdomain:  

#I18n.locale  =  extract_locale_from_subdomain ||  I18n.default_locale  

end  

def extract_locale_from_tld

parsed_locale =  request.host.split('.').last

I18n.available_locales.include?(parsed_locale.to_sym)  ?  

parsed_locale :  nil

end  

def extract_locale_from_subdomain

parsed_locale =  request.subdomains.first

I18n.available_locales.include?(parsed_locale.to_sym)  ?  

parsed_locale :  nil

end

https://lingohub.com MADE WITH BY LINGOHUB

Page 16: Ruby i18n - internationalization for ruby

SETTING THE LOCALE FROM CLIENT-SUPPLIED INFORMATION

− Information other than the page URL can

be used to set the appropriate locale for

the current user.

− An example for a trivial implementation of

using an Accept-Language header

https://lingohub.com MADE WITH BY LINGOHUB

I18n.locale  =  current_user.locale

def set_locale

I18n.locale  =  

extract_locale_from_accept_language_header

end  

private  

def extract_locale_from_accept_language_header

request.env['HTTP_ACCEPT_LANGUAGE'].scan(/

^[a-­‐z]{2}/).first  

end

Page 17: Ruby i18n - internationalization for ruby

TRANSLATION LOOKUP AND DATE/TIME LOCALIZATION BY RUBY ON RAILS

Rails adds t (translate) and l (localize) helper

methods to controllers. They will catch

missing translations and wrap the resulting

error message into a <span>.

#instead  of  I18n.translate  :hello

t  :hello

#instead  of  I18n.localize  Time.now

l Time.now

https://lingohub.com MADE WITH BY LINGOHUB

Page 18: Ruby i18n - internationalization for ruby

USING SAFE HTML TRANSLATIONS IN RUBY ON RAILS

− Keys with a ‘_html’ suffix and keys named

‘html’ are marked as HTML safe. Use

them without escaping.

#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>

https://lingohub.com MADE WITH BY LINGOHUB

Page 19: Ruby i18n - internationalization for ruby

TRANSLATION FOR ACTIVE RECORD MODELS

− Methods Model.model_name.human and

Model.human_attribute_name(attribute)

can be used to transparently look up

translations for model and attribute

names.

en:  

activerecord:

models:

user:  Dude

attributes:  

user:

login:  “Handle”

#  will  translate  User  

attribute  “login”  as  “Handle”

https://lingohub.com MADE WITH BY LINGOHUB

Page 20: Ruby i18n - internationalization for ruby

ERROR MESSAGE SCOPES

For example, if there is an ActiveRecord

model “User” that has the :presence

validation for :name, the key for the

message would be :blank. ActiveRecord will

look up for this key in several namespaces,

in this order:

activerecord.errors.models.[model_name].attr

ibutes.[attribute_name]

activerecord.errors.models.[model_name]

activerecord.errors.messages

errors.attributes.[attribute_name]

errors.messages

https://lingohub.com MADE WITH BY LINGOHUB

Page 21: Ruby i18n - internationalization for ruby

SENATRA AND PADRINO

https://lingohub.com MADE WITH BY LINGOHUB

I18n FOR

Page 22: Ruby i18n - internationalization for ruby

i18n FOR SINATRA

Set up Sinatra to use i18n gem for

internationalization

require  ‘i18n’

require  ’i18n/backend/fallbacks’

configure

I18n::Backend::Simple.send(:include,  

I18n::Backend::Fallbacks)

I18n.load_path,  Dir

[File.join(settings.root,  ‘locales’,  

‘*.yml’)]

I18n.backend.load_translations

end

https://lingohub.com MADE WITH BY LINGOHUB

Page 23: Ruby i18n - internationalization for ruby

i18n FOR SINATRA

before  ‘/:locale/*’   do

I18n.locale   =  params[:locale]

request.path_info =  ‘/’  +  

params[:splat   ]  [0]

end

before  do

if  (locale  =  

request.host.split(‘.’)[0])   !=  ‘www’

I18n.locale   =  locale

end

end

use  Rack::Locale

https://lingohub.com MADE WITH BY LINGOHUB

Passing the locale

− Specific URLs

− Dedicated subdomains

Page 24: Ruby i18n - internationalization for ruby

i18n FOR SINATRA

use  Rack::Locale

helpers   dodef t(*args)

I18n.t(*args)end

def l(*args)I18n.l(*args)

endend

helpers   dodef find_template(views,   name,   engine,   &block)

I18n.fallbacks[I18n.locale].each   {  |locale|  

super(views,  “#{name}.#{locale}”,   engine,   &block)}

super(views,   name,   engine,   &block)end

end

https://lingohub.com MADE WITH BY LINGOHUB

Passing the locale

− Browser preference (requires rack-contrib)

Page 25: Ruby i18n - internationalization for ruby

i18n FOR PADRINO

Localization is fully supported in

− padrino-core (date formats, time formats etc.)

− padrino-admin (admin language, orm fields, orm errors, etc.)

− padrino-helpers (currency, percentage, precision, duration, etc.)

Setting up the default locale in config/boot.rb

https://lingohub.com MADE WITH BY LINGOHUB

Padrino.before_load do

I18n.locale  =  :en

end

Page 26: Ruby i18n - internationalization for ruby

BROUGHT TO YOU BY LINGOHUB

ANJA OBERMÜLLERBUSINESS DEVELOPMENT & MARKETING AT LINGOHUB

[email protected]@LingoHub@anjaobermuellerRead the whole article.

https://lingohub.com MADE WITH BY LINGOHUB