effective_email_templates 1.0.11 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd45246572ae7b8d6eab683d911aba2fb4d74e2b9ac9f805fb6faea71ebef8b6
4
- data.tar.gz: b37ed1adc75b8773d6c5caa57510e434b4537c2512bc63d1adf7b36d1ebe2939
3
+ metadata.gz: 633c93cac11add92db1adcfdd7d2441dbf928f12abc4182798e4c66d93995fe3
4
+ data.tar.gz: 85d947fcfd9da53aa93cf0b7e43e677633f250167a43afc67b1c6a71dc376a54
5
5
  SHA512:
6
- metadata.gz: 93297ce10d8e17183bd52a0c89cf393c42182a7ac4875669ac375f775a9a166770d7d6ffec1f7c9c385e4f40cb8f74e2f240ad2d428bc8b09dd2b4d8ddaaf5c4
7
- data.tar.gz: 16a24643ba98a5ad269071eb992e3c73ae7f4d02cbab1c331b083cce8d45ad231e8c8a22a554e547aa94fb748aa98d62f5199a8391f6723778e889b50e5d8b03
6
+ metadata.gz: 4e8ed05ed566941bb48fe9ec8be95bfc4d2019b7dbbee3fd0d282fd7c01061e5e51cfc13468bd466fc09c60b1f95ad8088db37af5095eb2fdb4929c6539bd993
7
+ data.tar.gz: '089e9291f52db8749cb282b2b087e162acb30c9b0c61da47d5e489a4ab18affd5f77e36aa5018f036efcde410f3ecb1594923c93fa3e57c5ccdb7211f70647f4'
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2020 Code and Effect Inc.
1
+ Copyright 2021 Code and Effect Inc.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -114,67 +114,21 @@ EmailTemplatesMailer.welcome(user).deliver
114
114
 
115
115
  ## Authorization
116
116
 
117
- All authorization checks are handled via the config.authorization_method found in the `app/config/initializers/effective_email_templates.rb` file.
117
+ All authorization checks are handled via the effective_resources gem found in the `config/initializers/effective_resources.rb` file.
118
118
 
119
- It is intended for flow through to CanCan or Pundit, but neither of those gems are required.
120
-
121
- This method is called by all controller actions with the appropriate action and resource
122
-
123
- Action will be one of [:index, :show, :new, :create, :edit, :update, :destroy]
124
-
125
- Resource will the appropriate Effective::EmailTemplate object or class
126
-
127
- The authorization method is defined in the initializer file:
128
-
129
- ```ruby
130
- # As a Proc (with CanCan)
131
- config.authorization_method = Proc.new { |controller, action, resource| authorize!(action, resource) }
132
- ```
133
-
134
- ```ruby
135
- # As a Custom Method
136
- config.authorization_method = :my_authorization_method
137
- ```
138
-
139
- and then in your application_controller.rb:
140
-
141
- ```ruby
142
- def my_authorization_method(action, resource)
143
- current_user.is?(:admin) || EffectivePunditPolicy.new(current_user, resource).send('#{action}?')
144
- end
145
- ```
146
-
147
- or disabled entirely:
148
-
149
- ```ruby
150
- config.authorization_method = false
151
- ```
152
-
153
- If the method or proc returns false (user is not authorized) an Effective::AccessDenied exception will be raised
154
-
155
- You can rescue from this exception by adding the following to your application_controller.rb:
156
-
157
- ```ruby
158
- rescue_from Effective::AccessDenied do |exception|
159
- respond_to do |format|
160
- format.html { render 'static_pages/access_denied', :status => 403 }
161
- format.any { render :text => 'Access Denied', :status => 403 }
162
- end
163
- end
164
- ```
165
119
 
166
120
  ### Permissions
167
121
 
168
122
  To allow a user to see the admin area, using CanCan:
169
123
 
170
124
  ```ruby
171
- can :manage, Effective::EmailTemplate
125
+ can [:index, :edit, :update, :destroy], Effective::EmailTemplate
172
126
  can :admin, :effective_email_templates
173
127
  ```
174
128
 
175
129
  ## License
176
130
 
