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
@@ -0,0 +1 @@
|
|
1
|
+
I really love {{ what }}. {{ great }}
|
File without changes
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
5
|
+
<title>{{ title_content }}</title>
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
|
9
|
+
<style type="text/css">
|
10
|
+
.h1 div{font-family:Helvetica}
|
11
|
+
ul{margin: 5px 5px 5px 5px}
|
12
|
+
</style>
|
13
|
+
|
14
|
+
<h1>Header 1 starts</h1>
|
15
|
+
|
16
|
+
Hi {{ full_name }},
|
17
|
+
|
18
|
+
{{ header_1_content }}
|
19
|
+
|
20
|
+
<h2>Header 2 starts</h2>
|
21
|
+
|
22
|
+
{{ header_2_content }}
|
23
|
+
|
24
|
+
</body>
|
25
|
+
</html>
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
bar foo
|
@@ -0,0 +1 @@
|
|
1
|
+
foo bar
|
@@ -0,0 +1 @@
|
|
1
|
+
A bore is a person who opens his {{ what }} and puts his feats in it.
|
File without changes
|
File without changes
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe HtmlEmailCreator::EmailCreator do
|
4
|
+
let(:creator) { HtmlEmailCreator::EmailCreator.new }
|
5
|
+
let(:email) { fixture_dir("complex_with_config", "Emails", "polite_email.yaml") }
|
6
|
+
let(:expected_basic_text_html) {
|
7
|
+
html = <<eos
|
8
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
9
|
+
<html>
|
10
|
+
<head>
|
11
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
12
|
+
<title>A variant</title>
|
13
|
+
</head>
|
14
|
+
<body>
|
15
|
+
|
16
|
+
<div class="h1"><div style="font-family: Helvetica;">Header 1 starts</div></div>
|
17
|
+
|
18
|
+
Hi {!name_fix},
|
19
|
+
|
20
|
+
**Logo**: WOHOO.
|
21
|
+
|
22
|
+
<div class="h2"><div>Header 2 starts</div></div>
|
23
|
+
|
24
|
+
<p>I really love iPhone. GREAT!</p>
|
25
|
+
|
26
|
+
</body>
|
27
|
+
</html>
|
28
|
+
eos
|
29
|
+
}
|
30
|
+
|
31
|
+
let(:expected_basic_text_txt) {
|
32
|
+
text = <<eos
|
33
|
+
=============================================================================
|
34
|
+
Header 1 starts
|
35
|
+
|
36
|
+
Hi {!name_fix},
|
37
|
+
|
38
|
+
**Logo**: WOHOO.
|
39
|
+
|
40
|
+
-----------------------------------------------------------------------------
|
41
|
+
Header 2 starts
|
42
|
+
|
43
|
+
I really love iPhone. GREAT!
|
44
|
+
eos
|
45
|
+
text.strip
|
46
|
+
}
|
47
|
+
|
48
|
+
let(:expected_first_html) {
|
49
|
+
html = <<eos
|
50
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
51
|
+
<html><body>
|
52
|
+
<p>This is simple template.
|
53
|
+
|
54
|
+
</p>
|
55
|
+
<p>foo bar</p>
|
56
|
+
|
57
|
+
<p>bar foo</p>
|
58
|
+
|
59
|
+
<img src="http://cdn.example.com/foo/bar" alt="alt text" border="0">
|
60
|
+
</body></html>
|
61
|
+
eos
|
62
|
+
}
|
63
|
+
|
64
|
+
let(:expected_first_txt) {
|
65
|
+
text = <<eos
|
66
|
+
This is simple template.
|
67
|
+
|
68
|
+
foo bar
|
69
|
+
|
70
|
+
bar foo
|
71
|
+
|
72
|
+
alt text (http://cdn.example.com/foo/bar)
|
73
|
+
eos
|
74
|
+
text.strip
|
75
|
+
}
|
76
|
+
|
77
|
+
describe "HTML mail" do
|
78
|
+
it "should create well formed and expected HTML mail" do
|
79
|
+
creator.create_html_email(email).get.should == expected_basic_text_html
|
80
|
+
creator.create_email(email, HtmlEmailCreator::Formatters::HtmlEmail.id).get.should == expected_basic_text_html
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "Plain text mail" do
|
85
|
+
it "should create well formed and expected plain text email" do
|
86
|
+
creator.create_plain_text_email(email).get.should == expected_basic_text_txt
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "Saving email to a filesystem" do
|
91
|
+
after(:each) { clean_fixture_output }
|
92
|
+
|
93
|
+
it "should be possible to store emails recursively" do
|
94
|
+
creator.save_emails(".").should be_empty
|
95
|
+
creator.save_emails(".", true).should_not be_empty
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should store all correct versions of emails recursively" do
|
99
|
+
emails = creator.save_emails(".", true)
|
100
|
+
|
101
|
+
read_fixture("complex_with_config", "Output", "basic_text.html").should == expected_basic_text_html
|
102
|
+
read_fixture("complex_with_config", "Output", "basic_text.txt").should == expected_basic_text_txt
|
103
|
+
read_fixture("with_config", "Output", "first.html").should == expected_first_html
|
104
|
+
read_fixture("with_config", "Output", "first.txt").should == expected_first_txt
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should store only one file if needed using absolute paths" do
|
108
|
+
IO.read(creator.create_html_email(fixture_dir("complex_with_config", "Emails", "polite_email.yaml")).save).should == expected_basic_text_html
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should store only one file if needed using relative paths" do
|
112
|
+
run_in_fixture_dir("complex_with_config") do
|
113
|
+
email_creator = HtmlEmailCreator::EmailCreator.new
|
114
|
+
IO.read(email_creator.create_html_email(File.join("Emails", "polite_email.yaml")).save).should == expected_basic_text_html
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe HtmlEmailCreator::Email do
|
4
|
+
let(:email) {
|
5
|
+
HtmlEmailCreator::Email.new(fixture_dir("with_config", "Emails", "first_email.yaml")).render_only(:html_email)
|
6
|
+
}
|
7
|
+
|
8
|
+
let(:expected_html) {
|
9
|
+
html = <<eos
|
10
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
11
|
+
<html><body>
|
12
|
+
<p>This is simple template.
|
13
|
+
|
14
|
+
</p>
|
15
|
+
<p>foo bar</p>
|
16
|
+
|
17
|
+
<p>bar foo</p>
|
18
|
+
|
19
|
+
<img src="http://cdn.example.com/foo/bar" alt="alt text" border="0">
|
20
|
+
</body></html>
|
21
|
+
eos
|
22
|
+
}
|
23
|
+
|
24
|
+
it "should render markdown and liquid templates using settings and email configuration" do
|
25
|
+
run_in_fixture_dir("with_config") do
|
26
|
+
email.get.should eql(expected_html)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe HtmlEmailCreator::Formatter do
|
4
|
+
describe "Markdown" do
|
5
|
+
let(:md) { HtmlEmailCreator::Formatters::Markdown.id }
|
6
|
+
|
7
|
+
it "should convert correctly" do
|
8
|
+
HtmlEmailCreator::Formatter.new("**I am strong**").find(md).format.should eql("<p><strong>I am strong</strong></p>")
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should support table extension" do
|
12
|
+
markdown = <<-eos
|
13
|
+
| First | Second | Third |
|
14
|
+
|:------|:-------|:------|
|
15
|
+
| 1 | 2 | 3 |
|
16
|
+
eos
|
17
|
+
|
18
|
+
html = <<eos
|
19
|
+
<table>
|
20
|
+
<thead>
|
21
|
+
<tr>
|
22
|
+
<th style="text-align: left">First</th>
|
23
|
+
<th style="text-align: left">Second</th>
|
24
|
+
<th style="text-align: left">Third</th>
|
25
|
+
</tr>
|
26
|
+
</thead>
|
27
|
+
<tbody>
|
28
|
+
<tr>
|
29
|
+
<td style="text-align: left">1</td>
|
30
|
+
<td style="text-align: left">2</td>
|
31
|
+
<td style="text-align: left">3</td>
|
32
|
+
</tr>
|
33
|
+
</tbody>
|
34
|
+
</table>
|
35
|
+
eos
|
36
|
+
|
37
|
+
HtmlEmailCreator::Formatter.new(markdown).find(md).format.should eql(html.strip)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe HtmlEmailCreator::Layout do
|
4
|
+
|
5
|
+
describe "with custom variables" do
|
6
|
+
it "should replace variables" do
|
7
|
+
HtmlEmailCreator::Layout.new("foo {{ bar }}").to_html("bar" => "great bar").should eql("foo great bar")
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should just ignore the variable if the variable was not found" do
|
11
|
+
HtmlEmailCreator::Layout.new("foo {{ bar }}").to_html.should eql("foo ")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "with built-in extensions" do
|
16
|
+
|
17
|
+
describe "aweber" do
|
18
|
+
let(:aweber) { HtmlEmailCreator::Extensions.new.built_in("aweber") }
|
19
|
+
let(:none) { {} }
|
20
|
+
|
21
|
+
it "should replace Aweber extension keys correctly if aweber extension is being used" do
|
22
|
+
HtmlEmailCreator::Layout.new("{{ after_7_days }}", aweber).to_html.should eql('{!date dayname+7}')
|
23
|
+
HtmlEmailCreator::Layout.new("{{ after_7_days }}", none).to_html.should eql('')
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should replace Aweber extension keys correctly if aweber extension is being used in settings" do
|
27
|
+
run_in_fixture_dir("with_config") do
|
28
|
+
HtmlEmailCreator::Layout.new("{{ after_7_days }}").to_html.should eql('{!date dayname+7}')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "with custom extensions" do
|
35
|
+
|
36
|
+
it "should replace custom extension keys correctly use custom extensions from configuration to render the layout" do
|
37
|
+
run_in_fixture_dir("with_config") do
|
38
|
+
HtmlEmailCreator::Layout.new("{{ foobar }}").to_html.should eql('Hi, this is foobar.')
|
39
|
+
HtmlEmailCreator::Layout.new("{{ great }}").to_html.should eql('Hi, this is **great**')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "with built-in filters" do
|
46
|
+
|
47
|
+
it "should generate photo url correctly" do
|
48
|
+
run_in_fixture_dir("with_config") do
|
49
|
+
markdown = '{{ "hello/world.jpg" | photo: "Custom alt text" }}'
|
50
|
+
output = '<img src="http://cdn.example.com/hello/world.jpg" alt="Custom alt text" border="0" />'
|
51
|
+
HtmlEmailCreator::Layout.new(markdown).to_html.should eql(output)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe HtmlEmailCreator::Processor do
|
4
|
+
|
5
|
+
let(:processor) {
|
6
|
+
html = <<-eos
|
7
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
8
|
+
<html>
|
9
|
+
<head>
|
10
|
+
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
11
|
+
<title>Title</title>
|
12
|
+
</head>
|
13
|
+
<body>
|
14
|
+
|
15
|
+
<style type="text/css">
|
16
|
+
.h1 div{font-family:Helvetica}
|
17
|
+
ul{margin: 5px 5px 5px 5px}
|
18
|
+
</style>
|
19
|
+
|
20
|
+
<h1>Header 1</h1>
|
21
|
+
|
22
|
+
<table class="inline">
|
23
|
+
<tr><td>col1</td><td>col2</td>
|
24
|
+
<tr><td>row 1 col 1</td><td>row 1 col 2</td>
|
25
|
+
<tr><td>row 2 col 1</td><td>row 2 col 2</td>
|
26
|
+
</table>
|
27
|
+
|
28
|
+
This is simple email with <a href="http://link1.com">link</a>
|
29
|
+
|
30
|
+
<p><img src="http://cdn.example.com/foo/bar" alt="Great image" border="0" /></p>
|
31
|
+
|
32
|
+
<p><a href="http://signup"><img src="http://cdn.example.com/foo/bar" alt="Signup" border="0" /></a></p>
|
33
|
+
|
34
|
+
<h2>Header 2</h2>
|
35
|
+
|
36
|
+
<ul>
|
37
|
+
<li>list 1</li>
|
38
|
+
<li>list 2</li>
|
39
|
+
</ul>
|
40
|
+
</body>
|
41
|
+
</html>
|
42
|
+
eos
|
43
|
+
|
44
|
+
HtmlEmailCreator::Processor.new(html)
|
45
|
+
}
|
46
|
+
|
47
|
+
describe "#to_html" do
|
48
|
+
let(:html) { processor.to_html }
|
49
|
+
|
50
|
+
it "should wrap headers with divs" do
|
51
|
+
html.should include('<div class="h1"><div style="font-family: Helvetica;">Header 1</div></div>')
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should inline styles" do
|
55
|
+
html.should include('<ul style="margin: 5px 5px 5px 5px;">')
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#to_plain_text" do
|
61
|
+
let(:text) { processor.to_plain_text }
|
62
|
+
|
63
|
+
it "format plain text message in a nice way" do
|
64
|
+
expected_output = <<-eos
|
65
|
+
=============================================================================
|
66
|
+
Header 1
|
67
|
+
|
68
|
+
col1
|
69
|
+
* row 1 col 1
|
70
|
+
* row 2 col 1
|
71
|
+
|
72
|
+
col2
|
73
|
+
* row 1 col 2
|
74
|
+
* row 2 col 2
|
75
|
+
|
76
|
+
This is simple email with link (http://link1.com)
|
77
|
+
|
78
|
+
Great image (http://cdn.example.com/foo/bar)
|
79
|
+
|
80
|
+
Signup (http://signup)
|
81
|
+
|
82
|
+
-----------------------------------------------------------------------------
|
83
|
+
Header 2
|
84
|
+
|
85
|
+
- list 1
|
86
|
+
- list 2
|
87
|
+
eos
|
88
|
+
|
89
|
+
text.should eq(expected_output.strip)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "aweber escaping" do
|
94
|
+
it "should not escape aweber markup if using aweber extension" do
|
95
|
+
html = <<-eos
|
96
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
97
|
+
<html>
|
98
|
+
<body>
|
99
|
+
<p>{!date dayname+7}</p>
|
100
|
+
</body>
|
101
|
+
</html>
|
102
|
+
eos
|
103
|
+
|
104
|
+
run_in_fixture_dir("with_config") do
|
105
|
+
processor = HtmlEmailCreator::Processor.new(html)
|
106
|
+
processor.to_html.should include("<p>{!date dayname+7}</p>")
|
107
|
+
processor.to_plain_text.should include("{!date dayname+7}")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|