50

I want to use variables declared in yml file right there. For example, I declared site_name and want to use it below in description.

en:
  site_name: &site_name "Site Name"
  static_pages:
    company:
      description: *site_name #this works fine
      description: "#{*site_name} is an online system" #this doesn't work

How can I combine *site_name variable with additional text?

Paul Fioravanti
  • 16,423
  • 7
  • 71
  • 122
alex
  • 3,682
  • 3
  • 21
  • 22

3 Answers3

74

The short answer is, I believe, no you cannot do string interpolation in YAML the way you want using an alias.

In your case, what I would do is have something like the following in my locale file:

en:
  site_name: "Site Name"
  static_pages:
    company:
      description: ! '%{site_name} is an online system'

and then call in the appropriate view with the site name as a parameter:

t('.description', site_name: t('site_name'))

which would get you "Site Name is an online system".

However, if you're desperate to use aliases in your YAML file to concatenate strings together, the following completely unrecommended code would also work by having the string be two elements of an array:

en:
  site_name: &site_name "Site Name"
  static_pages:
    company:
      description:
        - *site_name
        - "is an online system"

and then you would join the array in the appropriate view like this:

t('.description').join(" ")

Which would also get you "Site Name is an online system".

However, before you decide to go down this path, apart from the question that @felipeclopes linked to, have a look at:

  • this StackOverflow answer regarding concatenating i18n strings (tl;dr Please don't for your translation team's sake).
  • StackOverflow questions here and here that are similar to your question.
Community
  • 1
  • 1
Paul Fioravanti
  • 16,423
  • 7
  • 71
  • 122
  • Thank you, Paul, for such detailed answer. Now I know about this trick with `join`, it may be useful. But summarize all options I choose to write the site name multiple times in .yml file. It doesn't accord to the DRY principle, but better then other tricky options. – alex Dec 19 '12 at 17:02
  • 1
    I realize this is rather old, but I'm curious as to the purpose of the bang (!) in "description: ! '%{site_name} is an online system'"? – Ryan Crews Feb 03 '14 at 22:10
6

You can use the following syntax, like in the example:

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

This example was taken from: Refactoring Ruby on Rails i18n YAML files using dictionaries

Community
  • 1
  • 1
felipeclopes
  • 4,010
  • 2
  • 25
  • 35
  • 1
    The question is about passing varaibles inside yml file, not from view to yml – alex Oct 24 '12 at 21:21
  • Sorry, so you can find the answer here: http://stackoverflow.com/questions/11097572/refactoring-ruby-on-rails-i18n-yaml-files-using-dictionaries Read the comments, it was not supported by the other persons that saw the solution. Hope this helps! – felipeclopes Oct 24 '12 at 21:42
  • Thx, it's usefull. Edit your answer pls "use & and * syntax" so then I can vote your answer up. But it's not the complete solution. I've edit my question. – alex Oct 24 '12 at 22:27
  • Answer edited. Thank you for accepting it and hope this helps you in the solution. – felipeclopes Oct 25 '12 at 11:26
  • I've voted it up, thank you. But can't accept, because this solution is not complete. I've edited question. – alex Oct 25 '12 at 11:32
0

Late to the party. I've created a gem that does exactly that. i18n-env-var-lookup

My specific use case is a bit unique though. In our org, we have an existing rails app that we wanted to "white-label" for another project by another team in the org. We wanted to share the same source code repo for both projects while only change the site name. Given that there are already a few thousands entries in the locale files and close to a hundred of them contain the site name, it would be a bad practice to update all the templates to pass the site name as a variable. Other suggestions that we found in related questions are also no good in our case. We want to keep the locale files exactly the same for both project so that we can avoid messing with the source code and manage the locale files easily with 3rd-party localization service.

Therefore I turned to implementing the gem, and it solves our exact problem.

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 23 '22 at 03:26