177
- MIT License. Copyright [Code and Effect Inc.](http://www.codeandeffect.com/)
131
+ MIT License. Copyright [Code and Effect Inc.](http://www.codeandeffect.com/)
178
132
 
179
133
 
180
134
  ## Contributing
@@ -1,87 +1,19 @@
1
1
  module Admin
2
2
  class EmailTemplatesController < ApplicationController
3
- before_action :authenticate_user! if respond_to?(:authenticate_user!)
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_email_templates) }
4
5
 
5
- layout (EffectiveEmailTemplates.layout.kind_of?(Hash) ? EffectiveEmailTemplates.layout[:admin_email_templates] : EffectiveEmailTemplates.layout)
6
+ include Effective::CrudController
6
7
 
7
- def index
8
- @datatable = EffectiveEmailTemplatesDatatable.new
9
- @page_title = 'Email Templates'
10
-
11
- authorize_effective_email_templates!
12
- end
13
-
14
- def new
15
- @email_template = Effective::EmailTemplate.new
16
- @page_title = 'New Email Template'
17
-
18
- authorize_effective_email_templates!
19
- end
20
-
21
- def create
22
- @email_template = Effective::EmailTemplate.new(email_template_params)
23
- @page_title = 'New Email Template'
24
-
25
- authorize_effective_email_templates!
26
-
27
- if @email_template.save
28
- flash[:success] = 'Successfully created email template'
29
- redirect_to effective_email_templates.admin_email_templates_path
30
- else
31
- flash.now[:danger] = 'Unable to create email template'
32
- render :new
33
- end
34
- end
35
-
36
- def edit
37
- @email_template =
38
- Effective::EmailTemplate.where(id: params[:id]).or(
39
- Effective::EmailTemplate.where(template_name: params[:id])
40
- ).first!
41
-
42
- @page_title = 'Edit Email Template'
43
-
44
- authorize_effective_email_templates!
8
+ if (config = EffectiveEmailTemplates.layout)
9
+ layout(config.kind_of?(Hash) ? config[:admin] : config)
45
10
  end
46
11
 
47
- def update
48
- @email_template = Effective::EmailTemplate.find(params[:id])
49
- @page_title = 'Edit Email Template'
50
-
51
- authorize_effective_email_templates!
52
-
53
- if @email_template.update(email_template_params)
54
- flash[:success] = 'Successfully updated email template'
55
- redirect_to effective_email_templates.admin_email_templates_path
56
- else
57
- flash.now[:danger] = 'Unable to update email template'
58
- render :edit
59
- end
60
- end
61
-
62
- def destroy
63
- @email_template = Effective::EmailTemplate.find(params[:id])
64
-
65
- authorize_effective_email_templates!
66
-
67
- if @email_template.destroy
68
- flash[:success] = 'Successfully deleted email template'
69
- else
70
- flash[:danger] = 'Unable to delete email template'
71
- end
72
-
73
- redirect_to effective_email_templates.admin_email_templates_path
74
- end
75
-
76
- private
77
-
78
- def authorize_effective_email_templates!
79
- EffectiveEmailTemplates.authorize!(self, :admin, :effective_email_templates)
80
- EffectiveEmailTemplates.authorize!(self, action_name.to_sym, @email_template || Effective::EmailTemplate)
81
- end
12
+ submit :save, 'Save'
13
+ submit :save, 'Save and Add New', redirect: :new
82
14
 
83
15
  def email_template_params
84
- params.require(:effective_email_template).permit(EffectiveEmailTemplates.permitted_params)
16
+ params.require(:effective_email_template).permit!
85
17
  end
86
18
 
87
19
  end
@@ -8,15 +8,24 @@ class EffectiveEmailTemplatesDatatable < Effective::Datatable
8
8
  col :id, visible: false
9
9
 
10
10
  col :template_name, label: 'Name'
11
- col :from
12
- col :cc
13
- col :bcc
11
+
12
+ col :from do |email_template|
13
+ html_escape(email_template.from)
14
+ end
15
+
16
+ col :cc do |email_template|
17
+ html_escape(email_template.cc)
18
+ end
19
+
20
+ col :bcc do |email_template|
21
+ html_escape(email_template.bcc)
22
+ end
23
+
14
24
  col :subject
