How to create a mailer template in a .rb file (without a template file)

Part of this comes from how a convenient reaction made him have a small piece of template code with a component. Here is what I still have:

# 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 use this layout for all my emails and it is set as the default layout for 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 to be here, but I'm trying to find / figure out how to create a template for the mailer, layout and all the variables that I want to get are 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 

In the end, I will have erb, arbre, etc.

So, in general, when I make a call to mail (...) {...}, I would like my template to be defined in ruby, and not in the template file, because I don’t like that the mail program and the template is still separated from each other (in the file system .. why is it beyond the scope of this question, I just want to solve the problem of rendering in ruby ​​at the moment).

+5
source share
1 answer

It seems like the easiest way is to use render_anywhere , which just makes a very truncated controller, which then gives us access to render .

So my changes in my classes are as follows:

In my mail program

  def one_week_expiration(member, renewal, org) template_environment = { org: org, member: member, renewal: renewal } template = slim(env: template_environment) do %q( = content_for :header = org.name h3 Hello, #{member.name}, | 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 ) end subject = "Your membership for #{org.name} is going to expire soon" mail(to: member.email, subject: subject) do |format| format.html { render text: template } end end 

And then the important bit (in application_mailer)

 require 'render_anywhere' class ApplicationMailer < ActionMailer::Base layout 'email' default from: APPLICATION_CONFIG['support_email'] def slim(env: {}) raise 'No Block Given' unless block_given? RenderAnywhere::RenderingController.new.render_to_string( inline: yield, layout: 'email', type: :slim, locals: env ) end end 

What is it.

0
source

Source: https://habr.com/ru/post/1261889/


All Articles