mailtime 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +35 -20
- data/lib/generators/mailtime/templates/db/migrate/1_mailtime_migration.rb +18 -2
- data/lib/generators/mailtime/templates/default_initializer.rb +9 -11
- data/lib/mailtime.rb +1 -0
- data/lib/mailtime/action_mailer/base.rb +4 -0
- data/lib/mailtime/active_record/models/concerns/mail_layout_concern.rb +17 -0
- data/lib/mailtime/active_record/models/concerns/mail_log_concern.rb +1 -1
- data/lib/mailtime/active_record/models/concerns/mail_template_concern.rb +9 -2
- data/lib/mailtime/active_record/models/concerns/renderer_concern.rb +20 -0
- data/lib/mailtime/active_record/models/mail_layout.rb +11 -0
- data/lib/mailtime/active_record/models/mail_template.rb +2 -0
- data/lib/mailtime/acts_as_mailtime_loggable.rb +11 -1
- data/lib/mailtime/configuration.rb +22 -10
- data/lib/mailtime/models.rb +2 -1
- data/lib/mailtime/processor/processor.rb +4 -5
- data/lib/mailtime/railtie.rb +18 -2
- data/lib/mailtime/renderers/base_renderer.rb +9 -22
- data/lib/mailtime/renderers/erb_renderer.rb +10 -2
- data/lib/mailtime/renderers/mail_renderer.rb +41 -0
- data/lib/mailtime/renderers/null.rb +42 -0
- data/lib/mailtime/version.rb +1 -1
- metadata +7 -3
- data/lib/mailtime/loggable.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d1034ff118c9f1f13f3585d33f7d6ea7de54484
|
4
|
+
data.tar.gz: 4a14aed6613149b9887928f3bf82c82acd6de04b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c765236c8b6e7871d83c41bc3811649652bea36cb25a31f0c8b8207ad23846cd5e67a7aad19020f1a8a72e33a0ba8d0a4501c2c0fa4f18866e6eb8b1a6b74db
|
7
|
+
data.tar.gz: a9c3adcf5423fda4105fdc225bc63dcc25857d323cad62d3c3281c1fbeeba65744f6a7cd91809f68dd858739f0cba274fd57fdcae1de5c0502eb7ece43a235b9
|
data/README.md
CHANGED
@@ -26,16 +26,6 @@ Migrate it.
|
|
26
26
|
|
27
27
|
$ rake db:migrate
|
28
28
|
|
29
|
-
## How it works
|
30
|
-
|
31
|
-
Mailtime hooks into `ActionMailer#mail`. It injects a some methods in order to extract metadata, such as the mailer class (like `UserMailer`) and the action
|
32
|
-
(like `password_reset`). Once it knows what it's working with, it looks to the database for the corresponding `MailTemplate`.
|
33
|
-
If it finds the `MailTemplate`, it renders the template against the mail and merges the result with some of the mail's attributes (like `body`).
|
34
|
-
|
35
|
-
It then logs the mail and sends it away.
|
36
|
-
|
37
|
-
Mailtime aims to be highly flexible and tries not to dictate your setup. For example, you can render a `MailTemplate`'s contents however you want. Just specify in the initializer what `renderer` you want to use. And because Mailtime simply hooks into `ActionMailer`, it doesn't care how you're delivering mail (via `config.action_mailer.delivery_method`).
|
38
|
-
|
39
29
|
## Usage
|
40
30
|
|
41
31
|
Using Mailtime is simple. Just add `acts_as_mailtime_loggable` to each class you want to associate a `Mailtime::MailLog` to.
|
@@ -44,17 +34,38 @@ Using Mailtime is simple. Just add `acts_as_mailtime_loggable` to each class you
|
|
44
34
|
|
45
35
|
```Ruby
|
46
36
|
class User < ActiveRecord::Base
|
47
|
-
acts_as_mailtime_loggable
|
37
|
+
acts_as_mailtime_loggable
|
38
|
+
```
|
39
|
+
|
40
|
+
will tell `Mailtime::MailLog` to find an instance variable of class `User` where attribute `#email` (`email` is default) that matches an `ActionMailer#mail`'s `#to` (again, default) attribute.
|
41
|
+
|
42
|
+
Need to customize? Sure.
|
43
|
+
|
44
|
+
```Ruby
|
45
|
+
class User < ActiveRecord::Base
|
46
|
+
acts_as_mailtime_loggable :email_address, :fields => [:to, :cc, :bcc]
|
48
47
|
```
|
49
48
|
|
50
|
-
will tell `Mailtime::MailLog` to find
|
49
|
+
will tell `Mailtime::MailLog` to find an instance variable of class `User` where attribute `email_address` matches an `ActionMailer#mail`'s `#to`, `#cc`, or `#bcc` attribute.
|
51
50
|
|
52
51
|
#### Configuration
|
53
52
|
|
54
53
|
The default initializer that's installed when you run `rails g mailtime:install` is self-documented.
|
55
54
|
|
55
|
+
## How it works
|
56
|
+
|
57
|
+
Mailtime hooks into `ActionMailer#mail`. It injects a some methods in order to extract metadata, such as the mailer class (like `UserMailer`) and the action
|
58
|
+
(like `password_reset`). Once it knows what it's working with, it looks to the database for the corresponding `MailTemplate`.
|
59
|
+
If it finds the `MailTemplate`, it renders the template against the mail and merges the result with some of the mail's attributes (like `body`).
|
60
|
+
|
61
|
+
It then logs the mail and sends it away.
|
62
|
+
|
63
|
+
Mailtime aims to be highly flexible and tries not to dictate your setup. For example, you can render a `MailTemplate`'s contents however you want. Just specify in the initializer what `renderer` you want to use. And because Mailtime simply hooks into `ActionMailer`, it doesn't care how you're delivering mail (via `config.action_mailer.delivery_method`).
|
64
|
+
|
56
65
|
## Additional Setup
|
57
66
|
|
67
|
+
`Mailtime` doesn't ship with views. You want views.
|
68
|
+
|
58
69
|
#### MailTemplate
|
59
70
|
|
60
71
|
You'll want somewhere to view your logs and manage your templates. Basic scaffolding will do just fine.
|
@@ -65,15 +76,18 @@ def index
|
|
65
76
|
end
|
66
77
|
```
|
67
78
|
|
68
|
-
For `MailTemplate`, you'll want to permit the params `klass`, `action`, `subject`, and `content`
|
79
|
+
For `MailTemplate`, you'll want to permit the params `klass`, `action`, `subject`, `mail_layout_id`, `format`, `extension`, and `content`
|
69
80
|
|
70
|
-
Here's an example using
|
81
|
+
Here's an example using SimpleForm:
|
71
82
|
|
72
83
|
```Ruby
|
73
84
|
simple_form_for @mail_template do |f|
|
74
85
|
f.input :action, :as => :select, :collection => MailTemplate.mail_actions, :onchange => '$("#mail_template_klass").val($("#mail_template_action option:selected").closest("optgroup").attr("label"));'
|
75
86
|
f.input :klass, :as => :hidden
|
76
87
|
f.input :subject
|
88
|
+
f.input :mail_layout
|
89
|
+
f.input :format, :as => :select, :collection => Mailtime.configuration.valid_formats
|
90
|
+
f.input :extension, :as => :select, :collection => Mailtime.configuration.valid_extensions
|
77
91
|
f.input :content, :as => :text
|
78
92
|
f.submit
|
79
93
|
end
|
@@ -81,25 +95,26 @@ Here's an example using `SimpleForm`:
|
|
81
95
|
|
82
96
|
`MailTemplate.mail_actions` is an array of mailer classes and their public instance methods, e.g. `['UserMailer' => ['password_reset_email']]`
|
83
97
|
|
98
|
+
Note: If `subject` is present, it will override the mail's subject.
|
99
|
+
|
84
100
|
#### MailLog
|
85
101
|
|
86
|
-
A `MailLog` stores the `MailTemplate`, `action` (from the mailer), `klass` (from the mailer), `field` (such as `to`, `cc`, `bcc), `loggable` (from `acts_as_mailtime_loggable`), `headers` (from `ActionMailer#mail`), and `scope` (the instance variables defined in the action)
|
102
|
+
A `MailLog` stores the `MailTemplate`, `action` (from the mailer), `klass` (from the mailer), `field` (such as `to`, `cc`, `bcc`), `loggable` (from `acts_as_mailtime_loggable`), `headers` (from `ActionMailer#mail`), and `scope` (the instance variables defined in the action)
|
87
103
|
|
88
104
|
You'll probably want somewhere to look at these.
|
89
105
|
|
106
|
+
#### MailLayout
|
107
|
+
|
108
|
+
Has a `name`, `content`, `format`, and `extension`. `format` should be one of `Mailtime.configuration.valid_formats`, and `extension` should be one of `Mailtime.configuration.valid_extensions`
|
109
|
+
|
90
110
|
## Todo
|
91
111
|
|
92
|
-
* Import existing mailers with a rake task
|
93
|
-
* Layouts
|
94
112
|
* Tests
|
95
|
-
* BCC, CC for templates
|
96
|
-
* Configure overrides for subject
|
97
113
|
|
98
114
|
## Maybe todo
|
99
115
|
|
100
116
|
* Dump for production?
|
101
117
|
* Versioning for templates?
|
102
|
-
* Specify multiple formats?
|
103
118
|
|
104
119
|
## Contributing
|
105
120
|
|
@@ -4,12 +4,28 @@ class MailtimeMigration < ActiveRecord::Migration
|
|
4
4
|
t.string :klass
|
5
5
|
t.string :action
|
6
6
|
t.text :content
|
7
|
-
t.
|
8
|
-
|
7
|
+
t.string :subject
|
8
|
+
t.integer :mailtime_mail_layout_id
|
9
|
+
t.string :format
|
10
|
+
t.string :extension
|
9
11
|
t.timestamps null: false
|
10
12
|
end
|
11
13
|
add_index :mailtime_mail_templates, :klass
|
12
14
|
add_index :mailtime_mail_templates, :action
|
15
|
+
add_index :mailtime_mail_templates, :mailtime_mail_layout_id
|
16
|
+
add_index :mailtime_mail_templates, :extension
|
17
|
+
add_index :mailtime_mail_templates, :format
|
18
|
+
|
19
|
+
create_table :mailtime_mail_layouts do |t|
|
20
|
+
t.string :name
|
21
|
+
t.text :content
|
22
|
+
t.string :format
|
23
|
+
t.string :extension
|
24
|
+
t.timestamps null: false
|
25
|
+
end
|
26
|
+
add_index :mailtime_mail_layouts, :name
|
27
|
+
add_index :mailtime_mail_layouts, :extension
|
28
|
+
add_index :mailtime_mail_layouts, :format
|
13
29
|
|
14
30
|
create_table :mailtime_mail_logs do |t|
|
15
31
|
t.integer :mailtime_mail_template_id
|
@@ -15,16 +15,6 @@ Mailtime.configure do |config|
|
|
15
15
|
# you should set this to false
|
16
16
|
config.render = true
|
17
17
|
|
18
|
-
# But if you do (and you should), and you want to use your own renderer, specify
|
19
|
-
# it here. It's just a PORO that parse the template's (from the database) content
|
20
|
-
# and assign the mail's body to it.
|
21
|
-
# config.renderer = 'LiquidRenderer'
|
22
|
-
|
23
|
-
# If for some reason, calling #render on your renderer is not okay, you can specify
|
24
|
-
# the method below. (ps. the method should output the contents of the template + mail context)
|
25
|
-
# so that it can be assigned to the `body` of the mail
|
26
|
-
# config.renderer_method = :render
|
27
|
-
|
28
18
|
# == Logging
|
29
19
|
#
|
30
20
|
# Log the mail to the database. Set to `false` if you don't want to log anything.
|
@@ -36,10 +26,18 @@ Mailtime.configure do |config|
|
|
36
26
|
|
37
27
|
# Sometimes, a mail action gets polluted with instance variables we don't care about.
|
38
28
|
# Because we log all instance variables, you can remove any named instance variables here.
|
39
|
-
# Defaults to Devise::Mail's ['devise_mapping', 'scope_name']
|
40
29
|
# config.reject_scope_keys = ['devise_mapping', 'scope_name']
|
41
30
|
|
31
|
+
# == Layouts & Templates
|
32
|
+
#
|
33
|
+
# if you want to use a different keyword to gsub for a MailTemplate
|
34
|
+
# config.yield_keyword = '{{ mailtime_yield }}'
|
35
|
+
|
36
|
+
# Valid formats for a MailTemplate and MailLayout (pretty sure you're fine with the default)
|
37
|
+
# config.valid_formats = %w{html text}
|
38
|
+
|
42
39
|
# == Fallbacks
|
40
|
+
#
|
43
41
|
# Falls back to the mail's body if the template doesn't exist in the database
|
44
42
|
# If set to false, raises a `TemplateNotFound` error if the template doesn't exist
|
45
43
|
config.fallback = true
|
data/lib/mailtime.rb
CHANGED
@@ -27,6 +27,7 @@ end
|
|
27
27
|
|
28
28
|
require 'mailtime/action_mailer/base'
|
29
29
|
require 'mailtime/action_mailer/interceptor'
|
30
|
+
require 'mailtime/renderers/null'
|
30
31
|
require 'mailtime/processor/processor'
|
31
32
|
require 'mailtime/railtie'
|
32
33
|
require 'mailtime/active_record/models/concerns/mail_log_concern'
|
@@ -27,12 +27,16 @@ module Mailtime
|
|
27
27
|
self.message.instance_variable_set(:@action_variables, action_variables)
|
28
28
|
self.message.instance_variable_set(:@template_path, self.headers[:template_path] || mailer_klass)
|
29
29
|
self.message.instance_variable_set(:@template_name, self.headers[:template_name] || mailer_action)
|
30
|
+
self.message.instance_variable_set(:@mailtime_template, nil)
|
31
|
+
self.message.instance_variable_set(:@mailtime_layout, nil)
|
30
32
|
|
31
33
|
self.message.class.send(:attr_reader, :mailer_klass)
|
32
34
|
self.message.class.send(:attr_reader, :mailer_action)
|
33
35
|
self.message.class.send(:attr_reader, :action_variables)
|
34
36
|
self.message.class.send(:attr_reader, :template_path)
|
35
37
|
self.message.class.send(:attr_reader, :template_name)
|
38
|
+
self.message.class.send(:attr_accessor, :mailtime_template)
|
39
|
+
self.message.class.send(:attr_accessor, :mailtime_layout)
|
36
40
|
end
|
37
41
|
|
38
42
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Mailtime
|
2
|
+
# moving the functionality to this module, you can include
|
3
|
+
# this concern instead of sub-classing the `MailLayout` model.
|
4
|
+
module MailLayoutConcern
|
5
|
+
|
6
|
+
extend ::ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
self.table_name = 'mailtime_mail_layouts'
|
10
|
+
has_many :mail_templates, :class_name => 'Mailtime::MailTemplate'
|
11
|
+
|
12
|
+
validates_inclusion_of :format, :in => -> { Mailtime.configuration.valid_formats }
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -3,10 +3,10 @@ module Mailtime
|
|
3
3
|
# outlined in mail_template_concern.rb
|
4
4
|
module MailLogConcern
|
5
5
|
|
6
|
-
extend ::ActiveSupport::Concern
|
7
6
|
included do
|
8
7
|
self.table_name = 'mailtime_mail_logs'
|
9
8
|
belongs_to :loggable, :polymorphic => true
|
9
|
+
belongs_to :mail_templates, :class_name => 'Mailtime::MailTemplate'
|
10
10
|
end
|
11
11
|
|
12
12
|
end
|
@@ -8,8 +8,10 @@ module Mailtime
|
|
8
8
|
included do
|
9
9
|
self.table_name = 'mailtime_mail_templates'
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
belongs_to :mail_layout, :class_name => 'Mailtime::MailLayout'
|
12
|
+
validates_inclusion_of :klass, :in => -> { mailers }
|
13
|
+
validates_inclusion_of :format, :in => -> { Mailtime.configuration.valid_formats }
|
14
|
+
validates_uniqueness_of :action, :scope => [:klass, :format]
|
13
15
|
|
14
16
|
def self.mailers
|
15
17
|
Mailtime.configuration.mailers
|
@@ -20,6 +22,11 @@ module Mailtime
|
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
25
|
+
def mail_layout
|
26
|
+
return NullLayout.new unless self[:mail_layout].present?
|
27
|
+
|
28
|
+
end
|
29
|
+
|
23
30
|
def additional_headers
|
24
31
|
headers = {}
|
25
32
|
headers[:subject] = self.subject if self.subject.present?
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Mailtime
|
2
|
+
module RendererConcern
|
3
|
+
|
4
|
+
extend ::ActiveSupport::Concern
|
5
|
+
|
6
|
+
# find the renderer
|
7
|
+
def renderer
|
8
|
+
renderers = Mailtime::Renderers::BaseRenderer.descendants
|
9
|
+
renderers.each do |r|
|
10
|
+
return r if r.renders.include? self.extension
|
11
|
+
end
|
12
|
+
Mailtime::Renderer::ErbRenderer
|
13
|
+
end
|
14
|
+
|
15
|
+
# render against the mail
|
16
|
+
def render(mail)
|
17
|
+
renderer.new(mail, self.content).render
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'mailtime/active_record/models/concerns/mail_layout_concern'
|
2
|
+
require 'mailtime/active_record/models/concerns/renderer_concern'
|
3
|
+
|
4
|
+
module Mailtime
|
5
|
+
class MailLayout < ActiveRecord::Base
|
6
|
+
|
7
|
+
include Mailtime::MailLayoutConcern
|
8
|
+
include Mailtime::Renderer
|
9
|
+
|
10
|
+
end
|
11
|
+
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'mailtime/active_record/models/concerns/mail_template_concern'
|
2
|
+
require 'mailtime/active_record/models/concerns/renderer_concern'
|
2
3
|
|
3
4
|
module Mailtime
|
4
5
|
class MailTemplate < ActiveRecord::Base
|
5
6
|
|
6
7
|
include Mailtime::MailTemplateConcern
|
8
|
+
include Mailtime::Renderer
|
7
9
|
|
8
10
|
end
|
9
11
|
end
|
@@ -2,10 +2,20 @@ module Mailtime
|
|
2
2
|
module ActsAsMailtimeLoggable
|
3
3
|
|
4
4
|
def acts_as_mailtime_loggable(attr = 'email', opts = {})
|
5
|
-
require 'mailtime/loggable'
|
6
5
|
include Mailtime::Loggable
|
6
|
+
opts[:fields] ||= [:to]
|
7
7
|
Mailtime.configuration.loggable_lookups << { self.to_s => {:attribute => attr, :fields => opts[:fields]} }
|
8
8
|
end
|
9
9
|
|
10
10
|
end
|
11
|
+
|
12
|
+
module Loggable
|
13
|
+
|
14
|
+
def self.included(base)
|
15
|
+
base.class_eval do
|
16
|
+
has_many :mail_logs, :as => :loggable, :class_name => 'Mailtime::MailLog'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
11
21
|
end
|
@@ -1,8 +1,15 @@
|
|
1
1
|
module Mailtime
|
2
2
|
|
3
3
|
class Configuration
|
4
|
-
attr_accessor :mailers,
|
5
|
-
:
|
4
|
+
attr_accessor :mailers,
|
5
|
+
:render,
|
6
|
+
:log,
|
7
|
+
:log_fields,
|
8
|
+
:fallback,
|
9
|
+
:reject_scope_keys,
|
10
|
+
:loggable_lookups,
|
11
|
+
:yield_keyword,
|
12
|
+
:valid_formats
|
6
13
|
|
7
14
|
def initialize
|
8
15
|
@mailers = load_mailers
|
@@ -10,18 +17,20 @@ module Mailtime
|
|
10
17
|
@log = true
|
11
18
|
@log_fields = [:to]
|
12
19
|
@fallback = true
|
13
|
-
@renderer = 'Mailtime::Renderers::ErbRenderer'
|
14
|
-
@renderer_method = :render
|
15
|
-
@user_class = 'User'
|
16
|
-
@user_finder = nil
|
17
20
|
@reject_scope_keys = ['devise_mapping', 'scope_name']
|
18
21
|
@loggable_lookups = []
|
22
|
+
@yield_keyword = '{{ mailtime_yield }}'
|
23
|
+
@valid_formats = %w{html text}
|
19
24
|
end
|
20
25
|
|
21
26
|
def mailer(klass)
|
22
27
|
@mailers << klass
|
23
28
|
end
|
24
29
|
|
30
|
+
def mailers
|
31
|
+
@mailers
|
32
|
+
end
|
33
|
+
|
25
34
|
def loggables
|
26
35
|
@loggable_lookups.each_with_object({}) do |k,h|
|
27
36
|
key = k.keys.first
|
@@ -37,21 +46,24 @@ module Mailtime
|
|
37
46
|
@loggable_lookups
|
38
47
|
end
|
39
48
|
|
49
|
+
def valid_extensions
|
50
|
+
Mailtime::Renderers::BaseRenderer.descendants.map(&:renders).flatten
|
51
|
+
end
|
52
|
+
|
40
53
|
def preload_mailers!
|
41
54
|
preload_mailers
|
42
55
|
end
|
43
56
|
|
44
57
|
def preload_mailers
|
45
|
-
Dir.glob(Rails.root.join("app/mailers/**/*_mailer.rb"))
|
58
|
+
Dir.glob(::Rails.root.join("app/mailers/**/*_mailer.rb"))
|
46
59
|
.each { |klass| require klass }
|
47
60
|
end
|
48
61
|
|
49
|
-
protected
|
50
|
-
|
51
62
|
def load_mailers
|
52
63
|
ObjectSpace.each_object(Class).select { |klass| klass < ::ActionMailer::Base }
|
53
64
|
end
|
54
65
|
|
55
|
-
|
66
|
+
protected
|
56
67
|
|
68
|
+
end
|
57
69
|
end
|
data/lib/mailtime/models.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'mailtime/models'
|
2
|
+
require 'mailtime/renderers/mail_renderer'
|
2
3
|
require 'mailtime/renderers/base_renderer'
|
3
4
|
require 'mailtime/renderers/erb_renderer'
|
4
5
|
require 'mailtime/processor/mail_log_service'
|
5
|
-
require 'mailtime/processor/processor'
|
6
|
-
module Mailtime
|
7
6
|
|
7
|
+
module Mailtime
|
8
8
|
class Processor
|
9
9
|
|
10
10
|
def initialize(mail)
|
@@ -32,8 +32,8 @@ module Mailtime
|
|
32
32
|
|
33
33
|
def render_mail
|
34
34
|
return @mail unless Mailtime.configuration.render
|
35
|
-
renderer = Mailtime.
|
36
|
-
@mail.body = renderer.
|
35
|
+
renderer = Mailtime::Renderers::MailRenderer.new(@mail)
|
36
|
+
@mail.body = renderer.render
|
37
37
|
@mail
|
38
38
|
end
|
39
39
|
|
@@ -44,6 +44,5 @@ module Mailtime
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
|
48
47
|
end
|
49
48
|
end
|
data/lib/mailtime/railtie.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'rails'
|
2
2
|
require 'mailtime'
|
3
|
+
|
3
4
|
class Railtie < Rails::Railtie
|
4
5
|
initializer "Include your code in the controller" do
|
5
6
|
ActiveSupport.on_load(:action_controller) do
|
@@ -10,8 +11,23 @@ class Railtie < Rails::Railtie
|
|
10
11
|
rake_tasks do
|
11
12
|
namespace :mailtime do
|
12
13
|
desc 'Create a bunch of MailTemplate(s) based on existing mailers'
|
13
|
-
task :sync_mailers do
|
14
|
-
|
14
|
+
task :sync_mailers => :environment do
|
15
|
+
Dir.glob(::Rails.root.join("app/mailers/**/*_mailer.rb")).each { |m| require m }
|
16
|
+
mailers = ObjectSpace.each_object(Class).select { |klass| klass < ::ActionMailer::Base }
|
17
|
+
mailers.each do |mailer|
|
18
|
+
methods = mailer.public_instance_methods(false)
|
19
|
+
methods.each do |m|
|
20
|
+
formats = Dir.glob(Rails.root.join("app/views/#{mailer.to_s.underscore}/#{m}.*"))
|
21
|
+
formats.each do |f|
|
22
|
+
Mailtime::MailTemplate.create(:klass => mailer.to_s,
|
23
|
+
:action => m,
|
24
|
+
:content => File.read(f),
|
25
|
+
:format => f.scan(%r{\.(\w{3,4})\.}).to_a.first.first,
|
26
|
+
:extension => File.extname(f)[1 .. -1]
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
15
31
|
end
|
16
32
|
end
|
17
33
|
end
|
@@ -1,35 +1,22 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
1
3
|
module Mailtime
|
2
4
|
module Renderers
|
3
5
|
class BaseRenderer
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
# we inject mail with the instance variables from your ActionMailer action.
|
8
|
-
# access them via mail.action_variables
|
9
|
-
def initialize(mail)
|
7
|
+
def initialize(mail, content)
|
10
8
|
@mail = mail
|
11
|
-
@
|
9
|
+
@content = content
|
12
10
|
end
|
13
11
|
|
14
|
-
def
|
15
|
-
|
12
|
+
def self.renders
|
13
|
+
[]
|
16
14
|
end
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
# find the template. If one doesn't exist, and we want to fallback,
|
21
|
-
# pretend like we have a template with an OpenStruct
|
22
|
-
def template
|
23
|
-
_template = ::Mailtime::MailTemplate.find_by(:klass => @mail.mailer_klass, :action => @mail.mailer_action)
|
24
|
-
if _template.nil?
|
25
|
-
unless Mailtime.configuration.fallback
|
26
|
-
raise TemplateNotFound, "Template doesn't exist for klass #{@mail.mailer_klass} and action #{@mail.mailer_action}"
|
27
|
-
end
|
28
|
-
_template = OpenStruct.new(:content => @mail.body.raw_source)
|
29
|
-
end
|
30
|
-
_template
|
16
|
+
def render
|
17
|
+
@content
|
31
18
|
end
|
32
19
|
|
33
20
|
end
|
34
21
|
end
|
35
|
-
end
|
22
|
+
end
|
@@ -1,13 +1,21 @@
|
|
1
1
|
require 'erb'
|
2
|
-
require 'mailtime/renderers/erb_renderer'
|
3
2
|
|
4
3
|
module Mailtime
|
5
4
|
module Renderers
|
6
5
|
class ErbRenderer < BaseRenderer
|
7
6
|
|
7
|
+
def initialize(mail, content)
|
8
|
+
@mail = mail
|
9
|
+
@content = content
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.renders
|
13
|
+
['erb']
|
14
|
+
end
|
15
|
+
|
8
16
|
def render
|
9
17
|
set_instance_variables_from_mailer
|
10
|
-
ERB.new(@
|
18
|
+
ERB.new(@content).result(binding)
|
11
19
|
end
|
12
20
|
|
13
21
|
protected
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Mailtime
|
2
|
+
module Renderers
|
3
|
+
class MailRenderer
|
4
|
+
|
5
|
+
def initialize(mail)
|
6
|
+
@mail = mail
|
7
|
+
@template = find_template
|
8
|
+
@layout = find_layout
|
9
|
+
end
|
10
|
+
|
11
|
+
def render
|
12
|
+
render_and_merge
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.renders
|
16
|
+
[]
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
# find the template. If one doesn't exist, and we want to fallback,
|
22
|
+
# pretend like we have a template with a NullTemplate to make Sandi proud
|
23
|
+
def find_template
|
24
|
+
_template = Mailtime::MailTemplate.find_by(:klass => @mail.mailer_klass, :action => @mail.mailer_action)
|
25
|
+
if _template.nil?
|
26
|
+
_template = Mailtime::NullTemplate.new(@mail)
|
27
|
+
end
|
28
|
+
_template
|
29
|
+
end
|
30
|
+
|
31
|
+
def find_layout
|
32
|
+
@template.mail_layout
|
33
|
+
end
|
34
|
+
|
35
|
+
def render_and_merge
|
36
|
+
@layout.render(@mail).gsub(Mailtime.configuration.yield_keyword, @template.render(@mail))
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Just null objects
|
2
|
+
|
3
|
+
module Mailtime
|
4
|
+
class NullLayout
|
5
|
+
|
6
|
+
attr_reader :content
|
7
|
+
def initialize
|
8
|
+
@content = "#{Mailtime.configuration.yield_keyword}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.renders
|
12
|
+
['erb']
|
13
|
+
end
|
14
|
+
|
15
|
+
def renderer
|
16
|
+
Mailtime::Renderers::ErbRenderer
|
17
|
+
end
|
18
|
+
|
19
|
+
def render(mail)
|
20
|
+
renderer.new(mail, @content).render
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
class NullTemplate
|
26
|
+
|
27
|
+
attr_reader :content
|
28
|
+
def initialize(mail)
|
29
|
+
@content = mail.body.raw_source
|
30
|
+
end
|
31
|
+
|
32
|
+
def mail_layout
|
33
|
+
NullLayout.new
|
34
|
+
end
|
35
|
+
|
36
|
+
# doesn't do anything since we already know the mail.
|
37
|
+
def render(mail)
|
38
|
+
@content
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
data/lib/mailtime/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mailtime
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Brody
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -45,20 +45,24 @@ files:
|
|
45
45
|
- lib/mailtime.rb
|
46
46
|
- lib/mailtime/action_mailer/base.rb
|
47
47
|
- lib/mailtime/action_mailer/interceptor.rb
|
48
|
+
- lib/mailtime/active_record/models/concerns/mail_layout_concern.rb
|
48
49
|
- lib/mailtime/active_record/models/concerns/mail_log_concern.rb
|
49
50
|
- lib/mailtime/active_record/models/concerns/mail_template_concern.rb
|
51
|
+
- lib/mailtime/active_record/models/concerns/renderer_concern.rb
|
52
|
+
- lib/mailtime/active_record/models/mail_layout.rb
|
50
53
|
- lib/mailtime/active_record/models/mail_log.rb
|
51
54
|
- lib/mailtime/active_record/models/mail_template.rb
|
52
55
|
- lib/mailtime/acts_as_mailtime_loggable.rb
|
53
56
|
- lib/mailtime/configuration.rb
|
54
57
|
- lib/mailtime/engine.rb
|
55
|
-
- lib/mailtime/loggable.rb
|
56
58
|
- lib/mailtime/models.rb
|
57
59
|
- lib/mailtime/processor/mail_log_service.rb
|
58
60
|
- lib/mailtime/processor/processor.rb
|
59
61
|
- lib/mailtime/railtie.rb
|
60
62
|
- lib/mailtime/renderers/base_renderer.rb
|
61
63
|
- lib/mailtime/renderers/erb_renderer.rb
|
64
|
+
- lib/mailtime/renderers/mail_renderer.rb
|
65
|
+
- lib/mailtime/renderers/null.rb
|
62
66
|
- lib/mailtime/version.rb
|
63
67
|
- mailtime.gemspec
|
64
68
|
homepage: https://github.com/joshmn/mailtime
|