1

I have some html content stored in a database field. I would like trusted admins in our system to be able to edit the HTML when needed. Eventually this html will be converted into an email message and sent to users. In addition to the static html content, the email message has a first and last name that is stored in an active record model.

I was hoping to leave the <%= user.firstname user.lastname %> inside the HTML text when the admins are editing the content and then eventally combine the content with embedded erb the email renderer. I have the part where the admins can save the HTML working fine.

However, even ignoring the email and just trying to render to a normal web page, I am not able to get a view to correctly substitute the embedded <%= ... %> with the information from the database. I always see the <%= ... %> instead of the substituted text. I have tried render_to_string, render :inline, etc.

In summary, I am trying to:

  1. Take some html text with embedded some erb from the database
  2. Run the text through a template where the embedded erb is replaced with the variables passed into locals
  3. Take the resulting text block and either email it to users or display on a web page depending on my needs

The problem is that the results always have the <%= ... %> in it instead of the substitutions.

In an example controller I have:

 def showit
    @storedhtml = mymodel.savedhtml
    @emailtext = render_to_string( template: 'e.html.erb',
      layout: false, locals: { user:@user })
   end

The e.html.erb contains:

<%= raw @storedhtml %>

and the showit.html.erb has:

= raw @emailtext

I have also tried using inline like this:

def showit
     # the line below is substituted but the <p> tags are not converted
    @stuff = "<%= '<p>testme</p>' + user.firstname %>"  
    @storedhtml = mymodel.the_html_content
    @output = render( inline: @storedhtml, locals: { user:@user }, layout: true )
end

3 Answers 3

5

In a controller you wouldn't use Erb syntax, you'd use normal Ruby string interpolation:

@stuff = "#{'<p>testme</p>'} #{user.firstname}"
# Or, since the HTML isn't dynamic:
@stuff = "<p>testme</p> #{user.firstname}"

And to output it in the view you'd need to use html_safe:

<%= @stuff.html_safe %>

In general, generating HTML directly in the controller isn't a great idea since there are other mechanisms in place, and it creates another place to look when you're trying to figure out what component creates which HTML.

Edit I misunderstood. Another templating engine like Sameera suggested is one option, or just evaluate the DB value as an erb template using your current binding.

You could also create a template resolution component that would allow retrieval directly from the DB if no file is found; the Crafting Rails Applications book discusses this.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much for your help and your detailed response. I was able to get this working for my needs with Liquid. I am interested in other solutions as well though and I will look at the Crafting Rails Applications book and read their discussion.
1

I guess what you need is 'liquid' - it's a template language for Rails.

Check this out:

http://liquidmarkup.org/

http://railscasts.com/episodes/118-liquid

1 Comment

Thank you - I was able to get this working with Liquid. I will post my results here as an answer in case it will help others.
0

Assuming you have a Model with attribute named "template" which returns some html template (with ERB), if you want to render it you can use something like this into your controller's action:

render inline:"<%= raw ERB.new(@your_var.template).result(binding) %>".html_safe, layout:'application'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.