Render ERB from data file

I have a YAML data file with information about some products.

One of the product fields is a description. In that description I have found the need to link to other products. The only way I could think of doing this is with the link_to helper but I am having trouble getting the description field to be rendered as a block of ERB code.

Data file (products.yml)

- Widget1
  description: Widget1 is very similar to <%= link_to "widget2", data.products["Widget2"] %>
- Widget2
  description: Has nice features. 

View file (index.html.slim)

p
  | Product description: 
  = function_to_render_erb(data.products["Widget1"].description)

Technically, the link_to is a bit more complicated because I have to run the product through my custom get_url() helper function, so it is more like link_to "widget2", get_url(data.products["Widget2"]) but I hope that won’t be an issue.

I am open to putting the description in a separate file and then storing the location of that file in the YAML data if that makes it easier.

What I am trying to do seems similar to what people do with markdown sometimes using
Tilt['markdown'].new { source }.render

I managed to get the separate file solution working without much fuss but because my text is limited to about 200 characters it would really be nice if I could keep it in the data file rather than a separate file.

Here’s what I’m doing now. Basically, I just created a partial for each product description:

Data file

- Widget1
  description_file: products/_widget1

Partial (products/_widget1.erb)

Widget1 is very similar to <%= link_to "widget2", data.products["Widget2"] %>

View file (index.html.slim)

p
  | Product description: 
  = partial data.products["Widget1"].description_file

If it is your goal to be able to use a helper or embed some Ruby code in general in your yaml data files, I wrote a simple helper that does this:

helpers do
  def eval_str(str)
    eval "%Q[#{str}]"
  end
end

Example:

data/test.yml:

content: |
  This is a #{link_to 'link', 'test.html'}.

source/index.html.erb:

<p>
  <%= eval_str data.test.content %>
</p>

Hope this helps.

1 Like

Thank you so much!

That is exactly what I was trying to do.

In fact, your answer clears up another issue I was having that I was simply prepared to work around but that was still bothering me: the use of # in the YAML file.

I had resorted to using erb syntax in my yaml file (despite using slim everywhere else) because the slim #{ .. } syntax was being interpreted as a comment. I see that you are able to circumvent that by using the | character and a line break. I will have to remember that trick.

Thanks again. I really appreciate it :slight_smile:

You’re welcome. You can also use double quotes to circumvent the # issue:

content: "Data: #{variable}"