15
25
  col :body
16
-
17
26
  col :content_type, visible: false
18
27
 
19
- actions_col partial: '/admin/email_templates/actions', partial_as: 'email_template'
28
+ actions_col
20
29
  end
21
30
 
22
31
  collection do
@@ -13,6 +13,7 @@ module EffectiveEmailTemplatesHelper
13
13
 
14
14
  if mail.present?
15
15
  email_review.body = mail.message.body
16
+ email_review.subject = mail.message.subject
16
17
  end
17
18
  end
18
19
 
@@ -0,0 +1,35 @@
1
+ # HasOneEmailReview
2
+ # Allows any model to easily review an email template and make changes to the body
3
+
4
+ module EffectiveEmailTemplatesMailer
5
+ extend ActiveSupport::Concern
6
+
7
+ def mail(headers = {}, &block)
8
+ email_template = Effective::EmailTemplate.where(template_name: action_name).first!
9
+ assigns = (@assigns || {})
10
+
11
+ # Parse assigns. Special keys for body and subject.
12
+ body = assigns.delete(:body) || headers[:body] || headers['body']
13
+ email_template.body = body if body.present?
14
+
15
+ subject = assigns.delete(:subject) || headers[:subject] || headers['subject']
16
+ email_template.subject = subject if subject.present?
17
+
18
+ # Add any _url helpers
19
+ assigns = route_url_assigns(email_template).merge(assigns)
20
+
21
+ # Render from the template, possibly with updated body
22
+ rendered = email_template.render(assigns)
23
+
24
+ super(rendered.merge(headers.except(:body, :subject, 'body', 'subject')))
25
+ end
26
+
27
+ private
28
+
29
+ def route_url_assigns(email_template)
30
+ email_template.template_variables.select { |name| name.ends_with?('_url') }.inject({}) do |h, name|
31
+ h[name] = public_send(name) if respond_to?(name); h
32
+ end
33
+ end
34
+
35
+ end
@@ -1,31 +1,5 @@
1
1
  module Effective
2
2
  class EmailTemplatesMailer < ::ActionMailer::Base
3
-
4
- def mail(headers = {}, &block)
5
- email_template = Effective::EmailTemplate.where(template_name: action_name).first!
6
-
7
- # Parse Assigns. :body is a special key
8
- assigns = (@assigns || {})
9
-
10
- if (body = assigns.delete(:body))
11
- email_template.body = body
12
- end
13
-
14
- assigns = route_url_assigns(email_template).merge(assigns)
15
-
16
- # Render from the template, possibly with updated body
17
- rendered = email_template.render(assigns)
18
-
19
- super(rendered.merge(headers))
20
- end
21
-
22
- private
23
-
24
- def route_url_assigns(email_template)
25
- email_template.template_variables.select { |name| name.ends_with?('_url') }.inject({}) do |h, name|
26
- h[name] = public_send(name) if respond_to?(name); h
27
- end
28
- end
29
-
3
+ include EffectiveEmailTemplatesMailer
30
4
  end
31
5
  end
@@ -4,25 +4,32 @@ module Effective
4
4
 
5
5
  attr_accessor :email_template
6
6
  attr_accessor :template_name
7
+
7
8
  attr_accessor :body
9
+ attr_accessor :subject
10
+ attr_accessor :from
11
+ attr_accessor :cc
12
+ attr_accessor :bcc
8
13
 
9
14
  def self.build(attributes = {})
10
- new(attributes).tap do |email_review|
11
- email_review.body ||= email_review.email_template&.body
12
- email_review.template_name ||= email_review.email_template&.template_name
13
- end
14
- end
15
+ email_review = new(attributes)
16
+ template = email_review.email_template
15
17
 
16
- validates :body, presence: true
17
-
18
- validate(if: -> { body.present? }) do
19
- begin
20
- Liquid::Template.parse(body)
21
- rescue Liquid::SyntaxError => e
22
- errors.add(:body, e.message)
18
+ if template.present?
19
+ email_review.body ||= template.body
20
+ email_review.subject ||= template.subject
21
+ email_review.from ||= template.from
22
+ email_review.cc ||= template.cc
23
+ email_review.bcc ||= template.bcc
24
+ email_review.template_name ||= template.template_name
23
25
  end
