Part of this is coming from how convenient react has made it to have a small snipped of template code in with the component. Here is what I have so far:
# app/mailers/membership_mailer.rb
# frozen_string_literal: true
class MembershipMailer < ApplicationMailer
def one_week_expiration(member, renewal, org)
template = slim(%(
= content_for :header
= org.name
Hello, #{member.name},
br
Your membership for #{org.name} is set to expire at
#{renewal.expires_at.to_s(:short)}.
br
Please visit <a href=#{org.url}>#{org.url}</a> to purchase
a membership renewal.
br
br
))
subject = "Your membership for #{org.name} is going to expire soon"
mail(to: member.email, subject: subject) do |format|
# there isn't a slim renderer
format.html { render text: template }
end
end
end
I'm using this layout for all my emails, and it's set as the default layout application_mailer.
# app/views/layouts/email.html.slim
= stylesheet_link_tag "email"
header
.shell
h1 = yield :header
.shell
br
= yield :body
= yield
= render partial: "/shared/email_footer"
I want all the rendering methods in here, but what I'm struggling with is where to find / figure out how to build out the template for the mailer, the layout, and have all the variables I want accessible passed to the templates.
# app/mailers/application_mailer.rb
# frozen_string_literal: true
class ApplicationMailer < ActionMailer::Base
default from: APPLICATION_CONFIG['support_email']
layout 'email'
# taken from slim/test/block rendering / helper
def slim(source, options = {}, &block)
scope = options.delete(:scope)
locals = options.delete(:locals)
Slim::Template.new('', {}) { source }.render(scope, locals, &block)
end
end
Eventually, I'll have erb, arbre, etc.
So, in summary, I when I make the call to mail(...){...}, I'd like to be able to have my template defined in ruby, rather than in a template file, because I don't like have the mailer and template so far apart (in the file system.. why is outside the scope of this question, I just want to solve the problem of rendering in ruby for now).
Looks like the easiest way is to use render_anywhere which just makes a very stripped down controller, which then gives us access to the
render
method.So, my changes to my classes are as follows:
In my mailer
And then the important bit (in application_mailer)
And that's it.