Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you structure i18n yaml files in Rails?

I started populating an en yaml file in Rails and I can already tell it will get messy and out of hand before too long. Is there a convention to keeping this file organized?

So far I have this structure:

language:
  resource:
    pages: # index, show, new, edit
      page html elements: # h1, title
  activerecord:
    attributes:
      model:
        property:

Now I have the following things that I want to fit into this structure but I'm unsure how to:

  1. Navigation
  2. Button text (save changes, create account, etc)
  3. Error messages from controller flash
  4. How to add multi-word keys. Do I use a space or an underscore? For exmaple, t(".update button")) or t(".update_button")

Is there a convention to locale file structure?

like image 759
Mohamad Avatar asked Apr 23 '12 14:04

Mohamad


People also ask

What is i18n in Rails?

The Ruby I18n (shorthand for internationalization) gem which is shipped with Ruby on Rails (starting from Rails 2.2) provides an easy-to-use and extensible framework for translating your application to a single custom language other than English or for providing multi-language support in your application.

What is i18n t?

Internationalization (i18n) is the process of preparing software so that it can support local languages and cultural settings. An internationalized product supports the requirements of local markets around the world, functioning more appropriately based on local norms and better meeting in-country user expectations.

What is i18n and l10n?

Internationalization (i18n) is the process of developing products in such a way that they can be localized for languages and cultures easily. Localization (l10n), is the process of adapting applications and text to enable their usability in a particular cultural or linguistic market.


Video Answer


2 Answers

I've found that the best overall strategy is to somewhat reproduce the file structure so that given any translation, I can immediately find where it was called from. This gives me some kind of context for making the translation.

The majority of application translations are found in views, so my biggest top level namespace is usually views.

I create sub namespaces for the controller name and the action name or partial being used ex :

  • views.users.index.title
  • views.articles._sidebar.header

Both of these examples should make it obvious what part of my app we're translating and which file to look in to find it.

You mention navigation and buttons, if they are to be generic, then they belong in the views.application namespace just as do their view counterparts :

  • views.application._main_nav.links.about_us - a link in our app's main navigation partial
  • views.application.buttons.save
  • views.application.buttons.create - I have a bunch of these buttons ready to be used when needed

Flash messages are generated from the controller, so their top level namespace is... controllers! :)

We apply the same logic as we do to views :

  • controllers.users.create.flash.success|alert|notice

Again if you wanted to provide generic flash messages like "Operation successful", you would write something like this :

  • controllers.application.create.flash.notice

Finally, keys can be anything that is valid YAML, but please stick to using periods . as separators and underscores _ between words as a matter of convention.

The only thing left to sort out now, is getting rails' translations into its own namespace to clean up our top level :)

like image 118
tigrish Avatar answered Sep 25 '22 06:09

tigrish


I know that an answer has already been accepted, but this question provided me with some food for thought and I thought I'd share another structure for Rails i18n yml files for your consideration/criticism.

Given that I would like to

  1. keep the default app structure so I can use shorthand "lazy" lookups like t('.some_translation') in my views,
  2. avoid as much string repetition as possible, in particular with words that are not just the same, but also have identical contexts/meanings,
  3. only have to change a key once to have it reflected everywhere it's referenced,

for a config/locales/en.yml file that looks something like this:

activerecord:
  attributes:
    user:
      email: Email
      name: Name
      password: Password
      password_confirmation: Confirmation
  models:
    user: User
users:
  fields:
    email: Email
    name: Name
    password: Password
    confirmation: Confirmation
sessions:
  new:
    email: Email
    password: Password

I can see that there is significant repetition, and that the context of words like "Email" and "Password" are unambiguous and have the same meaning in their respective views. It would be a bit annoying to have to go and change them all if I decide to change "Email" to "e-mail", so I'd like to refactor the strings to reference a dictionary of some sort. So, how about adding a dictionary hash to the top of the file with some & anchors like this:

dictionary:
  email: &email Email
  name: &name Name
  password: &password Password
  confirmation: &confirmation Confirmation

activerecord:
  attributes:
    user:
      email: *email
      name: *name
      password: *password
      password_confirmation: *confirmation
  models:
    user: User
users:
  fields:  
    email: *email
    name: *name
    password: *password
    confirmation: *confirmation
sessions:
  new:
    email: *email
    password: *password

Whenever you get more than one instance of exactly the same word/phrase in your views, you could refactor it out to the dictionary. If the dictionary translation of a key in the base language doesn't make sense for a target language, then just change out the referenced value in the target language to a static string or add it as an extra entry to the target language's dictionary. I'm sure each language's dictionary could be refactored out into another file if they get too big and unwieldy.

This way of structuring i18n yaml files seemed to work well with some local test apps I tried it on. I'm hoping the wonderful Localeapp will provide support for this kind of anchoring/referencing in the future. But anyway, all this dictionary talk can't possibly be an original idea, so are there other issues with anchor referencing in YAML, or maybe just with the whole "dictionary" concept in general? Or is it just better to just rip out the default backend entirely and replace it with Redis or something?

like image 36
Paul Fioravanti Avatar answered Sep 24 '22 06:09

Paul Fioravanti