26
+
27
+ email_review
24
28
  end
25
29
 
30
+ validates :body, presence: true, liquid: true
31
+ validates :subject, liquid: true
32
+
26
33
  def email_template
27
34
  @email_template ||= Effective::EmailTemplate.where(template_name: template_name).first
28
35
  end
@@ -2,42 +2,32 @@ module Effective
2
2
  class EmailTemplate < ActiveRecord::Base
3
3
  self.table_name = EffectiveEmailTemplates.email_templates_table_name.to_s
4
4
 
5
+ attr_accessor :current_user
6
+
5
7
  log_changes if respond_to?(:log_changes)
6
8
 
7
9
  CONTENT_TYPES = ['text/plain', 'text/html']
8
10
 
9
- # Attributes
10
- # subject :string
11
- # from :string
12
- # cc :string
13
- # bcc :string
14
- # body :text
15
- # content_type :string
16
- #
17
- # template_name :string
18
- #
19
- # timestamps
11
+ effective_resource do
12
+ template_name :string
13
+ content_type :string
20
14
 
21
- before_validation do
22
- self.content_type ||= CONTENT_TYPES.first
23
- end
15
+ subject :string
16
+ from :string
17
+ cc :string
18
+ bcc :string
19
+ body :text
24
20
 
25
- before_validation(if: -> { body.present? }) do
26
- begin
27
- Liquid::Template.parse(body)
28
- rescue Liquid::SyntaxError => e
29
- errors.add(:body, e.message)
30
- end
21
+ timestamps
31
22
  end
32
23
 
33
- before_validation(if: -> { subject.present? }) do
34
- begin
35
- Liquid::Template.parse(subject)
36
- rescue Liquid::SyntaxError => e
37
- errors.add(:subject, e.message)
38
- end
24
+ before_validation do
25
+ self.content_type ||= CONTENT_TYPES.first
39
26
  end
40
27
 
28
+ validates :body, liquid: true
29
+ validates :subject, liquid: true
30
+
41
31
  validates :subject, presence: true
42
32
  validates :from, presence: true
43
33
  validates :body, presence: true
@@ -4,7 +4,7 @@
4
4
  - if EffectiveEmailTemplates.select_content_type
5
5
  = f.select :content_type, Effective::EmailTemplate::CONTENT_TYPES
6
6
 
7
- = f.email_field :from, hint: 'Whom the email will be sent from'
7
+ = f.text_field :from, hint: 'Whom the email will be sent from'
8
8
  = f.text_field :cc
9
9
  = f.text_field :bcc
10
10
 
@@ -2,37 +2,9 @@ EffectiveEmailTemplates.setup do |config|
2
2
  # Configure Database Tables
3
3
  config.email_templates_table_name = :email_templates
4
4
 
5
- # Authorization Method
6
- #
7
- # This method is called by all controller actions with the appropriate action and resource
8
- # If the method returns false, an Effective::AccessDenied Error will be raised (see README.md for complete info)
9
- #
10
- # Use via Proc (and with CanCan):
11
- # config.authorization_method = Proc.new { |controller, action, resource| can?(action, resource) }
12
- #
13
- # Use via custom method:
14
- # config.authorization_method = :my_authorization_method
15
- #
16
- # And then in your application_controller.rb:
17
- #
18
- # def my_authorization_method(action, resource)
19
- # current_user.is?(:admin)
20
- # end
21
- #
22
- # Or disable the check completely:
23
- # config.authorization_method = false
24
- config.authorization_method = Proc.new { |controller, action, resource| authorize!(action, resource) } # CanCanCan
25
-
26
5
  # Layout Settings
27
- # Configure the Layout per controller, or all at once
28
-
29
- # config.layout = 'application' # All EffectiveEmailTemplates controllers will use this layout
30
- config.layout = {
31
- email_templates: 'application',
32
- admin_email_templates: 'admin'
33
- }
6
+ # config.layout = { application: 'application', admin: 'admin' }
34
7
 
