Mange / roadie-rails

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

Roadie should extend module on Mail::Body instead of Mail object #14

Closed tomchentw closed 10 years ago

tomchentw commented 10 years ago

For gems like mail_view, it calls parts method on mail object, which returns an array of Mail::Body instances. But in Roadie::Rails::Automatic module, it extends email object directly and thus roadie won't inline email when rendering with mail_view.

tomchentw commented 10 years ago

A current quick & dirty fix to replace Roadie::Rails::Automatic module:

class YourAwesomeMailer < ActionMailer::Base
  module InlineOnBody
   attr_accessor :roadie_options

    def body
      options = roadie_options
      old_body = super
      if options.present? && old_body.present?
        # need to convert it back to a body object, don't know if it's proper to do so in all Rails environments
        ::Mail::Body.new(::Roadie::Rails::DocumentBuilder.build(old_body.decoded, options).transform)
      else
        old_body
      end
    end
  end

  module RoadieRailsAutomaticView
    def mail(*args, &block)
      super.tap do |email|
        email.parts.select { |part| part.content_type.to_s.match /text\/html/ }.each do |part|
          part.extend InlineOnBody
          part.roadie_options = roadie_options.try(:dup)
        end
      end
    end

    def roadie_options
      ::Rails.application.config.roadie
    end
  end

  include RoadieRailsAutomaticView

  def awesome
    mail(to: 'roadie@awesomegems.com', ...)
  end
end
tomchentw commented 10 years ago

It's interesting that include Roadie::Rails::Mailer don't have this problem.

Mange commented 10 years ago

That's because Mailer inlines immediately, while Automatic only inlines on delivery. This is by design, and I don't want to change it I'm afraid.

One motivation for this is that if you are previewing an email in your browser, you get to use the standard <link rel="stylesheet"> element like normal. If you really want to make sure it works like intended and you only want to see the end result, I suggest looking into a mail previewer that operates using the delivery_method config (so emails are delivered to it) or that you start using Mailer.

Would it be helpful with a new module that fits in-between Automatic and Mailer? One that just replaces mail with roadie_mail? It's easy to do yourself:

class MyMailer < ActionMailer::Base
  include Roadie::Rails::Mailer
  alias mail roadie_mail
end