template_mailer 0.0.1
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 +7 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +135 -0
- data/Rakefile +2 -0
- data/lib/template_mailer/exceptions.rb +4 -0
- data/lib/template_mailer/logging_helper.rb +11 -0
- data/lib/template_mailer/mail_message.rb +70 -0
- data/lib/template_mailer/mailer.rb +135 -0
- data/lib/template_mailer/template_directory.rb +65 -0
- data/lib/template_mailer/template_factory.rb +84 -0
- data/lib/template_mailer/version.rb +3 -0
- data/lib/template_mailer.rb +14 -0
- data/spec/data/more_templates/another_template.text.erb +1 -0
- data/spec/data/test_template_1.txt +1 -0
- data/spec/data/test_template_2.txt.erb +1 -0
- data/spec/data/test_template_3.html.erb +1 -0
- data/spec/data/test_template_4.html.erb +1 -0
- data/spec/data/test_template_4.text.erb +1 -0
- data/spec/data/test_template_4.txt.erb +1 -0
- data/spec/mail_message_spec.rb +66 -0
- data/spec/mailer_spec.rb +62 -0
- data/spec/spec_helper.rb +99 -0
- data/spec/template_directory_spec.rb +54 -0
- data/spec/template_factory_spec.rb +41 -0
- data/template_mailer.gemspec +27 -0
- metadata +156 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 83b2af7df86d4e00961e7e7863e1278b3d87cc17
|
4
|
+
data.tar.gz: d330298ec3ace4d7975c389ddeb3855ace67b47e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 762b21bb217c393ac8bd12be866503b18d766c33aa2b7d7e8845a0626a900513305b2e7b16e7bc956467721cc3560bdc5366b859057ebbc758d973f542ff5c84
|
7
|
+
data.tar.gz: ffd9d59f7f8b6e473eed31f686f43174c7d214df590274a438a195c25f3b861a8031d63b1f51e8e4696a23acd085215098576dd5ccabe78b097e77fa5bf55794
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2016 Peter Wood
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
# TemplateMailer
|
2
|
+
|
3
|
+
The Template Mailer library provides functionality to encapsulate the creation
|
4
|
+
and dispatch of emails. The emails sent by the library are created from templates
|
5
|
+
stored locally and allows for the creation of emails that are both HTML and/or
|
6
|
+
textual based. The library makes use of the [Tilt](https://github.com/rtomayko/tilt)
|
7
|
+
template library and the [Pony](https://github.com/benprew/pony libraries and
|
8
|
+
aspects of these interactions are exposed via configuration settings.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
gem 'template_mailer'
|
16
|
+
```
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
$ gem install template_mailer
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
To make use of the library you first need to require in the Tilt functionality
|
29
|
+
for the templating systems that you want to support and then require in the
|
30
|
+
template mailer library. So, for example, if you wanted to make use of ERB as
|
31
|
+
your templating engine then you would do the following...
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
require "tilt/erb"
|
35
|
+
require "template_mailer"
|
36
|
+
```
|
37
|
+
|
38
|
+
Next you want to create a ```Mailer``` class instance. To do this you will need
|
39
|
+
to specify a number of configuration settings as parameters to the constructor.
|
40
|
+
The parameters needed include the path to the directory containing your template
|
41
|
+
files as well as the mechanism that you want to use when dispatching emails. The
|
42
|
+
default mechanism, inherited from Pony, is ```sendmail``` but throughout the
|
43
|
+
rest of this document the assumption will be that you want to send your email via
|
44
|
+
an SMTP server. So, assuming your templates are stored in the ```/templates```
|
45
|
+
folder the code to create a ```Mailer``` might look as follows...
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
mailer = TemplateMailer::Mailer.new(directory: "/templates",
|
49
|
+
server: {address: 'mymail.smtp.com',
|
50
|
+
port: '587',
|
51
|
+
enable_starttls_auto: true,
|
52
|
+
user_name: 'mymailuser',
|
53
|
+
password: 'password',
|
54
|
+
authentication: :login,
|
55
|
+
domain: "mydomain.com"},
|
56
|
+
via: :smtp)
|
57
|
+
```
|
58
|
+
|
59
|
+
Once you have a ```Mailer``` instance you can use it to create an email. To create
|
60
|
+
an email you call the ```generate_mail()``` method on the mailer and give it the
|
61
|
+
name of the template that you want to generate the email from. The template name
|
62
|
+
equates to the name of the file or files containing the templates to be generated
|
63
|
+
minus any extensions. So, for example, if you had a template file in the template
|
64
|
+
directory called ```test_message.html.erb``` then the template name to specify to
|
65
|
+
the ```Mailer``` would be ```test_message```.
|
66
|
+
|
67
|
+
Note that if you want your email message to contain details for HTML and text only
|
68
|
+
based clients then create to files in the template directory with ```.text``` and
|
69
|
+
```.html``` extension. The ```Mailer``` will find both of these templates and
|
70
|
+
generate content from them both for the email message to be sent.
|
71
|
+
|
72
|
+
Note that when calling ```generate_mail()``` you can pass a Hash of context
|
73
|
+
parmaeters as the second parameter to the method call. The values within this
|
74
|
+
Hash will be available to populate the message templates with. So, for example,
|
75
|
+
if you wanted to pass in a parameter called full name you would make a call that
|
76
|
+
looked like this...
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
mailer.generate_mail("my_template", full_name: "John Smith")
|
80
|
+
```
|
81
|
+
|
82
|
+
To send the email generated simply call ```send()``` on the value returned from
|
83
|
+
the call to the ```generate_mail()``` method. The call to ```send()``` should be
|
84
|
+
accompanied by the final set of details needed to send the email such as the list
|
85
|
+
of recipients for the message, the title to be given to the email and possibly the
|
86
|
+
email address that the message will appear to come from. For example, a send
|
87
|
+
might look as follows...
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
mailer.send(from: "me@mydomain.com",
|
91
|
+
recipients: ["first.person@mydomain.com", "second.person@mydomain.com"],
|
92
|
+
subject: "Test Message")
|
93
|
+
```
|
94
|
+
|
95
|
+
### Advanced Usage
|
96
|
+
|
97
|
+
Having all potential email templates within a single directory could ultimately
|
98
|
+
become difficult to manage. To support a hierarchical directory structure an
|
99
|
+
instance of the ```Mailer``` class will support stepping down through a list of
|
100
|
+
subdirectories to pick out a particular template. For example, lets say that you
|
101
|
+
wanted to keep all emails relating to account creation and maintenance in a
|
102
|
+
subdirectory beneath the mail template directory called ```accounts```. To send
|
103
|
+
a template called ```create``` from this directory you could create the
|
104
|
+
```Mailer``` as outlined above and then do the following...
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
message = mailer.accounts.generate_mail("create")
|
108
|
+
```
|
109
|
+
|
110
|
+
The call to ```mailer.accounts``` automatically creates a new ```Mailer``` instance
|
111
|
+
based on the subdirectory. As this works this way you can chain calls like this
|
112
|
+
together so, if you had a template called 'verify' that was stored in a subfolder
|
113
|
+
of the accounts folder called create you could create a messasge based on it as
|
114
|
+
follows...
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
message = mailer.accounts.create.generate_mail("verify")
|
118
|
+
```
|
119
|
+
|
120
|
+
Note that the call to ```generate_mail()``` here can be replaced with the name of
|
121
|
+
the template as the ```Mailer``` instance will recognise that this relates to an
|
122
|
+
existing template and automatically call ```generate_mail()``` for you. This
|
123
|
+
means that previous call could be changed to...
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
message = mailer.account.create.verify
|
127
|
+
```
|
128
|
+
|
129
|
+
## Contributing
|
130
|
+
|
131
|
+
1. Fork it ( https://github.com/[my-github-username]/template_mailer/fork )
|
132
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
133
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
134
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
135
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
module TemplateMailer
|
2
|
+
class MailMessage
|
3
|
+
# Constructor for the MailMessage class.
|
4
|
+
#
|
5
|
+
# ==== Parameters
|
6
|
+
# options:: An options Hash. The following keys are recognised within this
|
7
|
+
# Hash...
|
8
|
+
# * :html - The HTML content for the email message. Both this and
|
9
|
+
# text can be specified but at least one of them should be.
|
10
|
+
# * :text - The textual content for the email message. Both this
|
11
|
+
# and :html can be specified but at least one should be.
|
12
|
+
# * :server - When SMTP is the preferred email mecahnism (see the
|
13
|
+
# :via option) then this value should be a Hash of the parameters
|
14
|
+
# that will be used to talk to the SMTP server.
|
15
|
+
# * :via - The email mechanism to use to dispatch email messages.
|
16
|
+
# options are :sendmail (the default) or :smtp. If :smtp is
|
17
|
+
# specified then the :server option should also be given a
|
18
|
+
# value.
|
19
|
+
def initialize(options={})
|
20
|
+
@html = options[:html]
|
21
|
+
@text = options.fetch(:text, options[:txt])
|
22
|
+
@server = options[:server]
|
23
|
+
@via = options.fetch(:via, :sendmail)
|
24
|
+
end
|
25
|
+
attr_reader :html, :text
|
26
|
+
|
27
|
+
# This method attempts to send the contents of a mail message to a specified
|
28
|
+
# set of recipients.
|
29
|
+
#
|
30
|
+
# ==== Parameters
|
31
|
+
# options:: A Hash of the options to be used when sending the email.
|
32
|
+
# Recognised keys in this Hash are :subject (a String containing
|
33
|
+
# the email title), :recipients (either a String or Array list
|
34
|
+
# of email addresses that the message should be sent to) and
|
35
|
+
# :from (the email address that will be set as the message
|
36
|
+
# source).
|
37
|
+
def send(options={})
|
38
|
+
if !options.include?(:recipients) || [nil, "", []].include?(options[:recipients])
|
39
|
+
raise TemplateMailerError, "No recipients specified for email."
|
40
|
+
end
|
41
|
+
Pony.mail(send_settings(options))
|
42
|
+
end
|
43
|
+
alias :dispatch :send
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
# This method assembles a Hash of configuration settings to be given to the
|
48
|
+
# Pony library to dispatch an email.
|
49
|
+
#
|
50
|
+
# ==== Parameters
|
51
|
+
# settings:: A Hash of the base server settings to be used when putting\
|
52
|
+
# the complete settings together.
|
53
|
+
def send_settings(settings)
|
54
|
+
output = {to: settings[:recipients]}
|
55
|
+
output[:subject] = settings[:subject]
|
56
|
+
output[:html_body] = @html if (@html || "") != ""
|
57
|
+
output[:body] = @text if (@text || "") != ""
|
58
|
+
output[:from] = settings[:from] if settings.include?(:from)
|
59
|
+
output.merge(pony_settings(settings))
|
60
|
+
end
|
61
|
+
|
62
|
+
# This method is used internally to assemble configuration settings that are
|
63
|
+
# specific to dispatching an email via SMTP through the Pony library.
|
64
|
+
def pony_settings(settings)
|
65
|
+
output = {via: @via}
|
66
|
+
output[:via_options] = @server if @via == :smtp
|
67
|
+
output
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
module TemplateMailer
|
2
|
+
class Mailer
|
3
|
+
include LoggingHelper
|
4
|
+
|
5
|
+
# Constructor for the Mailer class.
|
6
|
+
#
|
7
|
+
# ==== Parameters
|
8
|
+
# options:: A Hash of the options to be used by the Mailer. Recognised
|
9
|
+
# option settings are...
|
10
|
+
# * :directory - The root directory that the mailer will use
|
11
|
+
# when looking for template files. If not specified or if the
|
12
|
+
# value specified does not exist then the current working
|
13
|
+
# directory is assumed to have a subdirectory called templates
|
14
|
+
# and that will be used.
|
15
|
+
# * :logger - The logger to be used by the mailer. Defaults to
|
16
|
+
# using a null logger.
|
17
|
+
# * :server - Configuration details used to talk to the SMTP
|
18
|
+
# server to send emails. See the :via option.
|
19
|
+
# * :via - A indication of the mailing method to be used when
|
20
|
+
# dispatching emails. Viable options are :sendmail (the
|
21
|
+
# default) or :smtp. If :smtp is specified then server
|
22
|
+
# details should also be specified.
|
23
|
+
def initialize(options={})
|
24
|
+
@logger = options[:logger]
|
25
|
+
@directory = TemplateDirectory.new(template_directory(options[:directory]))
|
26
|
+
@via = options.fetch(:via, :sendmail)
|
27
|
+
@server = options[:server]
|
28
|
+
end
|
29
|
+
attr_reader :server, :via
|
30
|
+
|
31
|
+
# Fetches the path to the template directory being used by the mailer.
|
32
|
+
def directory
|
33
|
+
@directory.path
|
34
|
+
end
|
35
|
+
|
36
|
+
# This method creates a new Mailer instance by using the details of the
|
37
|
+
# current mailer and extending the directory used with the name passed
|
38
|
+
# in.
|
39
|
+
#
|
40
|
+
# ==== Parameters
|
41
|
+
# name:: The name of the folder to be appended to the directory being
|
42
|
+
# used by the mailer that the call is being made on.
|
43
|
+
def subdirectory(name)
|
44
|
+
Mailer.new(directory: File.join(directory, name.to_s),
|
45
|
+
logger: log,
|
46
|
+
server: @server,
|
47
|
+
via: @via)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Generates a MailMessage for a named template in the template directory.
|
51
|
+
#
|
52
|
+
# ==== Parameters
|
53
|
+
# template:: The name of the template to generate the email from.
|
54
|
+
# context:: A Hash of the variables to be used when generating the email
|
55
|
+
# templates. Defaults to an empty Hash.
|
56
|
+
def generate_mail(template, context={})
|
57
|
+
log.debug "Constructing a mail message based on the '#{template}' template."
|
58
|
+
factory = TemplateFactory.new(@directory.path, log)
|
59
|
+
content = factory.manufacture(template, context)
|
60
|
+
MailMessage.new({server: @server, via: @via}.merge(content))
|
61
|
+
end
|
62
|
+
|
63
|
+
# This method overrides the default implementation to return true for
|
64
|
+
# anything that represents a valid Ruby method name. Everything else
|
65
|
+
# is delegated to the parent class.
|
66
|
+
def respond_to?(name, all=false)
|
67
|
+
method_name?(name) || super
|
68
|
+
end
|
69
|
+
|
70
|
+
# This method checks the template directory for a subdirectory for the
|
71
|
+
# given name. If a subdirectory is found then the call becomes an
|
72
|
+
# equivalent to a call to the subdirectory() method. If template
|
73
|
+
# matching the name passed in is instead found then this is equivalent
|
74
|
+
# to a call to the generate_mail() method. If all other options are
|
75
|
+
# exhausted then the parent class version of this method is invoked.
|
76
|
+
def method_missing(name, *arguments, &block)
|
77
|
+
if directory_exists?(@directory.path, name.to_s)
|
78
|
+
subdirectory(name)
|
79
|
+
elsif @directory.exists?(name.to_s)
|
80
|
+
generate_mail(name, arguments.empty? ? {} : arguments[0])
|
81
|
+
else
|
82
|
+
super
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def method_name?(name)
|
89
|
+
return /[@$"]/ !~ name.inspect
|
90
|
+
end
|
91
|
+
|
92
|
+
def settings
|
93
|
+
{directory: @directory.path, engines: @engines.values, logger: log}
|
94
|
+
end
|
95
|
+
|
96
|
+
def generate_template(path, context={})
|
97
|
+
raise TemplateMailerError, "The '#{path}' template files does not exist." if !File.exist?(path)
|
98
|
+
raise TemplateMailerError, "Insufficient permission to read the '#{path}' file." if !File.readable?(path)
|
99
|
+
|
100
|
+
pathname = Pathname.new(path)
|
101
|
+
engine = @engines[Pathname.new(path).extname]
|
102
|
+
raise TemplateMailerError, "No template engine configured to process the '#{path}' template file." if engine.nil?
|
103
|
+
|
104
|
+
log.debug "Processing the '#{path}' template file with an instance of the #{engine.class.name} class."
|
105
|
+
engine.process(pathname, context)
|
106
|
+
end
|
107
|
+
|
108
|
+
def template_directory(path)
|
109
|
+
output = File.join(Dir.getwd, "templates")
|
110
|
+
if path && path.strip != ""
|
111
|
+
if directory_exists?(path)
|
112
|
+
output = path
|
113
|
+
else
|
114
|
+
log.warn "The '#{path}' path either does not exist or is not a directory. Default will be used."
|
115
|
+
end
|
116
|
+
end
|
117
|
+
log.debug "Using '#{output}' as the mailer templates directory."
|
118
|
+
output
|
119
|
+
end
|
120
|
+
|
121
|
+
def directory_exists?(*components)
|
122
|
+
path = File.join(*components)
|
123
|
+
File.exist?(path) && File.directory?(path)
|
124
|
+
end
|
125
|
+
|
126
|
+
def file_exists?(*components)
|
127
|
+
path = path(*components)
|
128
|
+
File.exist?(path) && File.file?(path)
|
129
|
+
end
|
130
|
+
|
131
|
+
def path(*components)
|
132
|
+
File.join(*components)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module TemplateMailer
|
2
|
+
class TemplateDirectory
|
3
|
+
include LoggingHelper
|
4
|
+
|
5
|
+
# Constructor for the TemplateDirectory class.
|
6
|
+
#
|
7
|
+
# ==== Parameters
|
8
|
+
# path:: The path to the template directory.
|
9
|
+
# logger:: The logger to be used by the directory object.
|
10
|
+
def initialize(path,logger=nil)
|
11
|
+
@pathname = Pathname.new(path)
|
12
|
+
@logger = logger
|
13
|
+
scan_templates
|
14
|
+
end
|
15
|
+
attr_reader :pathname, :engines, :extensions
|
16
|
+
|
17
|
+
# Returns a String containing the template directory path.
|
18
|
+
def path
|
19
|
+
@pathname.to_s
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns an array of the template files within the directory.
|
23
|
+
def template_files
|
24
|
+
[].concat(@templates)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Checks whether at least one template file with a given name exists within
|
28
|
+
# the template directory.
|
29
|
+
#
|
30
|
+
# ==== Parameters
|
31
|
+
# name:: The name of the template. This should be the file name, not
|
32
|
+
# including base path details or extensions.
|
33
|
+
def exists?(name)
|
34
|
+
!template_paths(name).empty?
|
35
|
+
end
|
36
|
+
|
37
|
+
# Retrieves a list of paths for all template files within a template
|
38
|
+
# directory that match a given template name.
|
39
|
+
#
|
40
|
+
# ==== Parameters
|
41
|
+
# name:: The name of the template. This should be the file name, not
|
42
|
+
# including base path details or extensions.
|
43
|
+
def template_paths(name)
|
44
|
+
@templates.inject([]) do |list, path|
|
45
|
+
file_name = File.basename(path)
|
46
|
+
file_name[0, name.length] == name.to_s ? list << path : list
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
# Scans the files in the template directory to generate a list of files
|
53
|
+
# recognised as templates based on extensions from the object itself and
|
54
|
+
# the engine it possesses.
|
55
|
+
def scan_templates
|
56
|
+
@templates = Dir.glob(File.join(path, "*")).inject([]) do |list, file_path|
|
57
|
+
log.debug "Checking if #{file_path} is a recognised template file."
|
58
|
+
file_name = File.basename(file_path)
|
59
|
+
log.debug "#{file_path} is a template file." if !(Tilt[file_name]).nil?
|
60
|
+
list << file_path if !(Tilt[file_name]).nil?
|
61
|
+
list
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module TemplateMailer
|
2
|
+
class TemplateFactory
|
3
|
+
include LoggingHelper
|
4
|
+
|
5
|
+
# Constructor for the template factory class.
|
6
|
+
#
|
7
|
+
# ==== Parameters
|
8
|
+
# directory:: The path to the directory containing the template files.
|
9
|
+
# logger:: The logger to be used by the factory. Defaults to nil.
|
10
|
+
def initialize(directory, logger=nil)
|
11
|
+
@directory = TemplateDirectory.new(directory, logger)
|
12
|
+
@logger = logger
|
13
|
+
end
|
14
|
+
|
15
|
+
# Fetches the template directory being used by the factory.
|
16
|
+
def directory
|
17
|
+
@directory.path
|
18
|
+
end
|
19
|
+
|
20
|
+
# Checks whether one or more template files exist for a given name.
|
21
|
+
#
|
22
|
+
# ==== Parameters
|
23
|
+
# name:: The name of the template to check for. A template name should be
|
24
|
+
# the template file name without extension(s).
|
25
|
+
def exists?(name)
|
26
|
+
@directory.exists?(name)
|
27
|
+
end
|
28
|
+
|
29
|
+
# This method 'manufactures' a set of templates based on the template name.
|
30
|
+
# Manufacturing involves finding all instance of a template and then using
|
31
|
+
# the template engine to generate the results of the template including the
|
32
|
+
# elements of the context passed in. The return value from this method will
|
33
|
+
# be a Hash of the templates generated (there may be more than one) keyed
|
34
|
+
# on the base file types used to generate the template instance. If a
|
35
|
+
# matching template cannot be found then an empty Hash is returned.
|
36
|
+
#
|
37
|
+
# ==== Parameters
|
38
|
+
# name:: The name of the template to manufacture. Template names equate
|
39
|
+
# to template file names minus extensions.
|
40
|
+
# context:: A Hash of settings that will be made available to the template
|
41
|
+
# engine when the template is instantiated. Defaults to {}.
|
42
|
+
def manufacture(name, context={})
|
43
|
+
paths = @directory.template_paths(name)
|
44
|
+
log.debug "Manufacture requested for the '#{name}' template. Context:\n#{context}\nFound #{paths.size} matching template files."
|
45
|
+
paths.inject({}) do |store, path|
|
46
|
+
key = file_base_type(path)
|
47
|
+
engine = Tilt.new(path)
|
48
|
+
log.debug "Generating template for the #{path} template file as type '#{key}'."
|
49
|
+
store[key] = engine.render(nil, context)
|
50
|
+
store
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Same as the manufacture() method except this version raises an exception
|
55
|
+
# if no matching templates are found.
|
56
|
+
#
|
57
|
+
# ==== Parameters
|
58
|
+
# name:: The name of the template to manufacture. Template names equate
|
59
|
+
# to template file names minus extensions.
|
60
|
+
# context:: A Hash of settings that will be made available to the template
|
61
|
+
# engine when the template is instantiated. Defaults to {}.
|
62
|
+
def manufacture!(name, context={})
|
63
|
+
output = manufacture(name, context)
|
64
|
+
raise TemplateMailerError, "Unable to locate a template with the name '#{name}'." if output.empty?
|
65
|
+
output
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
# Generate a Symbol based on the base type for a file. The base type for
|
71
|
+
# template files will be the first extension that the file has rather than
|
72
|
+
# the second (e.g. :html for a file called template.html.erb).
|
73
|
+
#
|
74
|
+
# ==== Parameters
|
75
|
+
# path:: The path and name of the template file to generate the base type
|
76
|
+
# for.
|
77
|
+
def file_base_type(path)
|
78
|
+
file_name = File.basename(path)
|
79
|
+
extension = File.extname(file_name)
|
80
|
+
file_name = file_name[0, file_name.length - extension.length]
|
81
|
+
(File.extname(file_name)[1..-1]).to_sym
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "tilt"
|
2
|
+
require "logger"
|
3
|
+
require "pathname"
|
4
|
+
require "pony"
|
5
|
+
require "template_mailer/version"
|
6
|
+
require "template_mailer/exceptions"
|
7
|
+
require "template_mailer/logging_helper"
|
8
|
+
require "template_mailer/template_directory"
|
9
|
+
require "template_mailer/template_factory"
|
10
|
+
require "template_mailer/mail_message"
|
11
|
+
require "template_mailer/mailer"
|
12
|
+
|
13
|
+
module TemplateMailer
|
14
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
This is another test template.
|
@@ -0,0 +1 @@
|
|
1
|
+
A simple template.
|
@@ -0,0 +1 @@
|
|
1
|
+
Template File 2
|
@@ -0,0 +1 @@
|
|
1
|
+
<h1>Test Template 3</h1>
|
@@ -0,0 +1 @@
|
|
1
|
+
<h1>T4: <%= one %>, '<%= two %>'</h1>
|
@@ -0,0 +1 @@
|
|
1
|
+
T4: <%= one %>, '<%= two %>'
|
@@ -0,0 +1 @@
|
|
1
|
+
T4: <%= one %>, '<%= two %>'
|
@@ -0,0 +1,66 @@
|
|
1
|
+
describe TemplateMailer::MailMessage do
|
2
|
+
let(:recipients) {
|
3
|
+
["one@test.com", "two@test.com"]
|
4
|
+
}
|
5
|
+
let(:from) {
|
6
|
+
"sender@somewhere.com"
|
7
|
+
}
|
8
|
+
let(:title) {
|
9
|
+
"Test Email"
|
10
|
+
}
|
11
|
+
let(:html_body) {
|
12
|
+
"<h1>HTML message.</h1>"
|
13
|
+
}
|
14
|
+
let(:text_body) {
|
15
|
+
"Text message."
|
16
|
+
}
|
17
|
+
let(:server) {
|
18
|
+
{address: "smtp.test.com",
|
19
|
+
port: "25",
|
20
|
+
user_name: "user",
|
21
|
+
password: "password",
|
22
|
+
authentication: :plain,
|
23
|
+
domain: "localhost.localdomain"}
|
24
|
+
}
|
25
|
+
subject {
|
26
|
+
TemplateMailer::MailMessage.new(html: html_body,
|
27
|
+
server: server,
|
28
|
+
text: text_body,
|
29
|
+
via: :smtp)
|
30
|
+
}
|
31
|
+
|
32
|
+
describe "#send()" do
|
33
|
+
let(:server_settings) {
|
34
|
+
{body: text_body,
|
35
|
+
from: from,
|
36
|
+
html_body: html_body,
|
37
|
+
subject: title,
|
38
|
+
to: recipients,
|
39
|
+
via: :smtp,
|
40
|
+
via_options: server}
|
41
|
+
}
|
42
|
+
|
43
|
+
it "invokes the Pony.mail() method when called with valid parameters" do
|
44
|
+
expect(Pony).to receive(:mail).with(server_settings).once
|
45
|
+
subject.send(from: from, recipients: recipients, subject: title)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "raises an exception when invoked without specifying recipients" do
|
49
|
+
expect {
|
50
|
+
subject.send()
|
51
|
+
}.to raise_exception(TemplateMailer::TemplateMailerError, "No recipients specified for email.")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "raises an exception when invoked with an empty recipient list" do
|
55
|
+
expect {
|
56
|
+
subject.send(recipients: [])
|
57
|
+
}.to raise_exception(TemplateMailer::TemplateMailerError, "No recipients specified for email.")
|
58
|
+
end
|
59
|
+
|
60
|
+
it "raises an exception when invoked with a blank recipient string" do
|
61
|
+
expect {
|
62
|
+
subject.send(recipients: "")
|
63
|
+
}.to raise_exception(TemplateMailer::TemplateMailerError, "No recipients specified for email.")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/spec/mailer_spec.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
describe TemplateMailer::Mailer do
|
2
|
+
let(:template_directory) {
|
3
|
+
File.join(Dir.getwd, "spec", "data")
|
4
|
+
}
|
5
|
+
let(:subdirectory) {
|
6
|
+
"more_templates"
|
7
|
+
}
|
8
|
+
let(:server) {
|
9
|
+
{address: "smtp.test.com",
|
10
|
+
port: "25",
|
11
|
+
user_name: "user",
|
12
|
+
password: "password",
|
13
|
+
authentication: :plain,
|
14
|
+
domain: "localhost.localdomain"}
|
15
|
+
}
|
16
|
+
subject {
|
17
|
+
TemplateMailer::Mailer.new(directory: template_directory,
|
18
|
+
server: server,
|
19
|
+
via: :smtp)
|
20
|
+
}
|
21
|
+
|
22
|
+
describe "#directory()" do
|
23
|
+
it "returns a String containing the template directory path" do
|
24
|
+
expect(subject.directory).to eq(template_directory)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#subdirectory()" do
|
29
|
+
let(:subdirectory_path) {
|
30
|
+
File.join(template_directory, subdirectory)
|
31
|
+
}
|
32
|
+
|
33
|
+
it "creates a new Mailer instance pointing at the appropriate subdirectory" do
|
34
|
+
mailer = subject.subdirectory(subdirectory)
|
35
|
+
expect(mailer).not_to be_nil
|
36
|
+
expect(mailer.class).to eq(TemplateMailer::Mailer)
|
37
|
+
expect(mailer.directory).to eq(subdirectory_path)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#generate_mail()" do
|
42
|
+
it "generates a MailMessage with appropriate content" do
|
43
|
+
message = subject.generate_mail("test_template_4", one: 1, two: "TWO")
|
44
|
+
expect(message).not_to be_nil
|
45
|
+
expect(message.class).to eq(TemplateMailer::MailMessage)
|
46
|
+
expect(message.html).to eq("<h1>T4: 1, 'TWO'</h1>")
|
47
|
+
expect(message.text).to eq("T4: 1, 'TWO'")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#method_missing()" do
|
52
|
+
it "calls the #subdirectory() method if the method invoked matches a subdirectory name" do
|
53
|
+
expect(subject).to receive(:subdirectory).with(subdirectory.to_sym).once
|
54
|
+
subject.more_templates
|
55
|
+
end
|
56
|
+
|
57
|
+
it "calls the #generate_mail() method of the method invoked matches a template" do
|
58
|
+
expect(subject).to receive(:generate_mail).with(:test_template_2, {}).once
|
59
|
+
subject.test_template_2
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# The generated `.rspec` file contains `--require spec_helper` which will cause
|
4
|
+
# this file to always be loaded, without a need to explicitly require it in any
|
5
|
+
# files.
|
6
|
+
#
|
7
|
+
# Given that it is always loaded, you are encouraged to keep this file as
|
8
|
+
# light-weight as possible. Requiring heavyweight dependencies from this file
|
9
|
+
# will add to the boot time of your test suite on EVERY test run, even for an
|
10
|
+
# individual file that may not need all of that loaded. Instead, consider making
|
11
|
+
# a separate helper file that requires the additional dependencies and performs
|
12
|
+
# the additional setup, and require it from the spec files that actually need
|
13
|
+
# it.
|
14
|
+
#
|
15
|
+
# The `.rspec` file also contains a few flags that are not defaults but that
|
16
|
+
# users commonly want.
|
17
|
+
#
|
18
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
19
|
+
|
20
|
+
require "template_mailer"
|
21
|
+
|
22
|
+
RSpec.configure do |config|
|
23
|
+
# rspec-expectations config goes here. You can use an alternate
|
24
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
25
|
+
# assertions if you prefer.
|
26
|
+
config.expect_with :rspec do |expectations|
|
27
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
28
|
+
# and `failure_message` of custom matchers include text for helper methods
|
29
|
+
# defined using `chain`, e.g.:
|
30
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
31
|
+
# # => "be bigger than 2 and smaller than 4"
|
32
|
+
# ...rather than:
|
33
|
+
# # => "be bigger than 2"
|
34
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
35
|
+
end
|
36
|
+
|
37
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
38
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
39
|
+
config.mock_with :rspec do |mocks|
|
40
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
41
|
+
# a real object. This is generally recommended, and will default to
|
42
|
+
# `true` in RSpec 4.
|
43
|
+
mocks.verify_partial_doubles = true
|
44
|
+
end
|
45
|
+
|
46
|
+
# The settings below are suggested to provide a good initial experience
|
47
|
+
# with RSpec, but feel free to customize to your heart's content.
|
48
|
+
=begin
|
49
|
+
# These two settings work together to allow you to limit a spec run
|
50
|
+
# to individual examples or groups you care about by tagging them with
|
51
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
52
|
+
# get run.
|
53
|
+
config.filter_run :focus
|
54
|
+
config.run_all_when_everything_filtered = true
|
55
|
+
|
56
|
+
# Allows RSpec to persist some state between runs in order to support
|
57
|
+
# the `--only-failures` and `--next-failure` CLI options. We recommend
|
58
|
+
# you configure your source control system to ignore this file.
|
59
|
+
config.example_status_persistence_file_path = "spec/examples.txt"
|
60
|
+
|
61
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
62
|
+
# recommended. For more details, see:
|
63
|
+
# - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
|
64
|
+
# - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
65
|
+
# - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
|
66
|
+
config.disable_monkey_patching!
|
67
|
+
|
68
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
69
|
+
# be too noisy due to issues in dependencies.
|
70
|
+
config.warnings = true
|
71
|
+
|
72
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
73
|
+
# file, and it's useful to allow more verbose output when running an
|
74
|
+
# individual spec file.
|
75
|
+
if config.files_to_run.one?
|
76
|
+
# Use the documentation formatter for detailed output,
|
77
|
+
# unless a formatter has already been configured
|
78
|
+
# (e.g. via a command-line flag).
|
79
|
+
config.default_formatter = 'doc'
|
80
|
+
end
|
81
|
+
|
82
|
+
# Print the 10 slowest examples and example groups at the
|
83
|
+
# end of the spec run, to help surface which specs are running
|
84
|
+
# particularly slow.
|
85
|
+
config.profile_examples = 10
|
86
|
+
|
87
|
+
# Run specs in random order to surface order dependencies. If you find an
|
88
|
+
# order dependency and want to debug it, you can fix the order by providing
|
89
|
+
# the seed, which is printed after each run.
|
90
|
+
# --seed 1234
|
91
|
+
config.order = :random
|
92
|
+
|
93
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
94
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
95
|
+
# test failures related to randomization by passing the same `--seed` value
|
96
|
+
# as the one that triggered the failure.
|
97
|
+
Kernel.srand config.seed
|
98
|
+
=end
|
99
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require "tilt/erb"
|
2
|
+
|
3
|
+
describe TemplateMailer::TemplateDirectory do
|
4
|
+
let(:path) {
|
5
|
+
File.join(Dir.getwd, "spec", "data")
|
6
|
+
}
|
7
|
+
subject {
|
8
|
+
TemplateMailer::TemplateDirectory.new(path)
|
9
|
+
}
|
10
|
+
|
11
|
+
describe "#path()" do
|
12
|
+
it "returns the path to the template directory" do
|
13
|
+
expect(subject.path).to eq(path)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#template_files()" do
|
18
|
+
let(:file_paths) {
|
19
|
+
Dir.glob(File.join(path, "*.erb"))
|
20
|
+
}
|
21
|
+
|
22
|
+
it "returns a list of matching template paths for the directory" do
|
23
|
+
paths = subject.template_files
|
24
|
+
expect(paths.size).to eq(file_paths.size)
|
25
|
+
file_paths.each do |file_path|
|
26
|
+
expect(paths).to include(file_path)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#exists?()" do
|
32
|
+
it "returns true for a template that exists" do
|
33
|
+
expect(subject.exists?("test_template_2")).to eq(true)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns false for a template that does not exist" do
|
37
|
+
expect(subject.exists?("does_not_exist")).to eq(false)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#template_paths()" do
|
42
|
+
let(:paths) {
|
43
|
+
[File.join(path, "test_template_3.html.erb")]
|
44
|
+
}
|
45
|
+
|
46
|
+
it "returns a list of template paths given an existing template name" do
|
47
|
+
expect(subject.template_paths("test_template_3")).to eq(paths)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "returns an empty array if given the name of a template that does not exist" do
|
51
|
+
expect(subject.template_paths("does_not_exist")).to eq([])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
describe TemplateMailer::TemplateFactory do
|
2
|
+
let(:directory) {
|
3
|
+
File.join(Dir.getwd, "spec", "data")
|
4
|
+
}
|
5
|
+
subject {
|
6
|
+
TemplateMailer::TemplateFactory.new(directory)
|
7
|
+
}
|
8
|
+
|
9
|
+
describe "#directory()" do
|
10
|
+
it "returns the path to the template directory" do
|
11
|
+
expect(subject.directory).to eq(directory)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#manufacture()" do
|
16
|
+
let(:context) {
|
17
|
+
{one: 1, two: "Two"}
|
18
|
+
}
|
19
|
+
let(:templates) {
|
20
|
+
{html: "<h1>T4: 1, 'Two'</h1>",
|
21
|
+
text: "T4: 1, 'Two'",
|
22
|
+
txt: "T4: 1, 'Two'"}
|
23
|
+
}
|
24
|
+
|
25
|
+
it "returns an empty Hash if given the name of a template that does not exist" do
|
26
|
+
expect(subject.manufacture("does_not_exist")).to eq({})
|
27
|
+
end
|
28
|
+
|
29
|
+
it "generates template entries for all available template files" do
|
30
|
+
expect(subject.manufacture("test_template_4", context)).to eq(templates)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#manufacture!()" do
|
35
|
+
it "raises an exception if a matching template is not found" do
|
36
|
+
expect {
|
37
|
+
subject.manufacture!("does_not_exist")
|
38
|
+
}.to raise_exception(TemplateMailer::TemplateMailerError, "Unable to locate a template with the name 'does_not_exist'.")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'template_mailer/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "template_mailer"
|
8
|
+
spec.version = TemplateMailer::VERSION
|
9
|
+
spec.authors = ["Peter Wood"]
|
10
|
+
spec.email = ["pwood@blacknorth.com"]
|
11
|
+
spec.summary = %q{A simple library that uses the Tilt and Pony libraries to generate and dispatch emails.}
|
12
|
+
spec.description = %q{Template Mailer is a library that can be used to send emails that are created from templates. It makes use of the Tilt library to support a wide variety of templating systems and the Pony library for integration with mail servers.}
|
13
|
+
spec.homepage = "https://github.com/free-beer/template_mailer"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.4"
|
24
|
+
|
25
|
+
spec.add_dependency "pony", "~> 1.11"
|
26
|
+
spec.add_dependency "tilt", "~> 2.0"
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: template_mailer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Peter Wood
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-03-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.4'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.4'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pony
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.11'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.11'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: tilt
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.0'
|
83
|
+
description: Template Mailer is a library that can be used to send emails that are
|
84
|
+
created from templates. It makes use of the Tilt library to support a wide variety
|
85
|
+
of templating systems and the Pony library for integration with mail servers.
|
86
|
+
email:
|
87
|
+
- pwood@blacknorth.com
|
88
|
+
executables: []
|
89
|
+
extensions: []
|
90
|
+
extra_rdoc_files: []
|
91
|
+
files:
|
92
|
+
- ".gitignore"
|
93
|
+
- ".rspec"
|
94
|
+
- Gemfile
|
95
|
+
- LICENSE.txt
|
96
|
+
- README.md
|
97
|
+
- Rakefile
|
98
|
+
- lib/template_mailer.rb
|
99
|
+
- lib/template_mailer/exceptions.rb
|
100
|
+
- lib/template_mailer/logging_helper.rb
|
101
|
+
- lib/template_mailer/mail_message.rb
|
102
|
+
- lib/template_mailer/mailer.rb
|
103
|
+
- lib/template_mailer/template_directory.rb
|
104
|
+
- lib/template_mailer/template_factory.rb
|
105
|
+
- lib/template_mailer/version.rb
|
106
|
+
- spec/data/more_templates/another_template.text.erb
|
107
|
+
- spec/data/test_template_1.txt
|
108
|
+
- spec/data/test_template_2.txt.erb
|
109
|
+
- spec/data/test_template_3.html.erb
|
110
|
+
- spec/data/test_template_4.html.erb
|
111
|
+
- spec/data/test_template_4.text.erb
|
112
|
+
- spec/data/test_template_4.txt.erb
|
113
|
+
- spec/mail_message_spec.rb
|
114
|
+
- spec/mailer_spec.rb
|
115
|
+
- spec/spec_helper.rb
|
116
|
+
- spec/template_directory_spec.rb
|
117
|
+
- spec/template_factory_spec.rb
|
118
|
+
- template_mailer.gemspec
|
119
|
+
homepage: https://github.com/free-beer/template_mailer
|
120
|
+
licenses:
|
121
|
+
- MIT
|
122
|
+
metadata: {}
|
123
|
+
post_install_message:
|
124
|
+
rdoc_options: []
|
125
|
+
require_paths:
|
126
|
+
- lib
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
requirements: []
|
138
|
+
rubyforge_project:
|
139
|
+
rubygems_version: 2.4.6
|
140
|
+
signing_key:
|
141
|
+
specification_version: 4
|
142
|
+
summary: A simple library that uses the Tilt and Pony libraries to generate and dispatch
|
143
|
+
emails.
|
144
|
+
test_files:
|
145
|
+
- spec/data/more_templates/another_template.text.erb
|
146
|
+
- spec/data/test_template_1.txt
|
147
|
+
- spec/data/test_template_2.txt.erb
|
148
|
+
- spec/data/test_template_3.html.erb
|
149
|
+
- spec/data/test_template_4.html.erb
|
150
|
+
- spec/data/test_template_4.text.erb
|
151
|
+
- spec/data/test_template_4.txt.erb
|
152
|
+
- spec/mail_message_spec.rb
|
153
|
+
- spec/mailer_spec.rb
|
154
|
+
- spec/spec_helper.rb
|
155
|
+
- spec/template_directory_spec.rb
|
156
|
+
- spec/template_factory_spec.rb
|