Namespaced View Translations

ViewTranslations are a very handy way of translating all of your content that isn’t represented by an ActiveRecord model, which is actually quite a lot of content.

And they work great:


#In es locale

"translate me".t => "Traduceme" 

"%s, can you translate this?" / 'saimon' => '¿Saimon, puedes traducir esto?'

"%d translations" / 0 => "No hay traducciónes" 
"%d translations" / 1 => "1 traducción" 
"%d translations" / 10 => "10 traducciónes" 

But imagine you’re using view translations all over the place in your application.

You use them to translate the static content of your view templates. You use them to translate the urls in your links. You use them to translate your administration interface.

After a while the list of translations starts to become a bit too unwieldy.

Let’s say that you decide to bring in professional translators, who may be decidedly non technical, to translate your site’s content.

You point them to your new spiffy, paginated, searchable list of words/phrases to be translated and leave them to it.

The day after your boss phones you up and bellows:

- None of the site’s links are working in Slovenian?

Oops! You start to investigate and find that the stupid translators, went ahead and translated:


'section' => 'sección' (In Spanish)

which you were using to translate the url:


http://example.com/section => http://example.com/seccion

- Jeez, don’t translators know you can’t use non-ascii characters in urls?

- Umm, well no. They’re translators. That’s your job.

- Ah, well, ok I’ll just give them a list of words that are urls and should be translated without accents.

- But we use the word ‘section’ in the view as well…

- ummm… Let me think….. (time passes)

- Also we need the site in Greek which has a lot of strange characters. And come to think of it, this list of urls is getting pretty hard to maintain.

-Well, what we need is to be able to have two sorts of translation of the word ‘section’, one for the front end and one for the urls.

Using namespaced view translations

And that’s what namespaced view translations are all about:


#In es locale

"section".t         => "sección"  #The default translation with no namespace

"section" >> 'urls' => "seccion"  #The translation in the 'urls' namespace
or
"section".tn(:urls)
or
"draw".translate_with_namespace(:urls)

#The translation in the 'admin' namespace
"section" >> 'admin' => "sección" 

# Text interpolation of the translation in the 'admin' namespace
"%s, can you translate this?".tn(:admin, 'saimon') => '¿Saimon, puedes traducir esto?'

#Numeric interpolation of the translation in the 'admin' namespace with a zero value
"%d translations".tn(:admin, 0) => "No hay traducciónes" 

#Numeric interpolation of the translation in the 'admin' namespace with non-zero values
"%d translations".tn(:admin, 1) => "1 traducción" 
"%d translations".tn(:admin, 10) => "10 traducciónes" 

#Translation in the 'admin' namespace with a default value if no
#translation is available
"should be translated".tn(:admin,nil, 'untranslated') => "untranslated" 

Adding namespaced view translations to the database

Adding translations with namespaces to the database uses a differently named method but is basically the same syntax as Locale.set_translation:


Locale.set('es-ES')

#No namespace
Locale.set_translation("section", "sección")

#With namespace 'urls'
Locale.set_translation_with_namespace("section", "urls", "seccion")

or adding translations with plural forms:


Locale.set('es-ES')

#No namespace
Locale.set_translation("draw %d times", "dibujar una vez", "dibujar %d veces")

#With namespace 'lottery'
Locale.set_translation_with_namespace("draw %d times", "lottery", "seleccionar una vez", "seleccionar %d veces")

Filtering translations by namespace

Once you have view translations categorised under different namespaces, you’ll most likely want to create a friendly interface for your translators so that they don’t translate phrases in the ‘urls’ namespace for example and can concentrate on the translations of the front-end.


url_translations = ViewTranslations.find(:all, :conditions => {:namespace => 'urls', :language => spanish})

Of course that’s very simplistic and you’d probably want to also distinguish between translations with plural forms, paginate etc but you get the idea.

Upgrading your schema

I needed to change the globalize view_translations table and add an extra varchar column to support namespaced view translations. So in order to use the for-1.2 release with your application, you need to upgrade your schema.

If you install the for-1.2 release via:


script/plugin install http://svn.globalize-rails.org/svn/globalize/branches/for-1.2

then the plugin’s install hook will automatically update your globalize tables for you if they already exist.

If you don’t use the script/plugin install method, then you can simply run the following rake task which does the same thing:


rake globalize:upgrade_schema_to_1_dot_2

If this is the first time you’re installing Globalize then just run the default globalize setup rake task:


rake globalize:setup

That concludes this article. Watch out for the next article in the series where I’ll be talking about Globalize::SupportedLocales, a class that encapsulates the idea of an application’s supported locales.


Επέστρεψε στο άρθρα