mailtime 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|