Yaml with Erb Is Not Parsing

YAML with erb is not parsing

You can't load a YAML file containing ERB like a basic YAML file. Checkout this post.

What you can do instead is (in a spec initializer or a before hook):

FIXTURE_CONFIG = YAML.load(ERB.new(File.read("#{Rails.root}/path_to_your_file.yml.erb")).result)

And then use this variable in your test.

Rails not picking up .yaml.erb fixtures?

UPDATE: turned out it's not a yaml parsing issue, when rails loads fixtures, you can also get argument errors, which if you are using dynamic yaml's can be coming from your models, in my case, it was a missing environment variable that broke the models which in return stopped the fixtures from loading.

How to read ERb when importing a .yml file in an initializer?

Your question is a little unclear, but it seems like you suspect the ERb (<%= ...) in your YAML file isn't being evaluated before the YAML is parsed in adauth.rb.

It would be easy enough to find out just by printing the value of AD_CONF["ad.bind_password"] in adauth.rb—but it does seem likely, since you're just calling YAML.load_file and never doing anything to parse the ERb. If you want to parse the ERb, you can see how Rails does it in Rails::Application::Configuration.database_configuration. The most important part is this:

yaml = Pathname.new(paths["config/database"].existent.first || "")
# ...snip...
YAML.load(ERB.new(yaml.read).result) || {}

Following this example, you would change the first line in adauth.rb to something like this:

ad_yaml_path = Rails.root.join('config/ad.yml')    # The path to the .yml file
ad_yaml = ERB.new( ad_yaml_path.read ).result # Read the file and evaluate the ERB
ad_hash = YAML.load(ad_yaml) # Parse the resulting YAML
AD_CONF = ad_hash[Rails.env]

(The first line works because Rails.root is a Pathname object, and Pathname#join also returns a Pathname, and Pathname#read works like File#read, returning the contents of the file.)

Of course, this can be shortened (you could make it a one-liner but that'd be pretty hard to read):

ad_yaml = ERB.new( Rails.root.join('config/ad.yml').read ).result
AD_CONF = YAML.load(ad_yaml)[Rails.env]

One more thing: Rails 4.2, which is now in beta, has a config_for method that does exactly this. Instead of the above you would just do this:

AD_CONF = Rails.application.config_for(Rails.root + 'config/ad.yml')

So that's neat.

How to embed a .yaml.erb into another .yaml.erb while keeping indentation?

You could do it this way.

parent.yaml.erb

name: parent
first:
second:
third: something
<%- content = ERB.new(File.read("child.yaml.erb"), nil, "-").result().gsub(/^/," ") -%>
<%= content -%>

child.yaml.erb

<% if some_condition -%>
a:
b:
c: <%= 2+2 %>
<% end -%>

Some explanation

  • I had to enable trim mode by passing nil and "-" as 2nd and 3rd arguments to ERB.new().
  • With trim mode enabled, I can trim unwanted white space using <$- and -%>.
  • I used gsub to indent by 4 spaces.

Of course, as noted in comments, it could be better to read the YAML data into memory as a hash, although I do realise you lose a lot of control of the output that way.

How to pass contents of a yml file to my erb template?

With help from http://ciaranm.wordpress.com/2009/03/31/feeding-erb-useful-variables-a-horrible-hack-involving-bindings/

Not super pretty, but if you hid the class away then it's not so bad. Downside is you'll probably run into problems calling other methods that don't exist in the ThingsForERB class so you'll want to think about that before just changing things over to use config['key1'] as Sergio suggested.

require 'erb'

config = {'key1' => 'aaa', 'key2' => 'bbb'}

class ThingsForERB
def initialize(hash)
@hash = hash.dup
end
def method_missing(meth, *args, &block)
@hash[meth.to_s]
end
def get_binding
binding
end
end

template = ERB.new <<-EOF
The value of key1 is: <%= key1 %>
The value of key2 is: <%= key2 %>
EOF
puts template.result(ThingsForERB.new(config).get_binding)

When run the output is:

  The value of key1 is: aaa
The value of key2 is: bbb

What's the correct way to read some data from a yaml file and use it in an erb page?

Create a config/initializers/load_colors.rb initializer file with these contents:

COLORS = YAML.load_file("#{Rails.root}/config/colors.yml")

This will load the contents of the configuration file into the COLORS variable when the Rails application starts. Then you can access the colours from anywhere within the application using COLORS['section_name']['white'] etc. For example, you could do:

<h1 style="color: <%= COLORS['h1']['blue'] %>;">Main Heading</h1>

—Although using an inline style like this within a view template isn't really good practice, but it gives you an idea of the usage.

parsing and composing YAML

In Yaml,, --- starts a new document in a Yaml stream, so in your quotes.yaml you have three separate documents and you’re only reading the first one.

What I think you want is something like this:

- quote: "This is a quote"
attribution: "Kate Something"
extras: "Braintree"

- quote: "Blah blah"
attribution: "Donna Doe"
extras: "Essex"

- quote: "Blah blah"
attribution: "Donna Doe"
extras: "Essex"

which is s single Yaml document containing a list of maps.



Related Topics



Leave a reply



Submit