35
8
  # Not allowed to select text/html by default
36
9
  config.select_content_type = false
37
-
38
10
  end
@@ -2,6 +2,9 @@ module EffectiveEmailTemplates
2
2
  class Engine < ::Rails::Engine
3
3
  engine_name 'effective_email_templates'
4
4
 
5
+ config.autoload_paths += Dir["#{config.root}/lib/validators/"]
6
+ config.eager_load_paths += Dir["#{config.root}/lib/validators/"]
7
+
5
8
  # Set up our default configuration options.
6
9
  initializer 'effective_email_templates.defaults', before: :load_config_initializers do |app|
7
10
  eval File.read("#{config.root}/config/effective_email_templates.rb")
@@ -16,4 +19,3 @@ module EffectiveEmailTemplates
16
19
 
17
20
  end
18
21
  end
19
-
@@ -1,24 +1,30 @@
1
1
  module EffectiveEmailTemplates
2
2
  class Importer
3
- def self.import(quiet: false)
4
- new().execute(overwrite: false, quiet: quiet)
3
+ def self.import(quiet: false, paths: nil)
4
+ new().execute(overwrite: false, paths: paths, quiet: quiet)
5
5
  end
6
6
 
7
- def self.overwrite(quiet: false)
8
- new().execute(overwrite: true, quiet: quiet)
7
+ def self.overwrite(quiet: false, paths: nil)
8
+ new().execute(overwrite: true, paths: paths, quiet: quiet)
9
9
  end
10
10
 
11
- def execute(overwrite:, quiet: false)
12
- Dir[Rails.root.join('app', 'views', '**', '*.liquid')].each do |filepath|
13
- name = File.basename(filepath, '.liquid')
14
- email_template = Effective::EmailTemplate.find_or_initialize_by(template_name: name)
11
+ def execute(overwrite:, paths: nil, quiet: false)
12
+ return false unless ActiveRecord::Base.connection.table_exists?(EffectiveEmailTemplates.email_templates_table_name)
15
13
 
16
- if email_template.persisted? && !overwrite
17
- puts("SKIPPED #{filename(filepath)}") unless quiet
18
- next
19
- end
14
+ paths ||= ActionController::Base.view_paths.map(&:path)
15
+
16
+ paths.each do |path|
17
+ Dir[Rails.root.join(path, '**', '*_mailer/', '*.liquid')].each do |filepath|
18
+ name = File.basename(filepath, '.liquid')
19
+ email_template = Effective::EmailTemplate.find_or_initialize_by(template_name: name)
20
20
 
21
- save(email_template, filepath, quiet: quiet)
21
+ if email_template.persisted? && !overwrite
22
+ puts("SKIPPED #{filename(filepath)}") unless quiet
23
+ next
24
+ end
25
+
26
+ save(email_template, filepath, quiet: quiet)
27
+ end
22
28
  end
23
29
  end
24
30
 
@@ -1,3 +1,3 @@
1
1
  module EffectiveEmailTemplates
2
- VERSION = '1.0.11'.freeze
2
+ VERSION = '1.1.1'.freeze
3
3
  end
@@ -1,37 +1,18 @@
1
- require "liquid"
2
- require "effective_email_templates/engine"
3
- require "effective_email_templates/version"
1
+ require 'liquid'
2
+ require 'effective_resources'
3
+ require 'effective_email_templates/engine'
4
+ require 'effective_email_templates/version'
4
5
 
5
6
  module EffectiveEmailTemplates
6
7
 
7
- mattr_accessor :email_templates_table_name
8
- mattr_accessor :authorization_method
9
- mattr_accessor :select_content_type
10
- mattr_accessor :layout
11
-
12
- def self.setup
13
- yield self
14
- end
15
-
16
- def self.authorized?(controller, action, resource)
17
- @_exceptions ||= [Effective::AccessDenied, (CanCan::AccessDenied if defined?(CanCan)), (Pundit::NotAuthorizedError if defined?(Pundit))].compact
18
-
19
- return !!authorization_method unless authorization_method.respond_to?(:call)
20
- controller = controller.controller if controller.respond_to?(:controller)
21
-
22
- begin
23
- !!(controller || self).instance_exec((controller || self), action, resource, &authorization_method)
24
- rescue *@_exceptions
25
- false
26
- end
8
+ def self.config_keys
9
+ [:email_templates_table_name, :select_content_type, :layout]
27
10
  end
