I'm trying to create an HTML string using a view. I would like to render this from a class that is not a controller. How can I use the rails rendering engine outside a controller? Similar to how ActionMailer does?
Thanks!
I'm trying to create an HTML string using a view. I would like to render this from a class that is not a controller. How can I use the rails rendering engine outside a controller? Similar to how ActionMailer does?
Thanks!
Rails 5 now supports this in a much more convenient manner that handles creating a request and whatnot behind the scenes:
rendered_string = ApplicationController.render(
template: 'users/show',
assigns: { user: @user }
)
This renders app/views/users/show.html.erb
and sets the @user
instance variable so you don't need to make any changes to your template. It automatically uses the layout specified in ApplicationController
(application.html.erb
by default).
The test shows a handful of additional options and approaches.
You can use ActionView::Base to achieve this.
view = ActionView::Base.new(ActionController::Base.view_paths, {})
view.render(file: 'template.html.erb')
The ActionView::Base initialize takes:
assigns
hash, providing the variables for the templateIf you would like to include helpers, you can use class_eval to include them:
view.class_eval do
include ApplicationHelper
# any other custom helpers can be included here
end
There is no need to over bloat your app with too many gems. As we know ERB is already included in your Rails app.
@jdf = JDF.new
@job = ERB.new(File.read(Rails.root + "app/views/entries/job.xml.erb"))
result = @job.result(binding)
Above there is snippet of code of an app I'm working on.
@jdf
is a object to be evaluated in the erb
view. xml
.result
is a string to be saved or sent anywhere you like.Technically, ActionMailer
is a subclass implementation of AbstractController::Base
. If you want to implement this functionality on your own, you'll likely want to inherit from AbstractController::Base
as well.
There is a good blog post here: https://www.amberbit.com/blog/2011/12/27/render-views-and-partials-outside-controllers-in-rails-3/ that explains the steps required.
For future reference, I ended up finding this handy gem that makes this a breeze:
https://github.com/yappbox/render_anywhere
"I'm trying to create an HTML string using a view." -- If you mean you're in the context of a view template, then just use a helper method or render a partial.
If you're in some other "Plain Old Ruby Object", then keep in mind you're free to use the ERB module directly:
erb = ERB.new("path/to/template")
result = erb.result(binding)
The trick is getting that 'binding' object that gives the context for the code in the template. ActionController and other Rails classes expose it for free, but I couldn't find a reference that explains where it comes from.
http://www.ruby-doc.org/stdlib-2.2.0/libdoc/erb/rdoc/ERB.html#method-i-result
Best to render the view using a controller, as that's what they're for, and then convert it to a string, as that is your ultimate goal.
require 'open-uri'
html = open(url, &:read)