Use YAML with variables Use YAML with variables ruby ruby

Use YAML with variables


I had this same question, and after a lot of research, it looks like it's not possible.

The answer from cgat is on the right track, but you can't actually concatenate references like that.

Here are things you can do with "variables" in YAML (which are officially called "node anchors" when you set them and "references" when you use them later):

Define a value and use an exact copy of it later:

default: &default_title This Post Has No Titletitle: *default_title

{ or }

example_post: &example  title: My mom likes roosters  body: Seriously, she does. And I don't know when it started.  date: 8/18/2012first_post: *examplesecond_post:  title: whatever, etc.

For more info, see this section of the wiki page about YAML: http://en.wikipedia.org/wiki/YAML#References

Define an object and use it with modifications later:

default: &DEFAULT  URL:          stooges.com  throw_pies?:  true    stooges:  &stooge_list    larry:  first_stooge    moe:    second_stooge    curly:  third_stoogedevelopment:  <<: *DEFAULT  URL:      stooges.local  stooges:     shemp: fourth_stoogetest:  <<: *DEFAULT  URL:    test.stooges.qa  stooges:     <<: *stooge_list    shemp: fourth_stooge

This is taken directly from a great demo here: https://gist.github.com/bowsersenior/979804


After some search, I've found a cleaner solution wich use the % operator.

In your YAML file :

key : 'This is the foobar var : %{foobar}'

In your ruby code :

require 'yaml'file = YAML.load_file('your_file.yml')foobar = 'Hello World !'content = file['key']modified_content = content % { :foobar => foobar }puts modified_content

And the output is :

This is the foobar var : Hello World !

As @jschorr said in the comment, you can also add multiple variable to the value in the Yaml file :

Yaml :

key : 'The foo var is %{foo} and the bar var is %{bar} !'

Ruby :

# ...foo = 'FOO'bar = 'BAR'# ...modified_content = content % { :foo => foo, :bar => bar }

Output :

The foo var is FOO and the bar var is BAR !


This is an old post, but I had a similar need and this is the solution I came up with. It is a bit of a hack, but it works and could be refined.

require 'erb'require 'yaml'doc = <<-EOF  theme:  name: default  css_path: compiled/themes/<%= data['theme']['name'] %>  layout_path: themes/<%= data['theme']['name'] %>  image_path: <%= data['theme']['css_path'] %>/images  recursive_path: <%= data['theme']['image_path'] %>/plus/one/moreEOFdata = YAML::load("---" + doc)template = ERB.new(data.to_yaml);str = template.result(binding)while /<%=.*%>/.match(str) != nil  str = ERB.new(str).result(binding)endputs str

A big downside is that it builds into the yaml document a variable name (in this case, "data") that may or may not exist. Perhaps a better solution would be to use $ and then substitute it with the variable name in Ruby prior to ERB. Also, just tested using hashes2ostruct which allows data.theme.name type notation which is much easier on the eyes. All that is required is to wrap the YAML::load with this

data = hashes2ostruct(YAML::load("---" + doc))

Then your YAML document can look like this

doc = <<-EOF  theme:  name: default  css_path: compiled/themes/<%= data.theme.name %>  layout_path: themes/<%= data.theme.name %>  image_path: <%= data.theme.css_path %>/images  recursive_path: <%= data.theme.image_path %>/plus/one/moreEOF