28
11
 
29
- def self.authorize!(controller, action, resource)
30
- raise Effective::AccessDenied.new('Access Denied', action, resource) unless authorized?(controller, action, resource)
31
- end
12
+ include EffectiveGem
32
13
 
33
14
  def self.permitted_params
34
- [:from, :bcc, :cc, :subject, :body, :content_type]
15
+ @permitted_params ||= [:from, :bcc, :cc, :subject, :body, :content_type]
35
16
  end
36
17
 
37
18
  end
@@ -0,0 +1,15 @@
1
+ # An ActiveRecord validator for any liquid field that you would use with effective_email_templates or otherwise
2
+ #
3
+ # validates :body, liquid: true
4
+
5
+ class LiquidValidator < ActiveModel::EachValidator
6
+ def validate_each(record, attribute, value)
7
+ if value.present?
8
+ begin
9
+ Liquid::Template.parse(value)
10
+ rescue Liquid::SyntaxError => e
11
+ record.errors.add(attribute, e.message)
12
+ end
13
+ end
14
+ end
15
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_email_templates
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.11
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-04 00:00:00.000000000 Z
11
+ date: 2021-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -92,15 +92,12 @@ files:
92
92
  - app/controllers/admin/email_templates_controller.rb
93
93
  - app/datatables/effective_email_templates_datatable.rb
94
94
  - app/helpers/effective_email_templates_helper.rb
95
+ - app/mailers/concerns/effective_email_templates_mailer.rb
95
96
  - app/mailers/effective/email_templates_mailer.rb
96
97
  - app/models/concerns/has_one_email_review.rb
97
- - app/models/effective/access_denied.rb
98
98
  - app/models/effective/email_review.rb
99
99
  - app/models/effective/email_template.rb
100
- - app/views/admin/email_templates/_actions.html.haml
101
100
  - app/views/admin/email_templates/_form.html.haml
102
- - app/views/admin/email_templates/edit.html.haml
103
- - app/views/admin/email_templates/index.html.haml
104
101
  - app/views/effective/email_reviews/_fields.html.haml
105
102
  - app/views/layouts/effective_email_templates_mailer_layout.html.haml
106
103
  - config/effective_email_templates.rb
@@ -115,6 +112,7 @@ files:
115
112
  - lib/effective_email_templates/version.rb
116
113
  - lib/generators/effective_email_templates/install_generator.rb
117
114
  - lib/tasks/effective_email_templates_tasks.rake
115
+ - lib/validators/liquid_validator.rb
118
116
  homepage: https://github.com/code-and-effect/effective_email_templates
119
117
  licenses:
120
118
  - MIT
@@ -1,17 +0,0 @@
1
- unless defined?(Effective::AccessDenied)
2
- module Effective
3
- class AccessDenied < StandardError
4
- attr_reader :action, :subject
5
-
6
- def initialize(message = nil, action = nil, subject = nil)
7
- @message = message
8
- @action = action
9
- @subject = subject
10
- end
11
-
12
- def to_s
13
- @message || I18n.t(:'unauthorized.default', :default => 'Access Denied')
14
- end
15
- end
16
- end
17
- end
@@ -1,5 +0,0 @@
1
- = dropdown(variation: :dropleft) do
2
- = dropdown_link_to 'Edit', effective_email_templates.edit_admin_email_template_path(email_template)
3
-
4
- = dropdown_link_to "Delete #{email_template}", effective_email_templates.admin_email_template_path(email_template),
5
- data: { method: :delete, confirm: "Really delete #{email_template}?" }
@@ -1,3 +0,0 @@
1
- %h1.effective-admin-heading= @page_title
2
-
3
- = render partial: 'form', locals: { email_template: @email_template }
@@ -1,3 +0,0 @@
1
- %h1.effective-admin-heading= @page_title
2
-
3
- = render_datatable @datatable