html_email_creator 1.0.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.
- data/.gitignore +2 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +49 -0
- data/README.markdown +5 -0
- data/Rakefile +7 -0
- data/bin/html_email_creator +35 -0
- data/html_email_creator.gemspec +41 -0
- data/lib/html_email_creator/email.rb +93 -0
- data/lib/html_email_creator/email_creator.rb +45 -0
- data/lib/html_email_creator/email_version.rb +26 -0
- data/lib/html_email_creator/extensions.rb +46 -0
- data/lib/html_email_creator/filters.rb +9 -0
- data/lib/html_email_creator/formatter.rb +30 -0
- data/lib/html_email_creator/formatters/formatter.rb +31 -0
- data/lib/html_email_creator/formatters/html_email.rb +24 -0
- data/lib/html_email_creator/formatters/markdown.rb +24 -0
- data/lib/html_email_creator/formatters/plain_text_email.rb +22 -0
- data/lib/html_email_creator/formatters/unknown_formatter.rb +17 -0
- data/lib/html_email_creator/helper.rb +25 -0
- data/lib/html_email_creator/information.rb +4 -0
- data/lib/html_email_creator/layout.rb +15 -0
- data/lib/html_email_creator/processor.rb +125 -0
- data/lib/html_email_creator/settings.rb +95 -0
- data/lib/html_email_creator/tags/include_tag.rb +71 -0
- data/lib/html_email_creator/version.rb +3 -0
- data/lib/html_email_creator.rb +46 -0
- data/spec/fixtures/complex_with_config/.html_config.yaml +11 -0
- data/spec/fixtures/complex_with_config/Emails/polite_email.yaml +7 -0
- data/spec/fixtures/complex_with_config/Includes/Emails/love.md +1 -0
- data/spec/fixtures/complex_with_config/Includes/Footers/polite.md +3 -0
- data/spec/fixtures/complex_with_config/Layouts/.keep +0 -0
- data/spec/fixtures/complex_with_config/Layouts/basic.liquid +25 -0
- data/spec/fixtures/complex_with_config/Output/.keep +0 -0
- data/spec/fixtures/default_config/Emails/Newsletter/.keep +0 -0
- data/spec/fixtures/default_config/Layouts/.keep +0 -0
- data/spec/fixtures/default_config/Output/.keep +0 -0
- data/spec/fixtures/with_config/.html_config.yaml +11 -0
- data/spec/fixtures/with_config/Emails/first_email.yaml +7 -0
- data/spec/fixtures/with_config/Includes/Emails/barfoo.md +1 -0
- data/spec/fixtures/with_config/Includes/Emails/foobar.md +1 -0
- data/spec/fixtures/with_config/Includes/Quotes/henry_ford.txt +1 -0
- data/spec/fixtures/with_config/Layouts/.keep +0 -0
- data/spec/fixtures/with_config/Layouts/simple.liquid +7 -0
- data/spec/fixtures/with_config/Output/.keep +0 -0
- data/spec/html_email_creator/email_creator_spec.rb +119 -0
- data/spec/html_email_creator/email_spec.rb +29 -0
- data/spec/html_email_creator/formatter_spec.rb +40 -0
- data/spec/html_email_creator/layout_spec.rb +55 -0
- data/spec/html_email_creator/processor_spec.rb +111 -0
- data/spec/html_email_creator/settings_spec.rb +70 -0
- data/spec/html_email_creator/tags/include_tag_spec.rb +11 -0
- data/spec/spec_helper.rb +32 -0
- metadata +244 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
html_email_creator (0.0.1)
|
5
|
+
commander (>= 4.0.6)
|
6
|
+
inline-style (>= 0.5.0)
|
7
|
+
kramdown (>= 0.13.3)
|
8
|
+
liquid (>= 2.3.0)
|
9
|
+
nokogiri (>= 1.5.0)
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: http://rubygems.org/
|
13
|
+
specs:
|
14
|
+
addressable (2.2.6)
|
15
|
+
commander (4.0.6)
|
16
|
+
highline (~> 1.5.0)
|
17
|
+
css_parser (1.2.5)
|
18
|
+
addressable
|
19
|
+
diff-lcs (1.1.3)
|
20
|
+
facets (2.9.2)
|
21
|
+
ffi (1.0.10)
|
22
|
+
highline (1.5.2)
|
23
|
+
inline-style (0.5.0)
|
24
|
+
css_parser
|
25
|
+
facets
|
26
|
+
maca-fork-csspool
|
27
|
+
nokogiri
|
28
|
+
kramdown (0.13.3)
|
29
|
+
liquid (2.3.0)
|
30
|
+
maca-fork-csspool (2.0.2)
|
31
|
+
ffi
|
32
|
+
nokogiri (1.5.0)
|
33
|
+
rake (0.9.2.2)
|
34
|
+
rspec (2.7.0)
|
35
|
+
rspec-core (~> 2.7.0)
|
36
|
+
rspec-expectations (~> 2.7.0)
|
37
|
+
rspec-mocks (~> 2.7.0)
|
38
|
+
rspec-core (2.7.1)
|
39
|
+
rspec-expectations (2.7.0)
|
40
|
+
diff-lcs (~> 1.1.2)
|
41
|
+
rspec-mocks (2.7.0)
|
42
|
+
|
43
|
+
PLATFORMS
|
44
|
+
ruby
|
45
|
+
|
46
|
+
DEPENDENCIES
|
47
|
+
html_email_creator!
|
48
|
+
rake (>= 0.9.2)
|
49
|
+
rspec
|
data/README.markdown
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'commander/import'
|
4
|
+
require 'html_email_creator'
|
5
|
+
require 'html_email_creator/version'
|
6
|
+
require 'html_email_creator/information'
|
7
|
+
|
8
|
+
# :name is optional, otherwise uses the basename of this executable
|
9
|
+
program :name, 'HTML Email Creator'
|
10
|
+
program :version, HtmlEmailCreator::VERSION
|
11
|
+
program :description, HtmlEmailCreator::DESCRIPTION
|
12
|
+
|
13
|
+
command :create do |c|
|
14
|
+
c.syntax = 'html_email_creator create <email or directory>'
|
15
|
+
c.description = 'Creates a single email or all emails from the directory'
|
16
|
+
c.option '--recursive', 'If creating directory, find from sub directories too.'
|
17
|
+
c.action do |args, options|
|
18
|
+
# TODO implement me
|
19
|
+
recursive = options.recursive ? true : false
|
20
|
+
full_path = File.expand_path(args.first)
|
21
|
+
# run in this directory
|
22
|
+
Dir.chdir(File.dirname(full_path))
|
23
|
+
results = HtmlEmailCreator::EmailCreator.new.save_emails(full_path, recursive)
|
24
|
+
say "Creation completed!\n\n"
|
25
|
+
results.each_pair do |file, format|
|
26
|
+
say "#{file}:"
|
27
|
+
say " Output:"
|
28
|
+
format.values.each do |output|
|
29
|
+
|
30
|
+
say " #{output}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
say "\nHave a nice day :)"
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib/', __FILE__)
|
3
|
+
$:.unshift lib unless $:.include?(lib)
|
4
|
+
|
5
|
+
require 'html_email_creator/version'
|
6
|
+
require 'html_email_creator/information'
|
7
|
+
|
8
|
+
Gem::Specification.new do |s|
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.name = "html_email_creator"
|
11
|
+
s.version = HtmlEmailCreator::VERSION
|
12
|
+
s.summary = HtmlEmailCreator::SUMMARY
|
13
|
+
s.description = HtmlEmailCreator::DESCRIPTION
|
14
|
+
s.default_executable = "html_email_creator"
|
15
|
+
|
16
|
+
s.required_ruby_version = '>= 1.9.2'
|
17
|
+
s.rubygems_version = ">= 1.3.6"
|
18
|
+
s.rubyforge_project = "html_email_creator"
|
19
|
+
|
20
|
+
s.author = 'Pekka Mattila'
|
21
|
+
s.email = 'pekka.mattila@gmail.com'
|
22
|
+
s.homepage = 'https://github.com/pekkaj/HTML-Email-Creator'
|
23
|
+
|
24
|
+
s.files = `git ls-files`.split("\n")
|
25
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
26
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
27
|
+
s.require_paths = ["lib"]
|
28
|
+
|
29
|
+
# Runtime Dependencies
|
30
|
+
|
31
|
+
s.add_runtime_dependency "commander", ">= 4.0.6"
|
32
|
+
s.add_runtime_dependency "kramdown", ">= 0.13.3"
|
33
|
+
s.add_runtime_dependency "liquid", ">= 2.3.0"
|
34
|
+
s.add_runtime_dependency "nokogiri", ">= 1.5.0"
|
35
|
+
s.add_runtime_dependency "inline-style", ">= 0.5.0"
|
36
|
+
|
37
|
+
# Development Dependencies
|
38
|
+
|
39
|
+
s.add_development_dependency "rspec"
|
40
|
+
s.add_development_dependency "rake", ">= 0.9.2"
|
41
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require "liquid"
|
2
|
+
|
3
|
+
module HtmlEmailCreator
|
4
|
+
class Email
|
5
|
+
attr_reader :settings
|
6
|
+
|
7
|
+
def self.find_emails(file_or_directory, recursively = false)
|
8
|
+
if File.directory?(file_or_directory)
|
9
|
+
if recursively
|
10
|
+
Dir.glob(File.join(file_or_directory, "**", "*.yaml"))
|
11
|
+
else
|
12
|
+
Dir.glob(File.join(file_or_directory, "*.yaml"))
|
13
|
+
end
|
14
|
+
else
|
15
|
+
return [] unless File.extname(file_or_directory) == ".yaml"
|
16
|
+
[file_or_directory]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(configuration, settings = HtmlEmailCreator.settings)
|
21
|
+
@settings = settings
|
22
|
+
@configuration = create_configuration(configuration)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Renders emails using configuration. Returns Hash[format, EmailVersion].
|
26
|
+
def render_all
|
27
|
+
# render only once
|
28
|
+
return @versions if @versions
|
29
|
+
|
30
|
+
@versions = {}
|
31
|
+
output_formats.each do |format|
|
32
|
+
@versions[format] = render_only(format)
|
33
|
+
end
|
34
|
+
@versions
|
35
|
+
end
|
36
|
+
|
37
|
+
# Renders email in a specific format
|
38
|
+
def render_only(format)
|
39
|
+
formatter = HtmlEmailCreator::Formatter.new(rendered_email, @settings).find(format)
|
40
|
+
HtmlEmailCreator::EmailVersion.new(formatter, output_basename, @settings)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Convenience method for rendering HTML email.
|
44
|
+
def render_html_email
|
45
|
+
render_only(HtmlEmailCreator::Formatters::HtmlEmail.id)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Convenience method for rendering plain text email.
|
49
|
+
def render_plain_text_email
|
50
|
+
render_only(HtmlEmailCreator::Formatters::PlainTextEmail.id)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def rendered_email
|
56
|
+
@email ||= HtmlEmailCreator::Layout.new(fill_blanks(IO.read(layout_path)), settings.extension_data).to_html
|
57
|
+
end
|
58
|
+
|
59
|
+
def output_formats
|
60
|
+
@configuration["output_formats"]
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_configuration(configuration)
|
64
|
+
config_hash = if configuration.kind_of?(String)
|
65
|
+
YAML.load_file(configuration)
|
66
|
+
else
|
67
|
+
configuration
|
68
|
+
end
|
69
|
+
|
70
|
+
defaults = {
|
71
|
+
"output_formats" => ["plain_text_email", "html_email"]
|
72
|
+
}
|
73
|
+
|
74
|
+
config_hash.merge(defaults)
|
75
|
+
end
|
76
|
+
|
77
|
+
def output_basename
|
78
|
+
@configuration["config"]["output"]
|
79
|
+
end
|
80
|
+
|
81
|
+
def layout_path
|
82
|
+
File.join(@settings.layouts_path, @configuration["config"]["layout"])
|
83
|
+
end
|
84
|
+
|
85
|
+
def fill_blanks(layout)
|
86
|
+
filled_layout = layout.dup
|
87
|
+
@configuration["config"]["data"].each_pair do |key, value|
|
88
|
+
filled_layout.gsub!(/\{\{\s*#{key}\s*\}\}/, value)
|
89
|
+
end
|
90
|
+
filled_layout
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module HtmlEmailCreator
|
2
|
+
class EmailCreator
|
3
|
+
def create_email(file_or_configuration, format)
|
4
|
+
email(file_or_configuration).render_only(format)
|
5
|
+
end
|
6
|
+
|
7
|
+
def create_html_email(file_or_configuration)
|
8
|
+
email(file_or_configuration).render_html_email
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_plain_text_email(file_or_configuration)
|
12
|
+
email(file_or_configuration).render_plain_text_email
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_all_email_versions(file_or_configuration)
|
16
|
+
email(file_or_configuration).render_all
|
17
|
+
end
|
18
|
+
|
19
|
+
def save_email(file_or_configuration)
|
20
|
+
formats_and_paths = {}
|
21
|
+
create_all_email_versions(file_or_configuration).each_value do |version|
|
22
|
+
formats_and_paths[version.id] = version.save
|
23
|
+
end
|
24
|
+
formats_and_paths
|
25
|
+
end
|
26
|
+
|
27
|
+
def save_emails(file_or_directory, recursively = false)
|
28
|
+
files = {}
|
29
|
+
HtmlEmailCreator::Email.find_emails(file_or_directory, recursively).each do |file|
|
30
|
+
files[file] = save_email(file)
|
31
|
+
end
|
32
|
+
files
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def email(file_or_configuration)
|
38
|
+
if file_or_configuration.kind_of?(String)
|
39
|
+
# Is file so update settings before creating email (makes sure that we have the latest settings file)
|
40
|
+
HtmlEmailCreator.update_settings(File.dirname(file_or_configuration))
|
41
|
+
end
|
42
|
+
Email.new(file_or_configuration, HtmlEmailCreator.settings)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module HtmlEmailCreator
|
2
|
+
class EmailVersion
|
3
|
+
def initialize(formatter, output_basename, settings)
|
4
|
+
@formatter = formatter
|
5
|
+
@output_basename = output_basename
|
6
|
+
@settings = settings
|
7
|
+
end
|
8
|
+
|
9
|
+
def get
|
10
|
+
@formatter.format
|
11
|
+
end
|
12
|
+
|
13
|
+
def id
|
14
|
+
@formatter.id
|
15
|
+
end
|
16
|
+
|
17
|
+
def save
|
18
|
+
FileUtils.mkdir_p(@settings.output_path) unless File.exists?(@settings.output_path)
|
19
|
+
file = File.join(@settings.output_path, "#{@output_basename}.#{@formatter.extension}")
|
20
|
+
File.open(file, "w") do |file|
|
21
|
+
file.write(get)
|
22
|
+
end
|
23
|
+
file
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'kramdown'
|
2
|
+
|
3
|
+
module HtmlEmailCreator
|
4
|
+
class Extensions
|
5
|
+
@@EXTENSIONS = {
|
6
|
+
'aweber' => {
|
7
|
+
'email' => '{!email}',
|
8
|
+
'subscription_date' => '{!signdate long}',
|
9
|
+
'unsubscribe_url' => '{!remove_web}',
|
10
|
+
'full_name' => '{!name_fix}',
|
11
|
+
'first_name' => '{!firstname_fix}',
|
12
|
+
'last_name' => '{!lastname_fix}',
|
13
|
+
'company_signature' => '{!signature}',
|
14
|
+
'company_address' => '{!contact_address}',
|
15
|
+
'tomorrow' => '{!date dayname+1}',
|
16
|
+
'after_2_days' => '{!date dayname+2}',
|
17
|
+
'after_3_days' => '{!date dayname+3}',
|
18
|
+
'after_4_days' => '{!date dayname+4}',
|
19
|
+
'after_5_days' => '{!date dayname+5}',
|
20
|
+
'after_6_days' => '{!date dayname+6}',
|
21
|
+
'after_7_days' => '{!date dayname+7}'
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
def initialize(settings = HtmlEmailCreator.settings)
|
26
|
+
@settings = settings
|
27
|
+
end
|
28
|
+
|
29
|
+
def built_in(*extensions)
|
30
|
+
new_data = {}
|
31
|
+
extensions.flatten.each do |extension|
|
32
|
+
data = @@EXTENSIONS[extension]
|
33
|
+
new_data.merge!(data.dup) if data
|
34
|
+
end
|
35
|
+
new_data
|
36
|
+
end
|
37
|
+
|
38
|
+
def custom(data = {}, extensions)
|
39
|
+
new_data = {}
|
40
|
+
extensions.each_pair do |key, value|
|
41
|
+
new_data[key] = value
|
42
|
+
end
|
43
|
+
new_data
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "liquid"
|
2
|
+
|
3
|
+
module HtmlEmailCreator
|
4
|
+
class Formatter
|
5
|
+
@@DEFAULT = HtmlEmailCreator::Formatters::UnknownFormatter
|
6
|
+
@@CONFIG = {}
|
7
|
+
|
8
|
+
[
|
9
|
+
HtmlEmailCreator::Formatters::Markdown,
|
10
|
+
HtmlEmailCreator::Formatters::PlainTextEmail,
|
11
|
+
HtmlEmailCreator::Formatters::HtmlEmail
|
12
|
+
].each do |klass|
|
13
|
+
@@CONFIG[klass.id] = klass
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(text, settings = HtmlEmailCreator.settings)
|
17
|
+
@text = text
|
18
|
+
@settings = settings
|
19
|
+
end
|
20
|
+
|
21
|
+
def find(format)
|
22
|
+
klass = @@CONFIG[format.to_sym] || @@DEFAULT
|
23
|
+
klass.send(:new, @text, @settings)
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_by_filename(filename)
|
27
|
+
find(File.extname(filename).split(".").last)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module HtmlEmailCreator
|
2
|
+
module Formatters
|
3
|
+
class Formatter
|
4
|
+
def self.id
|
5
|
+
raise "id needs to be defined"
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.extension
|
9
|
+
raise "extension needs to be defined"
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(text, settings)
|
13
|
+
@text = text
|
14
|
+
@settings = settings
|
15
|
+
end
|
16
|
+
|
17
|
+
# override to implement a correct formatter
|
18
|
+
def format
|
19
|
+
@text
|
20
|
+
end
|
21
|
+
|
22
|
+
def id
|
23
|
+
self.class.id
|
24
|
+
end
|
25
|
+
|
26
|
+
def extension
|
27
|
+
self.class.extension
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|