Is it possible to DRY up yaml?

3.2k Views Asked by At

I am using Rails' 4.1.4 YAML locale files to store some translations, for example:

en:
  words:
    en:
      passport: "passport"
      ticket: "ticket"
      train: "train"
de:
  words:
    en:
      passport: "passport"
      ticket: "ticket"
      train: "train"

With this I can use t("words.#{to_language}.train") to return train for a German user (I18n.locale == :de) who has chosen english as his to_language.

My question is: is there any way I can not repeat myself and have something like code below?

en OR de:
  words:
    en:
      passport: "passport"
      ticket: "ticket"
      train: "train"

Perhaps I can assign all the content of words to a variable and then just do:

en:
  all_words
de:
  all_words

Thanks

2

There are 2 best solutions below

0
On BEST ANSWER
all_words: &all_words
  words:
    en:
      passport: "passport"
      ticket: "ticket"
      train: "train"

en:
  <<: *all_words

de:
  <<: *all_words

And you course you can then specify the key and it will override the included default.

Checkout this SO that discusses what &, *, << mean.

0
On

Yes, YAML allows you to repeat nodes via reference. In particular, Ruby's YAML has something nonstandard called a "merge key", which will be useful in your particular situation.

For example, if you have, say:

base_fruits: &default # Alias the keys here into `default`.
  apple: one
  banana: two

then you can do

fruit_basket_one:
  <<: *default        # Include all the keys from the alias `default`.
  coconut: three      # Add another key too.

fruit_basket_two:
  <<: *default
  durian: five
  pear: six

So you can do something like:

en:
  words:
    en: &all_en_words
      passport: "passport"
      ticket: "ticket"
      train: "train"

de:
  words:
    en:
      <<: *all_en_words
      custom_word: "custom translation"

I would say that this probably isn't the right way to go about it, though. If a de user wants en translations, then they should just use en. Otherwise you will need an N^2 mapping for every pair of (actual language, desired language), instead of just a list of N translations, which is far easier to maintain.