views:

966

answers:

3

Hey guys, first post here, hope you can help me out.

We're generating a newsletter automatically every 24 hours using a rake task. There's a section at the top of the newsletter where an admin can put a customized message. The screen that the admin uses has a live preview of the newsletter (they were insistent on this), rendered using a haml partial that takes a collection.

In order to generate and send the emails, we are sending xml documents to a third party API that contain (among other things) the HTML for the email that we'd like to generate.

What I want to do is save the output of this haml partial within a rake task, something similar to PHP's ob_*() buffering functions. Is there any way to do something like the following:

ob_start();
render :partial => newsletter, :collection => posts
newsletter_html = ob_get_contents()
xml = "
<Creative>
  <Name>Our Newsletter -- #{Time.now.strftime('%m/%d/%Y')}</Name>
  <HTML>&lt;html&gt;&lt;body&gt;#{newsletter_html}&lt;/body&gt;&lt;/html&gt;</HTML>
  ...
</Creative>"

I'm probably missing something obvious, and I could think of a few ways to do this but most of them are not DRY and I don't want to be generating a lot of html in the helpers, models, or the task itself.

Let me know if there is a way for me to accomplish this. Thanks.

+1  A: 

A common way to do this (which is typically advised against) is to render into a string in your model or rake task:


cached_content = 
  ActionView::Base.new(Rails::Configuration.new.view_path).render(:partial => "newsletter", :locals => {:page => self,:collection => posts})

see here for a more full description: http://www.compulsivoco.com/2008/10/rendering-rails-partials-in-a-model-or-background-task/

If you are using page or fragment caching, you could pull the content out of the cache. The easiest way to do this is to just enable caching, and then look at where the files are being placed.

http://guides.rubyonrails.org/caching_with_rails.html

klochner
thanks a lot, that's exactly what I was looking for but now that you mention it, caching the newsletter would make a lot more sense for my application
Neil Sarkar
A: 

A bit of a shot in the dark but if you check out the rdoc for Haml it more than likely has a method which accepts a string and some variables and then renders the output.

With ERB it would look something like:

require 'erb'

name = 'world'
template = 'hello <%= name %>'
template = ERB.new(template)
puts template.result(binding)
Kris
+1  A: 

A more direct approach from the HAML docs:

require 'haml'
haml_string = "%p Haml-tastic!"
engine = Haml::Engine.new(haml_string)
engine.render #=> "<p>Haml-tastic!</p>\n"

You'll have to do a bit of work loading up the HAML template and setting up any local variables that need interpolation, but the flexibility may make up for that.

Nick Zadrozny