raphael_turtle
raphael_turtle

Reputation: 7314

Allow user to create custom email template for ActionMailer in Rails

I want to allow the user of rails app to create their own email template via a form and use that as the sites standard email template form which mail will be sent but I can't find any tutorials, it also needs to contain a couple of dynamic variables.

Is there a defined way of doing this?

( so the user would enter the email text in a form referencing variables that would be evaluated before being sent )

Upvotes: 3

Views: 5257

Answers (4)

Pratik Bhagwat
Pratik Bhagwat

Reputation: 31

You can use panaromic gem to store the views in database. This will allow Rails to automatically search for associated views in database based on path column and the handler.

To make variables accessible through UI, liquid templates can be used. liquid-rails provides a way to use liquid templates as Rails views. Now if you update handler column to .liquid, you can store the views in database as liquid templates.

  1. Add model
class NotificationTemplate < ApplicationRecord
  store_templates
end
  1. Create template
NotificationTemplate.create(
  id: 1,
  body: "<p>Hi {{user_name}}, Thanks for your feedback</p>",
  path: "feedback_response_mailer/send_response_mail",
  locale: nil,
  handler: "liquid",
  partial: false,
  format: "html"
}
  1. Add mailer which uses liquid
class FeedbackResponseMailer < ApplicationMailer
  prepend_view_path NotificationTemplate.resolver
  def send_response_mail
    @user = User.find(params[:user_id])
    mail(to: @user.email, subject: 'Thank you')
  end
  def liquid_assigns
    { 'user_name' => @user.name }
  end
end

Upvotes: 3

mahemoff
mahemoff

Reputation: 46389

I would modify Yosep's idea to avoid using an actual erb template. Send the mail directly using a body arg as it's less performance overhead.

e.g.

def send_email(template, custom_values)
    body = template.template_text\
     .gsub(/@@name@@/, custom_values[:name])
     .gsub(/@@value@@/, custom_values[:value]
    mail subject: "Your subject goes here..", body: body
end

Upvotes: 1

Yosep Kim
Yosep Kim

Reputation: 2951

There are many ways you can achieve it. Here is one way.

First of all, you need to store user-generated email templates in a database.

CustomEmailTemplate.create(user_id: params[:user_id], template_body: params[:template_body])

When it's time to send an email for the template, you would do something like:

custom_values = { name: "Whatever", value: "nice" }
template = CustomEmailTemplate.find(template_id)
CustomerEmailer.send_email(template, custom_values).deliver

To make it really work, you need to do something like this in the mailer:

def send_email(template, custom_values)
    @template = template
    @custom_values = custom_values
    mail subject: "Your subject goes here.."
end

In the send_email.html.erb, do something like this:

<%= @template.template_text.gsub(/@@name@@/, @custom_values[:name]).gsub(/@@value@@/, @custom_values[:value]) %>

You see that the template contains "@@name@@" and "@@value@@". Those are the markers for you to be able to replace with custom values.

Of course, you can refactor this code to put the substitution logic in the model, etc, to make it "clean code".

I hope this helps.

Upvotes: 7

coderhs
coderhs

Reputation: 4837

Well easiest would be to store it into you rails database. So you should create a rails model called EmailTemplate which has a field body type text.

Next you create a form to update or create new templates.

To use this particular template and send it as an email. Create a Rails mailer, and in the view load the corresponding EmailTemplate. So in the view it would be as follows.

<%= EmailTemplate.find(id).body.html_safe %>

The above method is the easiest way to do this. If you want to let the user access various variables in your system as well then I recommend you look into liquid markup language (https://github.com/Shopify/liquid/).

Upvotes: 3

Related Questions