sighmon / mjml-rails

MJML + ERb/Haml/Slim view template
https://mjml.io
Other
296 stars 64 forks source link

Rails Devise mailer does not work with mjml #47

Closed voordev closed 5 years ago

voordev commented 5 years ago

Devise for Rails does not work with mjml. The problem is it always tries the load the MJML format even when specifying format.text only!

this is my ApplicationMailer

class ApplicationMailer < ActionMailer::Base
  helper  :application
  layout "mailer" # i have /app/views/layouts/mailer.m
  append_view_path Rails.root.join('app', 'views', 'mailers') # i moved my mailer views from application_mailer to mailers folder
  default :from => "brand® <brand@outltd.ltd>"
end

This is DeviseMailer which is subclassed from the ApplicationMailer

class DeviserMailer < Devise::Mailer

  include Devise::Mailers::Helpers
  include Devise::Controllers::UrlHelpers
  layout "mailer"
  helper  :application

  def reset_password_instructions(record, token, opts={})
    @token = token
    devise_mail(record, :reset_password_instructions, opts)
    # this default mail method uses the mailer.mjml layout file
    # but overwriting this with format.text and a regular mail block like 
#mail(to: organisation.email, subject: subject) do |format|
  #    format.text
    #end
  end

end

So even with the format.text it will NOT load the mailer.text.erb layout file. Instead it tries to load the mailer.html.mjml layout file.

This mailer mjml layout file contains:

  <mj-head>
    <mj-preview></mj-preview>
    <%= render partial: "mailers/partials/head" %>
  </mj-head>

And it then breaks with a cannot find partial mailers/partials/head

Anyone have any idea how to resolve this? After moving to MJML our application is now out of password recovery because of this issue I have temporarily disabled password retrieval and hope this problem can be resolved. I cannot pinpoint the exact issue.

sighmon commented 5 years ago

@voordev I don't use a layout file, but here's what works for me:

# app/mailers/devise_mailer.rb
class DeviseMailer < Devise::Mailer
  def reset_password_instructions(record, token, opts={})
    # Logic to send the email with MJML
    @token = token
    @resource = record
    mail(
      :template_path => 'devise/mailer',
      :from => ENV["DEVISE_EMAIL_ADDRESS"], 
      :to => record.email, 
      :subject => "Reset password"
    ) do |format|
      format.mjml
      format.text
    end
  end
end
# app/views/devise/reset_password_instructions.mjml
<mjml>
  <mj-head>
    <mj-preview>Reset your password request</mj-preview>
  </mj-head>
  <mj-body>
    <mj-section>
      <mj-column>
        <mj-text>
          <p>Hello <%= @resource.email %>!</p>
        </mj-text>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>
# app/views/devise/reset_password_instructions.text.erb
Hello <%= @resource.email %>,
...
voordev commented 5 years ago

Above suggestions resolved the issues. Thank you.