Mange / roadie-rails

Making HTML emails comfortable for the Rails rockstars
MIT License
363 stars 65 forks source link

How do I use roadie in a controller instead of a mailer? #61

Closed kriskhaira closed 8 years ago

kriskhaira commented 8 years ago

I'd like to use roadie in a controller action (not a mailer). The use case for this is to display the HTML of a template at a URL where an external API can go to the URL of the template to grab the HTML source to use in an email.

How do I do this with roadie?

Mange commented 8 years ago

You can either generate a new email and display the body of it in a controller action (basically "render text: Mailer.foo.body.decoded" ), or you could use plain vanilla Roadie yourself. The Roadie docs show you how to do that.

Note that you cannot use the AutomaticMailer if you want to render the inlined body somewhere. Use the normal Mailer instead.

Let me know if you need more than these pointers.

Den tis 10 maj 2016 19:36Kris Khaira notifications@github.com skrev:

I'd like to use roadie in a controller action (not a mailer). The use case for this is to display the HTML of an email at a URL where an external developer can go to view the template and grab the HTML source of the email.

How do I do this with roadie?

— You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub https://github.com/Mange/roadie-rails/issues/61

kriskhaira commented 8 years ago

@Mange Thanks for the quick reply.

Note that you cannot use the AutomaticMailer if you want to render the inlined body somewhere. Use the normal Mailer instead.

By AutomaticMailer, you mean Roadie::Rails::Automatic, right? And what do you mean use the normal Mailer?

You can either generate a new email and display the body of it in a controller action (basically "render text: Mailer.foo.body.decoded" )

In other words, I should create a mailer, move the view there and then use the mailer template from the controller action, right? Will include Roadie::Rails::Automatic work in this case then?

Mange commented 8 years ago

Sorry for not being clearer. I'm on my phone.

By AutomaticMailer, you mean Roadie::Rails::Automatic, right? And what do you mean use the normal Mailer?

Yes, that is correct. I forgot about the naming for a second there. Automatic only inlines when the email is delivered, not when it's generated. If you use Roadie::Rails::Mailer instead, you get to control when to inline the email by calling roadie_mail instead of mail inside your mailer class. There are examples of mailers in the README.

In other words, I should create a mailer, move the view there and then use the mailer template from the controller action, right?

Not quite. You could do something like this (again, excuse my brevity):

class ExampleMailer < ApplicationMailer
  include Roadie::Rails::Mailer
  def example
    # assuming you have a example_mailer/example.html template
    roadie_mail
  end
end

class ExampleMailPreviewsController < ApplicationController
  def show
    render text: ExampleMailer.example.body.decoded
  end
end

In case you're not actually dealing with actual emails now, this is a huge indirection and you might be better off to just use roadie instead of roadie-rails. Then it'd be something like this:

class ExamplePreviewsController < ApplicationController
  def show
  end
end
<%# show.html.erb %>
<h1>Here's your preview:</h1>
<%= inline_html(render("example_contents")) %>

<%# _example_contents.html.erb %>
<p>Foo</p>
class HtmlInliningHelper
  def inline_html(html)
    inlined = Roadie.new(html).transform
    Nokogiri::HTML(inlined).at_css("body").inner_html
  end
end

Does that clear it up for you? :-)

kriskhaira commented 8 years ago

@Mange That makes a lot of sense. Thanks for the detailed explanation. My team might go with roadie-rails because we might be using the template in our own mailers in the future.

kriskhaira commented 8 years ago

In case anyone finds this thread—we went with the roadie-rails solution and moved the view to a mailer; and then called it from the controller using .body.decoded like @Mange suggested. Works great. Thanks for your help, @Mange!