html_email_creator 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|