Logan Serman
Logan Serman

Reputation: 29880

Can I render an ERB file to an HTML string inside of a gem (outside of ActionController::Base)?

I am making a gem that will generate a .html file inside of a Rails project's public/ directory. It will be used to automatically generate documentation from Cucumber scenarios.

It would be extremely convenient for me to be able to template the HTML file as ERB, that way I can pass in variables, have ERB do it's thing, then spit out the raw HTML to generate the file from.

I am aware of ActionController::Base#render_to_string, but within the gem I am obviously outside the scope of this method. Is there another way to do this? My other option is to define the markup in a heredoc, but I'd rather stay away from that if it's possible to just write ERB files.

Upvotes: 1

Views: 4144

Answers (3)

Nowaker
Nowaker

Reputation: 12412

Consider using ActionView instead of ERB if you want to access various helpers. Here's a fully working example of how to do this.

class MyClass
  def test
    render 'register_user', :jid => 'my login', :password => 'my password'
  end

  private
  def render template, **values
    templates_dir = "#{Rails.root}/app/lib/api"
    template_file = "#{template}.xml.erb"
    ActionView::Base.new(templates_dir).render \
        :file => template_file,
        :locals => values
  end
end

A template resides in app/lib/api and looks like this:

<query xmlns="archipel:xmppserver:users">
  <archipel action="register">
    <%= tag :user, :jid => jid, :password => password %>
  </archipel>
</query>

Upvotes: 3

Kyle
Kyle

Reputation: 22278

require 'erb'
ERB.new("Hello <%= 'World'%>").result

You could read the template file into a string, render with a new ERB instance and then write your static HTML.

If you need to use variables, you can supply a binding.

foo = :bar
ERB.new("Hello <%= foo%>").result(binding) # "Hello bar"

ERB docs

ERB#result

Upvotes: 1

Valery Kvon
Valery Kvon

Reputation: 4496

ActionView::Base.new(Rails.configuration.paths["app/views"].first).render(...)

Upvotes: 1

Related Questions