Slide 1

Slide 1 text

Globalizing Rails Jeremy Voorhis Lead Architect, www.jvoorhis.com www.planetargon.com

Slide 2

Slide 2 text

What is Globalization? • Internationalization • Localization

Slide 3

Slide 3 text

Internationalization (i18n) • Preparation of software to be useful in multiple locales • Strings - dynamic and static • Bidirectional strings • Dates, times and numbers • is it 123,456.78 or 123.456,78?

Slide 4

Slide 4 text

Localization (L10n) • Providing translated content for a specific language • Implementing designs from right to left • Formatting dates, times and numbers for a specific region • Content that is sensitive to your audience’s culture

Slide 5

Slide 5 text

Locales • Operating definition: a combination of a language and a region • Can be identified with a locale tag • Globalize understands locales

Slide 6

Slide 6 text

Locale tags • Locale tags follow RFC 3066 • Language-Tag = Primary-subtag *( "-" Subtag ) Primary-subtag = 1*8ALPHA Subtag = 1*8(ALPHA / DIGIT) • Primary-subtag is an ISO 639 language code and should be lowercase • Subtag is typically an ISO 3166 country code and should be CAPITALIZED • Sometimes you have to wing it

Slide 7

Slide 7 text

Example productions • en-US • fr-CA • es-419

Slide 8

Slide 8 text

Unicode • Unpopular in Japan, and not natively supported by Ruby • Support available through jcode module • require ‘jcode’ $KCODE = ‘u’ • Your database must support unicode too!

Slide 9

Slide 9 text

What is Globalize? • A Rails plugin providing internationalization services to a Rails application • Model translations • View translations • Date and time translations and formatting • Number formatting

Slide 10

Slide 10 text

API • core extensions • String#t • String#/(number) • ActiveRecord macro • ActiveRecord::Base::translates

Slide 11

Slide 11 text

Getting started

Slide 12

Slide 12 text

Installing Globalize $ svn export http://svn.globalize-rails.org/svn/ globalize/globalize/branches/for-1.1 vendor/plugins/globalize $ rake globalize:setup

Slide 13

Slide 13 text

Setting the base language # config/environment.rb Globalize::Locale.set_base_language 'en-US'

Slide 14

Slide 14 text

Capturing locales # config/routes.rb map.connect ':locale/:controller/:action/:permalink'

Slide 15

Slide 15 text

Setting an active locale class ApplicationController < ActionController::Base before_filter :set_locale private def set_locale Locale.set params[:locale] rescue ArgumentError redirect_to params.merge( 'locale' => 'en-US' ) end end

Slide 16

Slide 16 text

Using model translations # Table "public.features" # Column | Type #-------------+----------------------------- # id | integer # headline | character varying(255) # abstract | text # body | text # permalink | text # created_at | timestamp without time zone # modified_at | timestamp without time zone class Feature < ActiveRecord::Base translates :headline, :abstract, :body end

Slide 17

Slide 17 text

Using view translations <%# GLobalize style %>

<%= 'FEATURES'.t -%>

<%# gettext style %>

<%= :features.t -%>

Slide 18

Slide 18 text

Advanced techniques • Predicated blocks • Translation availability helper

Slide 19

Slide 19 text

The predicated block <% base_language_only do %> <%= link_to 'Destroy', { :action => 'destroy', :id => record.id }, { :post => true, :confirm => 'Are you sure?' } %> <% end %>

Slide 20

Slide 20 text

The predicated block defined def base_language_only yield if Locale.base? end def not_base_language yield unless Locale.base? end

Slide 21

Slide 21 text

Notify users when a translation is not available

Slide 22

Slide 22 text

A Translation Availability Helper <%= translation_availability_for :page, :body %> <%= markdown @page.body %>

Slide 23

Slide 23 text

Translation availability helper defined def translation_availability_for object_name, facet, message = nil not_base_language do message ||= content_tag 'p', '(Translation not available)'.t object = instance_variable_get "@#{object_name}" message if object and not object.send( facet ).blank? and object.send( "#{facet}_is_base?" ) end end

Slide 24

Slide 24 text

A gallery of practical interface design • Switching locales • Providing reference text • Bidirectional views • View translations

Slide 25

Slide 25 text

Make it easy for users to switch locales

Slide 26

Slide 26 text

Locale selector for public site

Slide 27

Slide 27 text

The same helper is used in the admin site

Slide 28

Slide 28 text

Translation interface with English reference

Slide 29

Slide 29 text

Base language administration screen params[:locale] # => ‘en-US’

Slide 30

Slide 30 text

Hide untranslated fields and provide a reference params[:locale] # => ‘zh-Hant’

Slide 31

Slide 31 text

Bidirectional views

Slide 32

Slide 32 text

English text is read left to right http://www.rashgash.co.il/en

Slide 33

Slide 33 text

Hebrew text is read right to left http://www.rashgash.co.il/

Slide 34

Slide 34 text

Make it easy for translators to update string literals in your views

Slide 35

Slide 35 text

Admin users can switch locales and update strings Translations provided by Google ;)

Slide 36

Slide 36 text

Globalize something • www.globalize-rails.org • Wiki • Mailing list • globalize.rubyforge.org • API Docs

Slide 37

Slide 37 text

Alternatives • Localization plugin • static text translation • Fluxiom • gettext • ubiquitous • interoperable

Slide 38

Slide 38 text

Acknowledgments • Joshua Harvey • Joshua Sierles • Per Wigren • Contributors!