antwort 0.0.12 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +12 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +28 -1
- data/README.md +1 -1
- data/antwort.gemspec +2 -2
- data/lib/antwort.rb +5 -4
- data/lib/antwort/builder/builder.rb +15 -24
- data/lib/antwort/builder/email.rb +47 -22
- data/lib/antwort/builder/flattener.rb +8 -9
- data/lib/antwort/builder/partial.rb +12 -11
- data/lib/antwort/builder/style.rb +26 -27
- data/lib/antwort/{builder.rb → builders.rb} +3 -3
- data/lib/antwort/cli.rb +0 -1
- data/lib/antwort/cli/cli.rb +42 -48
- data/lib/antwort/cli/send.rb +11 -14
- data/lib/antwort/cli/upload.rb +29 -28
- data/lib/antwort/core.rb +4 -0
- data/lib/antwort/email/build.rb +41 -0
- data/lib/antwort/email/collection.rb +41 -0
- data/lib/antwort/email/data.rb +27 -0
- data/lib/antwort/email/template.rb +88 -0
- data/lib/antwort/helpers/file_helper.rb +27 -0
- data/lib/antwort/{helpers.rb → helpers/helper.rb} +2 -2
- data/lib/antwort/helpers/logic_helper.rb +81 -0
- data/lib/antwort/helpers/markup_helper.rb +37 -0
- data/lib/antwort/{builder/helpers/sanitizers.rb → helpers/sanitizers_helper.rb} +2 -4
- data/lib/antwort/helpers/server_helper.rb +32 -0
- data/lib/antwort/{server.rb → server/server.rb} +26 -23
- data/{template/project → lib/antwort/server}/views/404.html.erb +1 -1
- data/{template/project → lib/antwort/server}/views/index.html.erb +4 -6
- data/{template/project → lib/antwort/server}/views/layout.erb +5 -5
- data/{template/project/views/markup/_button.html.erb → lib/antwort/server/views/markup/button.html.erb} +0 -0
- data/{template/project/views/markup/_image_tag.html.erb → lib/antwort/server/views/markup/image_tag.html.erb} +0 -0
- data/{template/project → lib/antwort/server}/views/server.erb +0 -0
- data/lib/antwort/version.rb +1 -1
- data/spec/builder/builder_spec.rb +17 -22
- data/spec/builder/email_spec.rb +11 -12
- data/spec/builder/flattener_spec.rb +20 -21
- data/spec/builder/helpers_logic_spec.rb +69 -73
- data/spec/builder/partial_spec.rb +42 -51
- data/spec/builder/style_spec.rb +25 -34
- data/spec/{cli_spec.rb → cli/cli_spec.rb} +8 -9
- data/spec/cli/send_spec.rb +80 -0
- data/spec/cli/upload_spec.rb +17 -9
- data/spec/email/build_spec.rb +13 -0
- data/spec/email/collection_spec.rb +56 -0
- data/spec/email/data_spec.rb +40 -0
- data/spec/email/template_spec.rb +116 -0
- data/spec/fixtures/assets/css/demo/include.scss +3 -0
- data/spec/fixtures/assets/css/demo/inline.scss +33 -0
- data/spec/fixtures/assets/css/no-images/include.scss +1 -0
- data/spec/fixtures/assets/css/no-images/inline.scss +2 -0
- data/spec/fixtures/assets/css/shared/_base.scss +64 -0
- data/spec/fixtures/assets/css/shared/_mixins.scss +25 -0
- data/spec/fixtures/assets/css/shared/_reset.scss +59 -0
- data/spec/fixtures/assets/css/shared/_vars.scss +12 -0
- data/spec/fixtures/assets/css/shared/include.scss +23 -0
- data/spec/fixtures/assets/css/shared/inline.scss +9 -0
- data/spec/fixtures/build/demo-20160101/demo.html +177 -0
- data/spec/fixtures/build/demo-20160101/source/demo.html +118 -0
- data/spec/fixtures/build/demo-20160101/source/include.css +58 -0
- data/spec/fixtures/build/demo-20160101/source/inline.css +83 -0
- data/spec/fixtures/build/demo-20160102/demo.html +177 -0
- data/spec/fixtures/build/demo-20160102/source/demo.html +118 -0
- data/spec/fixtures/build/demo-20160102/source/include.css +58 -0
- data/spec/fixtures/build/demo-20160102/source/inline.css +83 -0
- data/{template/project/data/.empty_directory → spec/fixtures/emails/1-demo/_bar.erb} +0 -0
- data/spec/fixtures/emails/1-demo/_foo.erb +0 -0
- data/spec/fixtures/emails/1-demo/index.html.erb +2 -2
- data/spec/fixtures/emails/4-custom-layout/index.html.erb +6 -0
- data/spec/fixtures/emails/4-custom-layout/layout.erb +5 -0
- data/spec/fixtures/emails/demo/index.html.erb +4 -0
- data/spec/fixtures/emails/no-images/index.html.erb +4 -0
- data/spec/fixtures/emails/shared/_foo.erb +0 -0
- data/spec/fixtures/{views → emails/shared}/layout.erb +0 -0
- data/spec/helpers/file_helper_spec.rb +30 -0
- data/spec/server/server_spec.rb +57 -0
- data/spec/spec_helper.rb +18 -7
- data/template/project/Gemfile.tt +1 -7
- metadata +92 -42
- data/lib/antwort/builder/helpers/logic.rb +0 -82
- data/lib/antwort/cli/helpers.rb +0 -44
- data/lib/antwort/server/helpers.rb +0 -67
- data/lib/antwort/server/markup.rb +0 -39
- data/spec/cli/helpers_spec.rb +0 -60
- data/spec/fixtures/build/demo-123456/build.html +0 -7
- data/spec/fixtures/build/demo-123457/build.html +0 -7
- data/spec/fixtures/build/demo-bar-123/build.html +0 -7
- data/spec/fixtures/views/404.html.erb +0 -1
- data/spec/fixtures/views/index.html.erb +0 -14
- data/spec/fixtures/views/server.erb +0 -5
- data/spec/server_spec.rb +0 -54
- data/template/project/.ruby-version +0 -1
- data/template/project/data/config.yml +0 -3
@@ -1,82 +0,0 @@
|
|
1
|
-
module Antwort
|
2
|
-
module LogicHelpers
|
3
|
-
|
4
|
-
def preserve_nbsps(html = '')
|
5
|
-
html.gsub(/ /, '%nbspace%')
|
6
|
-
end
|
7
|
-
|
8
|
-
def restore_nbsps(html = '')
|
9
|
-
html.gsub(/%nbspace%/, ' ')
|
10
|
-
end
|
11
|
-
|
12
|
-
def preserve_logic(html = '')
|
13
|
-
html = preserve_comments(html)
|
14
|
-
html = preserve_conditionals(html) # conditionals before loops, in case we have them inside loops
|
15
|
-
html = preserve_loops(html)
|
16
|
-
html = preserve_variables(html)
|
17
|
-
html = preserve_assignments(html)
|
18
|
-
html = convert_partials_to_includes(html)
|
19
|
-
html = convert_helper_wrappers(html)
|
20
|
-
html = preserve_leftover_statements(html) # must be last
|
21
|
-
html
|
22
|
-
end
|
23
|
-
|
24
|
-
def preserve_conditionals(html = '')
|
25
|
-
html.gsub(%r{<%\s*if (.*?)%>}, '{% if \1 %}') # if
|
26
|
-
.gsub(%r{<%\s*unless (.*?)%>}, '{% if !( \1) %}') # unless
|
27
|
-
.gsub(%r{<%\s*elsif(.*?)%>}, '{% elseif\1%}') # elsif
|
28
|
-
.gsub(%r{<%\s*else\s*%>}, '{% else %}') # else
|
29
|
-
.gsub(%r{<%\s*end\s*%>}, '{% end %}') # end
|
30
|
-
.gsub(/[ \t]{2,}%}/, ' %}') # remove extra white space, e.g. {% else %}
|
31
|
-
end
|
32
|
-
|
33
|
-
def preserve_loops(html = '')
|
34
|
-
html.gsub(%r{<%\s+(.*)(\.each\s+do\s+\|)\s*(\S+)\s*(\|\s+)%>}, '{% for \3 in \1 %}')
|
35
|
-
.gsub(%r{<%\s+(.*)(\.each_with_index\s+do\s+\|)\s*(\S+)\s*,\s*(\S+)\s*(\|\s+)%>}, '{% for \3 in \1 with: {@index: \4} %}')
|
36
|
-
.gsub(%r{<%\s*end\s*%>}, '{% end %}')
|
37
|
-
end
|
38
|
-
|
39
|
-
def preserve_comments(html = '')
|
40
|
-
html.gsub(%r{<%[ \t]*#(.*)%>},'{#\1#}')
|
41
|
-
.gsub(/{#([^=\s])/, '{# \1') # {#foo #} ->{# foo #}
|
42
|
-
end
|
43
|
-
|
44
|
-
def preserve_variables(html = '')
|
45
|
-
html.gsub(/\[:(.*?)\]/, '.\1') # a[:b][:c] -> a.b.c
|
46
|
-
.gsub(/\['(.*?)'\]/, '.\1') # a['b'] -> a.b
|
47
|
-
.gsub(/\["(.*?)"\]/, '.\1') # a["b"] -> a.b
|
48
|
-
.gsub(%r{<%=(.*?)%>}, '{{\1}}') # assume leftover erb output are variables
|
49
|
-
end
|
50
|
-
|
51
|
-
def preserve_assignments(html = '')
|
52
|
-
html.gsub(%r{<%\s+([A-Za-z0-9_]+)\s*(\|\|=)\s*(.*)\s+%>}, '{% set \1 = \1 || \3 %}')
|
53
|
-
.gsub(%r{<%\s+([A-Za-z0-9_]+)\s*(=)\s*(.*)\s+%>}, '{% set \1 = \3 %}')
|
54
|
-
end
|
55
|
-
|
56
|
-
def preserve_leftover_statements(html = '')
|
57
|
-
html.gsub(%r{<%\s*(.*?)?%>}, '{% \1%}') # no trailing space because group captures it
|
58
|
-
end
|
59
|
-
|
60
|
-
def restore_variables_in_links(html = '')
|
61
|
-
html.gsub('%7B%7B%20','{{ ')
|
62
|
-
.gsub('%20%7D%7D',' }}')
|
63
|
-
end
|
64
|
-
|
65
|
-
def convert_partials_to_includes(html = '')
|
66
|
-
html.gsub(%r{{{ partial :(.+?) }}}, '{% include \1 %}')
|
67
|
-
.gsub(%r{{% include (.+),\s+locals:(.+?)%}}, '{% include \1 with:\2%}')
|
68
|
-
.gsub(%r{(<%=\s+?partial\s+?:)(.+?),(.+?)(locals:)((.|\n)+?)(%>)}, '{% include \2 with:\5%}') # multiline partials not caught in presumably leftover variable
|
69
|
-
end
|
70
|
-
|
71
|
-
def convert_helper_wrappers(html = '')
|
72
|
-
html.gsub(%r{{{ button(.+?)}}}, '{% button\1%}')
|
73
|
-
.gsub(%r{{{ image_tag(.+?)}}}, '{% image_tag\1%}')
|
74
|
-
end
|
75
|
-
|
76
|
-
def cleanup_logic(html = '')
|
77
|
-
html.gsub(%r{({%|{{)(.*?)(<)(.*?)(}}|%})}, '\1\2<\4\5') # <
|
78
|
-
.gsub(%r{({%|{{)(.*?)(>)(.*?)(}}|%})}, '\1\2>\4\5') # >
|
79
|
-
.gsub(/&&/, '&&')
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
data/lib/antwort/cli/helpers.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
module Antwort
|
2
|
-
module CLIHelpers
|
3
|
-
|
4
|
-
def built_emails
|
5
|
-
list_folders('./build')
|
6
|
-
end
|
7
|
-
|
8
|
-
def available_emails
|
9
|
-
list_folders('./emails')
|
10
|
-
end
|
11
|
-
|
12
|
-
def images_dir(email_id)
|
13
|
-
"./assets/images/#{email_id}"
|
14
|
-
end
|
15
|
-
|
16
|
-
def count_files(dir)
|
17
|
-
Dir[File.join(dir, '**', '*')].count { |f| File.file? f }
|
18
|
-
end
|
19
|
-
|
20
|
-
def last_build_by_id(email_id)
|
21
|
-
built_emails.select { |f| f.split('-')[0..-2].join('-') == email_id }.sort.last
|
22
|
-
end
|
23
|
-
|
24
|
-
def list_folders(folder_name)
|
25
|
-
path = File.expand_path(folder_name)
|
26
|
-
Dir.entries(path).select { |f| !f.include? '.' }
|
27
|
-
end
|
28
|
-
|
29
|
-
def list_partials(folder_name)
|
30
|
-
path = File.expand_path(folder_name)
|
31
|
-
Dir.entries(path).select { |f| f[0]== '_' && f[-4,4] == '.erb' }
|
32
|
-
end
|
33
|
-
|
34
|
-
def folder_exists?(folder_name)
|
35
|
-
if Dir.exists?(folder_name)
|
36
|
-
return true
|
37
|
-
else
|
38
|
-
say "Error: Folder #{folder_name} does not exist.", :red
|
39
|
-
return false
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
44
|
-
end
|
@@ -1,67 +0,0 @@
|
|
1
|
-
module Antwort
|
2
|
-
module ApplicationHelpers
|
3
|
-
|
4
|
-
def sanitize_param(string)
|
5
|
-
string.nil? ? '' : string.gsub(/([^A-Za-z0-9_\/-]+)|(--)/, '_')
|
6
|
-
end
|
7
|
-
|
8
|
-
def get_template_file(template_name)
|
9
|
-
# Dir.entries("your/folder").select {|f| !File.directory? f}
|
10
|
-
"#{settings.views}/emails/#{template_name}/index.html.erb"
|
11
|
-
end
|
12
|
-
|
13
|
-
def get_page_title(template_name)
|
14
|
-
get_metadata(template_name)[:title] || 'Untitled'
|
15
|
-
end
|
16
|
-
|
17
|
-
def get_metadata(template_name)
|
18
|
-
read_template(template_name)[:metadata]
|
19
|
-
end
|
20
|
-
|
21
|
-
def read_template(template_name)
|
22
|
-
file = get_template_file(template_name)
|
23
|
-
|
24
|
-
data = File.read(file)
|
25
|
-
md = data.match(/^(?<metadata>---\s*\n.*?\n?)^(---\s*$\n?)/m)
|
26
|
-
{
|
27
|
-
body: (md.nil?) ? data : md.post_match,
|
28
|
-
metadata: (md.nil?) ? {} : symbolize_keys!(YAML.load(md[:metadata]))
|
29
|
-
}
|
30
|
-
end
|
31
|
-
|
32
|
-
def fetch_data_yaml(template_name)
|
33
|
-
data = {}
|
34
|
-
data_file = settings.root + '/data/' + template_name + '.yml'
|
35
|
-
if File.file? data_file
|
36
|
-
data = YAML.load_file(data_file)
|
37
|
-
data = symbolize_keys! data if data
|
38
|
-
end
|
39
|
-
data
|
40
|
-
end
|
41
|
-
|
42
|
-
def template_exists?(template_name)
|
43
|
-
File.file? settings.templates_dir + '/' + template_name + '/index.html.erb'
|
44
|
-
end
|
45
|
-
|
46
|
-
def template_from_path
|
47
|
-
request.path_info.gsub(%r{/template/}i, '')
|
48
|
-
end
|
49
|
-
|
50
|
-
def hash_to_instance_vars(data)
|
51
|
-
data.each { |k, v| instance_variable_set("@#{k}", v) } if data
|
52
|
-
end
|
53
|
-
|
54
|
-
def image_url_from_path(path)
|
55
|
-
p = path.split(':')[0]
|
56
|
-
if (p == 'http' || p == 'https')
|
57
|
-
url = path
|
58
|
-
else
|
59
|
-
a = [path]
|
60
|
-
a.unshift(template_from_path) unless path[0] == '/'
|
61
|
-
a.unshift('/assets')
|
62
|
-
url = File.join(a)
|
63
|
-
end
|
64
|
-
url
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
module Antwort
|
2
|
-
module MarkupHelpers
|
3
|
-
def image_tag(path, options = {})
|
4
|
-
options[:source] = image_url_from_path(path)
|
5
|
-
options[:alt] ||= ''
|
6
|
-
partial('views/markup/image_tag', locals: options)
|
7
|
-
.gsub(/\n/, '')
|
8
|
-
end
|
9
|
-
|
10
|
-
def button(text, url, args = {})
|
11
|
-
options = {
|
12
|
-
text: text,
|
13
|
-
url: url
|
14
|
-
}.merge(args)
|
15
|
-
partial('views/markup/button', locals: options)
|
16
|
-
end
|
17
|
-
|
18
|
-
def wrapper_table(args = {}, &block)
|
19
|
-
options = {
|
20
|
-
width: '100%',
|
21
|
-
cell_align: 'center',
|
22
|
-
cell_valign: 'top',
|
23
|
-
content: capture_html(&block)
|
24
|
-
}.merge(args)
|
25
|
-
|
26
|
-
concat_content partial('views/markup/table_wrapper', locals: options)
|
27
|
-
end
|
28
|
-
|
29
|
-
def counter_classes(index)
|
30
|
-
# 0 index based
|
31
|
-
klass = ''
|
32
|
-
klass += index.even? ? ' is-2n' : ''
|
33
|
-
klass += (index % 3 == 0) ? ' is-3n' : ''
|
34
|
-
klass += (index % 4 == 0) ? ' is-4n' : ''
|
35
|
-
klass += (index % 6 == 0) ? ' is-6n' : ''
|
36
|
-
klass
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
data/spec/cli/helpers_spec.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
class Dummy
|
4
|
-
end
|
5
|
-
|
6
|
-
describe Antwort::CLIHelpers do
|
7
|
-
|
8
|
-
before :each do
|
9
|
-
@helper = Dummy.new
|
10
|
-
@helper.extend(Antwort::CLIHelpers)
|
11
|
-
end
|
12
|
-
|
13
|
-
before :all do
|
14
|
-
Dir.chdir(fixtures_root)
|
15
|
-
end
|
16
|
-
|
17
|
-
describe 'CLI Helpers' do
|
18
|
-
|
19
|
-
it '#built_emails' do
|
20
|
-
b = @helper.built_emails
|
21
|
-
expect(b).to include('demo-123456')
|
22
|
-
expect(b).not_to include('2-no-layout')
|
23
|
-
end
|
24
|
-
|
25
|
-
it '#available_emails - lists all available emails' do
|
26
|
-
a = @helper.available_emails
|
27
|
-
expect(a).to include('1-demo')
|
28
|
-
expect(a).to include('2-no-layout')
|
29
|
-
expect(a).to include('3-no-title')
|
30
|
-
end
|
31
|
-
|
32
|
-
it '#images_dir - returns images asset path by EMAIL_ID' do
|
33
|
-
expect(@helper.images_dir('foo')).to eq './assets/images/foo'
|
34
|
-
end
|
35
|
-
|
36
|
-
it '#count_files' do
|
37
|
-
expect(@helper.count_files './assets/images/shared').to be(2)
|
38
|
-
expect(@helper.count_files './assets/images/1-demo').to be(1)
|
39
|
-
end
|
40
|
-
|
41
|
-
it '#last_build_by_id' do
|
42
|
-
expect(@helper.last_build_by_id 'foo').to eq('foo-1')
|
43
|
-
expect(@helper.last_build_by_id 'demo').to eq('demo-123457')
|
44
|
-
expect(@helper.last_build_by_id 'demo').not_to eq('demo-123456')
|
45
|
-
expect(@helper.last_build_by_id 'demo').not_to eq('demo-bar-123')
|
46
|
-
end
|
47
|
-
|
48
|
-
it '#list_folders' do
|
49
|
-
a = @helper.list_folders '.'
|
50
|
-
expect(a).to include('assets')
|
51
|
-
expect(a).to include('build')
|
52
|
-
expect(a).to include('data')
|
53
|
-
expect(a).to include('emails')
|
54
|
-
expect(a).to include('views')
|
55
|
-
expect(a).not_to include('support')
|
56
|
-
expect(a).not_to include('lib')
|
57
|
-
end
|
58
|
-
|
59
|
-
end
|
60
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
404 error, template not found
|
data/spec/server_spec.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe 'Antwort Server' do
|
4
|
-
|
5
|
-
def app
|
6
|
-
Antwort::Server
|
7
|
-
end
|
8
|
-
|
9
|
-
describe "Index page" do
|
10
|
-
it "is valid" do
|
11
|
-
get '/'
|
12
|
-
expect(last_response.status).to eq(200)
|
13
|
-
end
|
14
|
-
|
15
|
-
it "lists available templates by title, includes link" do
|
16
|
-
get '/'
|
17
|
-
expect(last_response.body).to include('Email One')
|
18
|
-
expect(last_response.body).to include('Email Two')
|
19
|
-
expect(last_response.body).to include('<a href="template/1-demo">')
|
20
|
-
expect(last_response.body).to include('<a href="template/2-no-layout">')
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
describe "Template show action" do
|
25
|
-
|
26
|
-
it "shows email preview" do
|
27
|
-
get '/template/1-demo'
|
28
|
-
expect(last_response.body).to include('<h1>Hello One</h1>')
|
29
|
-
expect(last_response.body).to include('<title>Email One</title>')
|
30
|
-
end
|
31
|
-
|
32
|
-
it "loads corresponding data yaml file" do
|
33
|
-
get '/template/1-demo'
|
34
|
-
expect(last_response.body).to include('foo')
|
35
|
-
expect(last_response.body).to include('bar')
|
36
|
-
end
|
37
|
-
|
38
|
-
it "respects layout:false metadata attribute" do
|
39
|
-
get '/template/2-no-layout'
|
40
|
-
expect(last_response.body).not_to include('<body>')
|
41
|
-
end
|
42
|
-
|
43
|
-
it "has default title if none found" do
|
44
|
-
get 'template/3-no-title'
|
45
|
-
expect(last_response.body).to include('Untitled')
|
46
|
-
end
|
47
|
-
|
48
|
-
it "shows 404 error if template not found" do
|
49
|
-
get '/template/does-not-exist'
|
50
|
-
expect(last_response.status).to eq(404)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
2.2.2
|