hamloft 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 340c780cf3c659da0a4bc337e0d8e1f927672894
4
+ data.tar.gz: b67da693288f6ae9fdc476b2959b1ad0a1764bf1
5
+ SHA512:
6
+ metadata.gz: 219b9c327b92c46644ef97c7d034fb35145205c860bc60457b6634ca66ac6c75c556253b9097b07b7572e4dd3ccfa37e8cb3c4fbe97fe683b4e1631bb13a1f67
7
+ data.tar.gz: 8427c325e5f5d3a61c3bbf9109f4f6ab7d1529af17064e7a5b10016d25b3f94d09d29c1f06f5b6cd1dd65a05cda62718b79edec530a268a21a511c69738b2d24
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .DS_Store
2
+ /hamlet-*.gem
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format d
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,77 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ hamloft (0.1.0)
5
+ activesupport (= 4.2.3)
6
+ bundler (= 1.10.5)
7
+ haml (= 4.0.6)
8
+ nokogiri (= 1.6.3.1)
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ activesupport (4.2.3)
14
+ i18n (~> 0.7)
15
+ json (~> 1.7, >= 1.7.7)
16
+ minitest (~> 5.1)
17
+ thread_safe (~> 0.3, >= 0.3.4)
18
+ tzinfo (~> 1.1)
19
+ ast (2.0.0)
20
+ astrolabe (1.3.1)
21
+ parser (~> 2.2)
22
+ coderay (1.1.0)
23
+ diff-lcs (1.2.5)
24
+ haml (4.0.6)
25
+ tilt
26
+ i18n (0.7.0)
27
+ json (1.8.3)
28
+ method_source (0.8.2)
29
+ mini_portile (0.6.0)
30
+ minitest (5.7.0)
31
+ nokogiri (1.6.3.1)
32
+ mini_portile (= 0.6.0)
33
+ parser (2.2.2.6)
34
+ ast (>= 1.1, < 3.0)
35
+ powerpack (0.1.1)
36
+ pry (0.10.1)
37
+ coderay (~> 1.1.0)
38
+ method_source (~> 0.8.1)
39
+ slop (~> 3.4)
40
+ rainbow (2.0.0)
41
+ rspec (3.3.0)
42
+ rspec-core (~> 3.3.0)
43
+ rspec-expectations (~> 3.3.0)
44
+ rspec-mocks (~> 3.3.0)
45
+ rspec-core (3.3.2)
46
+ rspec-support (~> 3.3.0)
47
+ rspec-expectations (3.3.1)
48
+ diff-lcs (>= 1.2.0, < 2.0)
49
+ rspec-support (~> 3.3.0)
50
+ rspec-mocks (3.3.2)
51
+ diff-lcs (>= 1.2.0, < 2.0)
52
+ rspec-support (~> 3.3.0)
53
+ rspec-support (3.3.0)
54
+ rubocop (0.32.1)
55
+ astrolabe (~> 1.3)
56
+ parser (>= 2.2.2.5, < 3.0)
57
+ powerpack (~> 0.1)
58
+ rainbow (>= 1.99.1, < 3.0)
59
+ ruby-progressbar (~> 1.4)
60
+ ruby-progressbar (1.7.5)
61
+ slop (3.6.0)
62
+ thread_safe (0.3.5)
63
+ tilt (1.4.1)
64
+ tzinfo (1.2.2)
65
+ thread_safe (~> 0.1)
66
+
67
+ PLATFORMS
68
+ ruby
69
+
70
+ DEPENDENCIES
71
+ hamloft!
72
+ pry (= 0.10.1)
73
+ rspec (= 3.3.0)
74
+ rubocop (= 0.32.1)
75
+
76
+ BUNDLED WITH
77
+ 1.10.5
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ [Hamloft](http://bitbucket.org/magloft/hamloft/) - MagLoft HAML Template Kit
2
+ ==========================================================================
data/hamloft.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'hamloft/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "hamloft"
7
+ s.version = Hamloft::VERSION
8
+ s.licenses = ["BSD-3-Clause"]
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["Tobias Strebitzer"]
11
+ s.email = ["tobias.strebitzer@magloft.com"]
12
+ s.homepage = "http://www.magloft.com"
13
+ s.summary = "Hamloft - MagLoft Widget Parser."
14
+ s.description = "This gem contains template built parser for creating MagLoft theme templates."
15
+ s.required_rubygems_version = '>= 2.4.7'
16
+ s.add_runtime_dependency "bundler", "1.10.5"
17
+ s.add_runtime_dependency 'haml', "4.0.6"
18
+ s.add_runtime_dependency "activesupport", "4.2.3"
19
+ s.add_runtime_dependency "nokogiri", "1.6.3.1"
20
+ s.add_development_dependency "rspec", "3.3.0"
21
+ s.add_development_dependency "pry", "0.10.1"
22
+ s.add_development_dependency "rubocop", "0.32.1"
23
+ s.files = `git ls-files`.split("\n")
24
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
25
+ s.require_path = 'lib'
26
+ end
@@ -0,0 +1,36 @@
1
+ module Hamloft
2
+ class Engine < Haml::Engine
3
+
4
+ def render(scope = Object.new, locals = {}, &block)
5
+ parent = scope.instance_variable_defined?('@haml_buffer') ? scope.instance_variable_get('@haml_buffer') : nil
6
+ buffer = Haml::Buffer.new(parent, @options.for_buffer)
7
+
8
+ if scope.is_a?(Binding) || scope.is_a?(Proc)
9
+ scope_object = eval("self", scope)
10
+ scope = scope_object.instance_eval{binding} if block_given?
11
+ else
12
+ scope_object = scope
13
+ scope = scope_object.instance_eval{binding}
14
+ end
15
+
16
+ set_locals(locals.merge(:_hamlout => buffer, :_erbout => buffer.buffer), scope, scope_object)
17
+
18
+ scope_object.instance_eval do
19
+ extend Haml::Helpers
20
+ extend Hamloft::Helpers
21
+ @haml_buffer = buffer
22
+ end
23
+ begin
24
+ eval(@compiler.precompiled_with_return_value, scope, @options[:filename], @options[:line])
25
+ rescue ::SyntaxError => e
26
+ raise SyntaxError, e.message
27
+ end
28
+ ensure
29
+ # Get rid of the current buffer
30
+ scope_object.instance_eval do
31
+ @haml_buffer = buffer.upper if buffer
32
+ end
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,216 @@
1
+ module Hamloft
2
+ module Helpers
3
+
4
+ def style_string(options, *args, &block)
5
+ Hamloft::StyleBuilder.new(options, args).process(block)
6
+ end
7
+
8
+ # styles
9
+ def asset(url)
10
+ "#{Hamloft::Options.defaults[:asset_uri]}/themes/#{@_haml_locals[:theme]}/#{url}"
11
+ end
12
+
13
+ def variable(key, default=false)
14
+ @_haml_locals[key.to_sym] || default
15
+ end
16
+
17
+ def parse_html(key, type)
18
+ if html = @_haml_locals[key.to_sym] and not Hamloft.template(type).nil?
19
+ template = Hamloft.template(type).new(self, html)
20
+ template.container do
21
+ template.chunks.each do |chunk|
22
+ template.process_chunk(chunk)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def link(href, referrer="Baker", &block)
29
+ if referrer and not referrer.empty? and not href.include?("referrer=")
30
+ href = "#{href}#{href.include?("?") ? "&" : "?"}referrer=#{referrer}"
31
+ end
32
+ haml_tag :a, :href => href do
33
+ block.call if block
34
+ end
35
+ end
36
+ # <a href="http://www.google.com/?referrer=Baker" class="">
37
+
38
+ def font(font_face, &block)
39
+ haml_tag :font, :face => font_face do
40
+ block.call if block
41
+ end
42
+ end
43
+
44
+ def style(*args, &block)
45
+ style = nil
46
+ if args[-1].class.name == "Hash"
47
+ style_options = args.pop
48
+ style = style_string(style_options, *style_options.keys)
49
+ end
50
+
51
+ classes = args.map{|a| "__#{a}"}
52
+ haml_tag :span, :class => classes.join(" "), :style => style do
53
+ block.call if block
54
+ end
55
+ end
56
+
57
+ # drop container
58
+
59
+ def drop_container
60
+ haml_tag :div, :class => "_typeloft_widget_drop_container"
61
+ end
62
+
63
+ # widgets
64
+
65
+ def widget_block(widget, &block)
66
+ haml_tag :div, widget.typeloft_widget_options do
67
+ block.call(widget) if block
68
+ end
69
+ end
70
+
71
+ def column(row, &block)
72
+ # get and increase span
73
+ next_span = row.next_span
74
+ if next_span
75
+ haml_tag :div, :class => "column col-12 col-tablet-#{next_span} col-#{row.options[:collapse_options]}-#{next_span}" do
76
+ block.call if block
77
+ drop_container
78
+ end
79
+ else
80
+ haml_tag :pre do
81
+ haml_concat "ERROR: Row does not allow column at position #{row.column_count}"
82
+ end
83
+ end
84
+ end
85
+
86
+ def columns_widget(options={}, &block)
87
+ widget_block(Widget::Columns.new(options)) do |widget|
88
+ haml_tag :div, widget.row_options do
89
+ block.call(widget) if block
90
+ end
91
+ end
92
+ end
93
+
94
+ def columns_widget_compose(key, options={}, &block)
95
+ columns_widget = Widget::Columns.new(options)
96
+ items = variable(key, [])
97
+ # calculate row and column count
98
+ row_count = (items.length.to_f / columns_widget.total_columns).ceil
99
+ col_count = columns_widget.total_columns
100
+ (0...row_count).each do |row_index|
101
+ columns_widget(options) do |row|
102
+ (0...col_count).each do |col_index|
103
+ index = (row_index * col_count) + col_index
104
+ block.call(row, items[index]) if not items[index].nil?
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ def container_widget(options={}, &block)
111
+ widget_block(Widget::Container.new(options)) do |widget|
112
+ haml_tag :section, widget.container_options do
113
+ haml_tag :div, widget.image_options do
114
+ block.call if block
115
+ drop_container
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ def banner_widget(options={}, &block)
122
+ widget_block(Widget::Banner.new(options)) do |widget|
123
+ haml_tag :div, :class => "banner-outer align-#{widget.options[:alignment]}" do
124
+ haml_tag :div, :class => "banner banner-#{widget.options[:style]}" do
125
+ block.call if block
126
+ drop_container
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ def youtube_widget(options={}, &block)
133
+ widget_block(Widget::Youtube.new(options)) do |widget|
134
+ haml_tag :div, class: "flex-video widescreen", style: style_string(widget.options, :margin, :padding) do
135
+ haml_tag :iframe, src: "http://www.youtube.com/embed/#{widget.options[:youtube_id]}", type: "text/html", style: "max-width: 100%; position: absolute; top: 0px; left: 0px; width: 100%; height: 100%;", allowfullscreen: "", frameborder: "0", webkitallowfullscreen: "", mozallowfullscreen: ""
136
+ end
137
+ end
138
+ end
139
+
140
+ def yahoo_screen_widget(options={}, &block)
141
+ widget_block(Widget::YahooScreen.new(options)) do |widget|
142
+ haml_tag :div, class: "flex-video widescreen", style: style_string(widget.options, :margin, :padding) do
143
+ haml_tag :iframe, src: "http://screen.yahoo.com/#{widget.options[:yahoo_screen_id]}.html?format=embed", type: "text/html", style: "max-width: 100%; position: absolute; top: 0px; left: 0px; width: 100%; height: 100%;", allowfullscreen: "", frameborder: "0", webkitallowfullscreen: "", mozallowfullscreen: ""
144
+ end
145
+ end
146
+ end
147
+
148
+ def image_widget_link(options={})
149
+ widget_block(Widget::Image.new(options)) do |widget|
150
+ haml_tag :div, :class => "image-widget align-#{widget.options[:align]}" do
151
+ link options[:href] do
152
+ haml_tag :img, style: style_string(widget.options, :margin, :padding), class: "image #{widget.options[:style]} #{widget.options[:magnify] ? "magnific-image" : ""}", src: widget.options[:source]
153
+ end
154
+ haml_tag :div, :class => "image-drop-target"
155
+ end
156
+ end
157
+ end
158
+
159
+ def horizontal_rule_widget(options={})
160
+ widget_block(Widget::HorizontalRule.new(options)) do |widget|
161
+ haml_tag :hr, style: "max-height: #{widget.options[:max_height]}", class: "#{widget.options[:style]} #{widget.options[:color]}"
162
+ end
163
+ end
164
+
165
+ def image_widget(options={})
166
+ widget_block(Widget::Image.new(options)) do |widget|
167
+ haml_tag :div, :class => "image-widget align-#{widget.options[:align]}", style: style_string(widget.options, :margin, :padding) do
168
+ haml_tag :img, class: "image #{widget.options[:style]} #{widget.options[:magnify] ? "magnific-image" : ""}", src: widget.options[:source]
169
+ haml_tag :div, class: "image-drop-target"
170
+ end
171
+ end
172
+ end
173
+
174
+ def heading_widget(options={}, contents=nil, &block)
175
+ if options.class.name == "String"
176
+ contents = options
177
+ options = {}
178
+ end
179
+ widget_block(Widget::Heading.new(options)) do |widget|
180
+ haml_tag :header, :class => "#{widget.options[:style]} align-#{widget.options[:align]}", style: style_string(widget.options, :margin, :padding) do
181
+ haml_tag widget.options[:type], :class => "_typeloft_editable _typeloft_widget_autoselect" do
182
+ haml_concat(contents) if contents
183
+ block.call if block
184
+ end
185
+ end
186
+ end
187
+ end
188
+
189
+ def paragraph_widget(options={}, contents=nil, &block)
190
+ if options.class.name == "String"
191
+ contents = options
192
+ options = {}
193
+ end
194
+ widget_block(Widget::Paragraph.new(options)) do |widget|
195
+ haml_tag :div, :style => style = style_string(widget.options, :margin, :padding), :class => "paragraph _typeloft_editable _typeloft_widget_autoselect #{widget.options[:style]} align-#{widget.options[:align]} size-#{widget.options[:size]}" do
196
+ haml_concat(contents) if contents
197
+ block.call if block
198
+ end
199
+ end
200
+ end
201
+
202
+ def button_widget(options={}, contents=nil, &block)
203
+ if options.class.name == "String"
204
+ contents = options
205
+ options = {}
206
+ end
207
+ widget_block(Widget::Button.new(options)) do |widget|
208
+ haml_tag :a, class: "btn btn-#{widget.options[:style]} #{widget.options[:type]} #{widget.options[:size]} _typeloft_editable", href: (widget.options[:href] or "#"), style: style_string(widget.options, :margin, :padding) do
209
+ haml_concat(contents) if contents
210
+ block.call if block
211
+ end
212
+ end
213
+ end
214
+
215
+ end
216
+ end
@@ -0,0 +1,42 @@
1
+ module Hamloft
2
+ class Options
3
+
4
+ @defaults = {
5
+ :asset_uri => "http://localhost:3000"
6
+ }
7
+
8
+ # The default option values.
9
+ # @return Hash
10
+ def self.defaults
11
+ @defaults
12
+ end
13
+
14
+ attr_accessor :asset_uri
15
+
16
+ def initialize(values = {}, &block)
17
+ defaults.each {|k, v| instance_variable_set :"@#{k}", v}
18
+ values.reject {|k, v| !defaults.has_key?(k) || v.nil?}.each {|k, v| send("#{k}=", v)}
19
+ yield if block_given?
20
+ end
21
+
22
+ # Retrieve an option value.
23
+ # @param key The value to retrieve.
24
+ def [](key)
25
+ send key
26
+ end
27
+
28
+ # Set an option value.
29
+ # @param key The key to set.
30
+ # @param value The value to set for the key.
31
+ def []=(key, value)
32
+ send "#{key}=", value
33
+ end
34
+
35
+ private
36
+
37
+ def defaults
38
+ self.class.defaults
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,66 @@
1
+ module Hamloft
2
+ class StyleBuilder
3
+ attr_accessor :options
4
+ attr_accessor :styles
5
+
6
+ def initialize(options, styles=[])
7
+ @options = {}
8
+ @styles = {}
9
+
10
+ # expand margins
11
+ if styles.include?(:margin)
12
+ styles = styles | [:margin_top, :margin_right, :margin_bottom, :margin_left]
13
+ styles.reject! {|style| styles === :margin}
14
+ end
15
+
16
+ # expand paddings
17
+ if styles.include?(:padding)
18
+ styles = styles | [:padding_top, :padding_right, :padding_bottom, :padding_left]
19
+ styles.reject! {|style| styles === :padding}
20
+ end
21
+
22
+ # build sanitized options
23
+ options.each do |k, v|
24
+ @options[sanitize_style(k)] = v
25
+ end
26
+
27
+ # add initial styles
28
+ add_multi(styles)
29
+ end
30
+
31
+ def process(block=nil)
32
+ block.call(self) if block
33
+ result = @styles.map{|k, v|"#{k}: #{v};"}.join(" ")
34
+ result.empty? ? nil : result
35
+ end
36
+
37
+ def add_multi(styles)
38
+ styles.each do |style|
39
+ add(style)
40
+ end
41
+ end
42
+
43
+ def add(style, value=nil, template=nil)
44
+ style = sanitize_style(style)
45
+
46
+ # handle empty value field
47
+ if (not value or value.empty?) and not (not @options[style] or @options[style].empty?)
48
+ value = @options[style]
49
+ end
50
+
51
+ # apply template
52
+ if value and not value.empty? and template and not template.empty?
53
+ value = ERB.new(template).result(binding)
54
+ end
55
+
56
+ @styles[style] = value if value and not value.empty?
57
+ end
58
+
59
+ def sanitize_style(value)
60
+ value.to_s.gsub(/([A-Z]+)([A-Z][a-z])/,'\1-\2').
61
+ gsub(/([a-z\d])([A-Z])/,'\1-\2').
62
+ tr("_", "-").downcase
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,24 @@
1
+ module Hamloft
2
+ class Template
3
+ attr_accessor :haml, :html, :doc
4
+
5
+ def initialize(haml, html)
6
+ self.haml = haml
7
+ self.html = html
8
+ self.doc = Nokogiri::HTML.fragment(self.html)
9
+ end
10
+
11
+ def chunks
12
+ []
13
+ end
14
+
15
+ def container(&block)
16
+ yield(block)
17
+ end
18
+
19
+ def process_chunk(chunk)
20
+ nil
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ module Hamloft
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,18 @@
1
+ module Hamloft
2
+ module Widget
3
+ class Banner < Base
4
+
5
+ def identifier
6
+ "banner"
7
+ end
8
+
9
+ def defaults
10
+ {
11
+ style: "dark",
12
+ alignment: "center"
13
+ }
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,33 @@
1
+ module Hamloft
2
+ module Widget
3
+ class Base
4
+ include Hamloft::Helpers
5
+ attr_accessor :options
6
+
7
+ def identifier
8
+ "base"
9
+ end
10
+
11
+ def defaults
12
+ {}
13
+ end
14
+
15
+ def initialize(options)
16
+ @options = defaults.merge(options)
17
+ end
18
+
19
+ def typeloft_widget_options
20
+ attributes = {
21
+ :class => "_typeloft_widget",
22
+ :"data-widget-identifier" => identifier
23
+ }
24
+ @options.each do |k, v|
25
+ attributes["data-attribute-#{k}"] = v
26
+ end
27
+ attributes
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ module Hamloft
2
+ module Widget
3
+ class Button < Base
4
+
5
+ def identifier
6
+ "button"
7
+ end
8
+
9
+ def defaults
10
+ {
11
+ style: "primary",
12
+ type: "btn-fit",
13
+ size: "btn-lg"
14
+ }
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,49 @@
1
+ module Hamloft
2
+ module Widget
3
+ class Columns < Base
4
+ attr_reader :columns
5
+ attr_reader :column_count
6
+ attr_reader :total_columns
7
+
8
+ def initialize(options)
9
+ super(options)
10
+ @column_count = 0
11
+ column_array = @options[:columns].to_s.split("x")
12
+ if column_array.length == 1
13
+ @total_columns = column_array[0].to_i
14
+ @columns = Array.new(@total_columns) { 12 / @total_columns }
15
+ else
16
+ @total_columns = column_array.length
17
+ @columns = column_array
18
+ end
19
+ end
20
+
21
+ def next_span
22
+ value = @columns[@column_count]
23
+ @column_count = @column_count + 1
24
+ value
25
+ end
26
+
27
+ def row_options
28
+ {
29
+ class: "row row-#{@options[:style]}",
30
+ style: style_string(@options, :margin_bottom)
31
+ }
32
+ end
33
+
34
+ def identifier
35
+ "columns"
36
+ end
37
+
38
+ def defaults
39
+ {
40
+ columns: "2",
41
+ style: "default",
42
+ margin_bottom: "",
43
+ collapse_options: "sm"
44
+ }
45
+ end
46
+
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,73 @@
1
+ module Hamloft
2
+ module Widget
3
+ class Container < Base
4
+
5
+ def identifier
6
+ "container"
7
+ end
8
+
9
+ def defaults
10
+ {
11
+ animate: "none",
12
+ image_source: false,
13
+ image_position: "center_center",
14
+ image_size: "cover",
15
+ parallax_effect: "none",
16
+ background_color: "",
17
+ bg_color: "",
18
+ opacity: "",
19
+ border_radius: "0px",
20
+ border_width: "0px",
21
+ border_style: "none",
22
+ style: "default",
23
+ padding_top: "0em",
24
+ padding_right: "",
25
+ padding_bottom: "0em",
26
+ padding_left: "",
27
+ min_height: "",
28
+ max_height: "",
29
+ margin_top: "",
30
+ margin_right: "",
31
+ margin_bottom: "",
32
+ margin_left: ""
33
+ }
34
+ end
35
+
36
+ def container_options
37
+ result = {class: container_classes, style: container_styles}
38
+ result["data-parallax-style"] = @options[:parallax_effect] if not @options[:parallax_effect].empty? and @options[:parallax_effect] != "none"
39
+ result
40
+ end
41
+
42
+ def image_options
43
+ {class: "one-container-image", style: image_styles}
44
+ end
45
+
46
+ def container_classes
47
+ classes = ["one-container"]
48
+ classes.push("animate #{@options[:animate]}") if @options[:animate] != "none"
49
+ classes.push("container-#{@options[:style]}") if not @options[:style].empty?
50
+ classes.push("container-image-#{@options[:image_size]}") if not @options[:image_size].empty?
51
+ classes.push("container-parallax") if not @options[:parallax_effect].empty? and @options[:parallax_effect] != "none"
52
+ classes.join(" ")
53
+ end
54
+
55
+ def container_styles
56
+ style_string @options, :opacity, :border, :opacity, :border_radius, :border_width, :border_style, :margin do |sb|
57
+ sb.add(:background_color, @options[:background_color] == "custom" ? @options[:bg_color] : nil)
58
+ if @options[:background_color] == "overlay"
59
+ sb.add(:background_image, @options[:image_source], "linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url(<%= value %>)")
60
+ else
61
+ sb.add(:background_image, @options[:image_source], "url(<%= value %>)")
62
+ end
63
+ sb.add(:background_position, @options[:image_position], "<%= value.split('_').join(' ') %>")
64
+ end
65
+ end
66
+
67
+ def image_styles
68
+ style_string @options, :min_height, :max_height, :padding
69
+ end
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,19 @@
1
+ module Hamloft
2
+ module Widget
3
+ class Heading < Base
4
+
5
+ def identifier
6
+ "heading"
7
+ end
8
+
9
+ def defaults
10
+ {
11
+ type: "h1",
12
+ style: "default",
13
+ align: "left"
14
+ }
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module Hamloft
2
+ module Widget
3
+ class HorizontalRule < Base
4
+
5
+ def identifier
6
+ "horizontal_rule"
7
+ end
8
+
9
+ def defaults
10
+ {
11
+ style: 'solid',
12
+ color: 'dark',
13
+ max_height: 'inherit'
14
+ }
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ module Hamloft
2
+ module Widget
3
+ class Image < Base
4
+
5
+ def identifier
6
+ "image"
7
+ end
8
+
9
+ def defaults
10
+ {
11
+ style: "img-responsive",
12
+ align: "center",
13
+ source: false,
14
+ magnify: false,
15
+ margin_bottom: "0"
16
+ }
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ module Hamloft
2
+ module Widget
3
+ class Paragraph < Base
4
+
5
+ def identifier
6
+ "paragraph"
7
+ end
8
+
9
+ def defaults
10
+ {
11
+ style: "default",
12
+ align: "left",
13
+ size: "md",
14
+ margin_bottom: ""
15
+ }
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ module Hamloft
2
+ module Widget
3
+ class YahooScreen < Base
4
+
5
+ def identifier
6
+ "yahoo_screen"
7
+ end
8
+
9
+ def defaults
10
+ {
11
+ yahoo_screen_id: "apple-iwatch-iphone-6-135616256",
12
+ width: "800",
13
+ height: "600"
14
+ }
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module Hamloft
2
+ module Widget
3
+ class Youtube < Base
4
+
5
+ def identifier
6
+ "youtube"
7
+ end
8
+
9
+ def defaults
10
+ {
11
+ youtube_id: "LFYNP40vfmE",
12
+ width: "800",
13
+ height: "600"
14
+ }
15
+ end
16
+
17
+ end
18
+ end
19
+ end
data/lib/hamloft.rb ADDED
@@ -0,0 +1,36 @@
1
+ require "haml"
2
+ require "erb"
3
+ require "nokogiri"
4
+ require "hamloft/engine"
5
+ require "hamloft/options"
6
+ require "hamloft/style_builder"
7
+ require "hamloft/helpers"
8
+ require "hamloft/template"
9
+ require "hamloft/widget/base"
10
+ require "hamloft/widget/container"
11
+ require "hamloft/widget/columns"
12
+ require "hamloft/widget/image"
13
+ require "hamloft/widget/heading"
14
+ require "hamloft/widget/button"
15
+ require "hamloft/widget/paragraph"
16
+ require "hamloft/widget/banner"
17
+ require "hamloft/widget/youtube"
18
+ require "hamloft/widget/yahoo_screen"
19
+ require "hamloft/widget/horizontal_rule"
20
+
21
+ module Hamloft
22
+ @@_templates = {}
23
+
24
+ def self.render(haml, variables={})
25
+ Hamloft::Engine.new(haml, remove_whitespace: true).render(Object.new, variables)
26
+ end
27
+
28
+ def self.register_template(key, template)
29
+ @@_templates[key] = template
30
+ end
31
+
32
+ def self.template(key)
33
+ @@_templates[key]
34
+ end
35
+
36
+ end
@@ -0,0 +1,65 @@
1
+ class TumblrTemplate < Hamloft::Template
2
+
3
+ def chunks
4
+ self.doc.children
5
+ end
6
+
7
+ def container(&block)
8
+ haml.container_widget(padding_left: "0em", padding_right: "0em", &block)
9
+ end
10
+
11
+ def process_chunk(chunk)
12
+ case chunk.name
13
+ when "text"
14
+ haml.paragraph_widget({margin_left: "2em", margin_right: "2em"}, chunk.text)
15
+ when "p"
16
+ haml.paragraph_widget({margin_left: "2em", margin_right: "2em"}, chunk.text)
17
+ when "a"
18
+ if chunk.css("img").length > 0
19
+ haml.image_widget_link(href: chunk.attribute("href").to_s, source: chunk.css("img").first.attribute("src").to_s)
20
+ else
21
+ haml.paragraph_widget({margin_left: "2em", margin_right: "2em"}, chunk.text) do
22
+ haml.link(chunk.attribute("href").to_s)
23
+ end
24
+ end
25
+ when "figure"
26
+ case chunk.children.first.name
27
+ when "img"
28
+ haml.image_widget(source: chunk.children.first.attribute("src").to_s, margin_bottom: "1em")
29
+ when "iframe"
30
+ iframe_url = chunk.children.first.attribute("src").value
31
+ if iframe_url.include?("screen.yahoo.com") and match = iframe_url.match("screen\.yahoo\.com\/([a-z0-9\-]+)\.html")
32
+ haml.yahoo_screen_widget(yahoo_screen_id: match[1], margin_bottom: "1em")
33
+ elsif iframe_url.include?("www.youtube.com") and match = iframe_url.match("www\.youtube\.com\/.*\/([a-zA-Z0-9]+)")
34
+ haml.youtube_widget(youtube_id: match[1], margin_bottom: "1em")
35
+ else
36
+ puts "-- unhandled iframe: #{iframe_url}"
37
+ end
38
+ else
39
+ puts "-- unhandled figure: #{chunk.children.first.name}"
40
+ end
41
+ when "div"
42
+ if chunk.attribute("class").to_s == "sponlogo"
43
+ haml.container_widget background_color: "white", padding_left: "1em", padding_right: "1em", padding_bottom: "0.5em", padding_top: "1em" do
44
+ haml.columns_widget columns: "3x9" do |row|
45
+ haml.column row do
46
+ process_chunk(chunk.children()[0])
47
+ end
48
+ haml.column row do
49
+ haml.paragraph_widget({align: "right"}, chunk.children()[1].text)
50
+ end
51
+ end
52
+ end
53
+ else
54
+ haml.container_widget do
55
+ chunk.children.each do |child_chunk|
56
+ process_chunk(child_chunk)
57
+ end
58
+ end
59
+ end
60
+ else
61
+ puts "-- unhandled chunk: #{chunk.name}"
62
+ end
63
+ end
64
+
65
+ end
@@ -0,0 +1,41 @@
1
+ -# ROOT DROP CONTAINER
2
+ - drop_container
3
+
4
+ -# ROOT CONTAINER
5
+ - container_widget min_height: "calc(100vh - 92px)", parallax_effect: "fixed", image_source: variable(:background_url, asset("images/bg/pastel-01.jpg")), image_size: "cover", background_color: "overlay", image_position: "top center" do
6
+
7
+ -# TOP PAGE CONTAINER
8
+ - container_widget min_height: "calc(100vh - 92px)" do
9
+
10
+ -# FIXED CONTAINER
11
+ - container_widget animate: "fade-in-down scroll-animate", style: "fixed", padding_top: "30vh", padding_left: "10vw", padding_right: "10vw" do
12
+
13
+ -# MAIN HEADING
14
+ - heading_widget align: "left", style: "feature" do
15
+ - style :bold, color: "#FFFFFF" do
16
+ = variable(:title, "WHY I DESIGN?")
17
+
18
+ - horizontal_rule_widget style: "flourish-01", color: "light"
19
+
20
+ -# CENTER CONTAINER
21
+ - container_widget style: "thin", background_color: "custom", bg_color: "rgba(255, 255, 255, 0.95)", padding_top: "1em", margin_bottom: "6em", animate: "fade-in-up" do
22
+
23
+ - container_widget padding_left: "1em", padding_right: "1em" do
24
+
25
+ - button_widget style: "success", href: "#scroll-next" do
26
+ - style :bold, color: "#FFFFFF" do
27
+ BEGIN
28
+
29
+ -# HEADER CONTAINER
30
+ - container_widget parallax_effect: "up", image_source: variable(:image_url, asset("images/base/bg/stripes.jpg")), margin_left: "1em", margin_right: "1em", margin_top: "1em", padding_top: "2em", padding_bottom: "2em", padding_left: "2em", padding_right: "2em" do
31
+ - heading_widget type: "h2", align: "center", style: "feature" do
32
+ - style :bold, color: "#FFFFFF" do
33
+ = variable(:title, "WHY I DESIGN?")
34
+
35
+ -# BODY CONTAINER
36
+ - container_widget padding_top: "2em", padding_left: "0em", padding_right: "0em" do
37
+ - parse_html(:html, :tumblr)
38
+
39
+ - button_widget style: "success", href: "#scroll-top" do
40
+ - style :bold, color: "#FFFFFF" do
41
+ BACK
@@ -0,0 +1,16 @@
1
+ require 'hamloft'
2
+ RSpec.describe Hamloft do
3
+
4
+ it "renders a custom hamloft template" do
5
+
6
+ require_relative "fixtures/template/tumblr.rb"
7
+ Hamloft.register_template(:tumblr, TumblrTemplate)
8
+
9
+ haml = File.read("spec/fixtures/test.haml")
10
+ results = Hamloft.render(haml, {
11
+ html: "<p>foo</p><p>bar</p>"
12
+ })
13
+ expect(results).to be_kind_of String
14
+ end
15
+
16
+ end
@@ -0,0 +1,97 @@
1
+ # require "pry"
2
+ # This file was generated by the `rspec --init` command. Conventionally, all
3
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
4
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
5
+ # this file to always be loaded, without a need to explicitly require it in any
6
+ # files.
7
+ #
8
+ # Given that it is always loaded, you are encouraged to keep this file as
9
+ # light-weight as possible. Requiring heavyweight dependencies from this file
10
+ # will add to the boot time of your test suite on EVERY test run, even for an
11
+ # individual file that may not need all of that loaded. Instead, consider making
12
+ # a separate helper file that requires the additional dependencies and performs
13
+ # the additional setup, and require it from the spec files that actually need
14
+ # it.
15
+ #
16
+ # The `.rspec` file also contains a few flags that are not defaults but that
17
+ # users commonly want.
18
+ #
19
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
20
+ RSpec.configure do |config|
21
+ # rspec-expectations config goes here. You can use an alternate
22
+ # assertion/expectation library such as wrong or the stdlib/minitest
23
+ # assertions if you prefer.
24
+ config.expect_with :rspec do |expectations|
25
+ # This option will default to `true` in RSpec 4. It makes the `description`
26
+ # and `failure_message` of custom matchers include text for helper methods
27
+ # defined using `chain`, e.g.:
28
+ # be_bigger_than(2).and_smaller_than(4).description
29
+ # # => "be bigger than 2 and smaller than 4"
30
+ # ...rather than:
31
+ # # => "be bigger than 2"
32
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
33
+ end
34
+
35
+ # rspec-mocks config goes here. You can use an alternate test double
36
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
37
+ config.mock_with :rspec do |mocks|
38
+ # Prevents you from mocking or stubbing a method that does not exist on
39
+ # a real object. This is generally recommended, and will default to
40
+ # `true` in RSpec 4.
41
+ mocks.verify_partial_doubles = true
42
+ end
43
+
44
+ # The settings below are suggested to provide a good initial experience
45
+ # with RSpec, but feel free to customize to your heart's content.
46
+ =begin
47
+ # These two settings work together to allow you to limit a spec run
48
+ # to individual examples or groups you care about by tagging them with
49
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
50
+ # get run.
51
+ config.filter_run :focus
52
+ config.run_all_when_everything_filtered = true
53
+
54
+ # Allows RSpec to persist some state between runs in order to support
55
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
56
+ # you configure your source control system to ignore this file.
57
+ config.example_status_persistence_file_path = "spec/examples.txt"
58
+
59
+ # Limits the available syntax to the non-monkey patched syntax that is
60
+ # recommended. For more details, see:
61
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
62
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
63
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
64
+ config.disable_monkey_patching!
65
+
66
+ # This setting enables warnings. It's recommended, but in some cases may
67
+ # be too noisy due to issues in dependencies.
68
+ config.warnings = true
69
+
70
+ # Many RSpec users commonly either run the entire suite or an individual
71
+ # file, and it's useful to allow more verbose output when running an
72
+ # individual spec file.
73
+ if config.files_to_run.one?
74
+ # Use the documentation formatter for detailed output,
75
+ # unless a formatter has already been configured
76
+ # (e.g. via a command-line flag).
77
+ config.default_formatter = 'doc'
78
+ end
79
+
80
+ # Print the 10 slowest examples and example groups at the
81
+ # end of the spec run, to help surface which specs are running
82
+ # particularly slow.
83
+ config.profile_examples = 10
84
+
85
+ # Run specs in random order to surface order dependencies. If you find an
86
+ # order dependency and want to debug it, you can fix the order by providing
87
+ # the seed, which is printed after each run.
88
+ # --seed 1234
89
+ config.order = :random
90
+
91
+ # Seed global randomization in this process using the `--seed` CLI option.
92
+ # Setting this allows you to use `--seed` to deterministically reproduce
93
+ # test failures related to randomization by passing the same `--seed` value
94
+ # as the one that triggered the failure.
95
+ Kernel.srand config.seed
96
+ =end
97
+ end
metadata ADDED
@@ -0,0 +1,171 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hamloft
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Tobias Strebitzer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-06 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.10.5
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.10.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: haml
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 4.0.6
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 4.0.6
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 4.2.3
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 4.2.3
55
+ - !ruby/object:Gem::Dependency
56
+ name: nokogiri
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 1.6.3.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 1.6.3.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '='
74
+ - !ruby/object:Gem::Version
75
+ version: 3.3.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '='
81
+ - !ruby/object:Gem::Version
82
+ version: 3.3.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '='
88
+ - !ruby/object:Gem::Version
89
+ version: 0.10.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '='
95
+ - !ruby/object:Gem::Version
96
+ version: 0.10.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '='
102
+ - !ruby/object:Gem::Version
103
+ version: 0.32.1
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '='
109
+ - !ruby/object:Gem::Version
110
+ version: 0.32.1
111
+ description: This gem contains template built parser for creating MagLoft theme templates.
112
+ email:
113
+ - tobias.strebitzer@magloft.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - .gitignore
119
+ - .rspec
120
+ - Gemfile
121
+ - Gemfile.lock
122
+ - README.md
123
+ - hamloft.gemspec
124
+ - lib/hamloft.rb
125
+ - lib/hamloft/engine.rb
126
+ - lib/hamloft/helpers.rb
127
+ - lib/hamloft/options.rb
128
+ - lib/hamloft/style_builder.rb
129
+ - lib/hamloft/template.rb
130
+ - lib/hamloft/version.rb
131
+ - lib/hamloft/widget/banner.rb
132
+ - lib/hamloft/widget/base.rb
133
+ - lib/hamloft/widget/button.rb
134
+ - lib/hamloft/widget/columns.rb
135
+ - lib/hamloft/widget/container.rb
136
+ - lib/hamloft/widget/heading.rb
137
+ - lib/hamloft/widget/horizontal_rule.rb
138
+ - lib/hamloft/widget/image.rb
139
+ - lib/hamloft/widget/paragraph.rb
140
+ - lib/hamloft/widget/yahoo_screen.rb
141
+ - lib/hamloft/widget/youtube.rb
142
+ - spec/fixtures/template/tumblr.rb
143
+ - spec/fixtures/test.haml
144
+ - spec/hamloft_spec.rb
145
+ - spec/spec_helper.rb
146
+ homepage: http://www.magloft.com
147
+ licenses:
148
+ - BSD-3-Clause
149
+ metadata: {}
150
+ post_install_message:
151
+ rdoc_options: []
152
+ require_paths:
153
+ - lib
154
+ required_ruby_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - '>='
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ required_rubygems_version: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - '>='
162
+ - !ruby/object:Gem::Version
163
+ version: 2.4.7
164
+ requirements: []
165
+ rubyforge_project:
166
+ rubygems_version: 2.4.7
167
+ signing_key:
168
+ specification_version: 4
169
+ summary: Hamloft - MagLoft Widget Parser.
170
+ test_files: []
171
+ has_rdoc: