ruhl 0.9.3 → 0.9.4

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.3
1
+ 0.9.4
@@ -0,0 +1,205 @@
1
+ module Ruhl
2
+ class Engine
3
+ attr_reader :document, :scope, :layout, :layout_source,
4
+ :local_object, :block_object
5
+
6
+ def initialize(html, options = {})
7
+ @local_object = options[:local_object] || options[:object]
8
+ @block_object = options[:block_object]
9
+ @layout_source = options[:layout_source]
10
+
11
+ if @layout = options[:layout]
12
+ raise LayoutNotFoundError.new(@layout) unless File.exists?(@layout)
13
+ end
14
+
15
+ if @layout || @local_object || @block_object
16
+ @document = Nokogiri::HTML.fragment(html)
17
+ else
18
+ @document = Nokogiri::HTML(html)
19
+ end
20
+ end
21
+
22
+ def render(current_scope)
23
+ set_scope(current_scope)
24
+
25
+ parse_doc(document)
26
+
27
+ if @layout
28
+ render_with_layout
29
+ else
30
+ document.to_s
31
+ end
32
+ end
33
+
34
+ # The _render_ method is used within a layout to inject
35
+ # the results of the template render.
36
+ #
37
+ # Ruhl::Engine.new(html, :layout => path_to_layout).render(self)
38
+ def _render_
39
+ document.to_s
40
+ end
41
+
42
+ private
43
+
44
+ def render_with_layout
45
+ render_file( @layout_source || File.read(@layout) )
46
+ end
47
+
48
+ def render_partial(tag, code)
49
+ file = execute_ruby(tag, code)
50
+ raise PartialNotFoundError.new(file) unless File.exists?(file)
51
+
52
+ render_file( File.read(file) )
53
+ end
54
+
55
+ def render_collection(tag, code, actions = nil)
56
+ results = execute_ruby(tag, code)
57
+
58
+ actions = actions.to_s.strip
59
+
60
+ tag['data-ruhl'] = actions if actions.length > 0
61
+ html = tag.to_html
62
+
63
+ new_content = results.collect do |item|
64
+ # Call to_s on the item only if there are no other actions
65
+ # and there are no other nested data-ruhls
66
+ if actions.length == 0 && tag.xpath('.//*[@data-ruhl]').length == 0
67
+ tag.inner_html = item.to_s
68
+ tag.to_html
69
+ else
70
+ Ruhl::Engine.new(html, :local_object => item).render(scope)
71
+ end
72
+ end.to_s
73
+
74
+ tag.swap(new_content)
75
+ end
76
+
77
+ def render_block(tag, code)
78
+ bo = execute_ruby(tag, code)
79
+ Ruhl::Engine.new(tag.inner_html, :block_object => bo).render(scope)
80
+ end
81
+
82
+ def render_file(contents)
83
+ doc = Nokogiri::HTML( contents )
84
+ parse_doc(doc)
85
+ doc.to_s
86
+ end
87
+
88
+ def parse_doc(doc)
89
+ if (nodes = doc.xpath('*[@data-ruhl][1]')).empty?
90
+ nodes = doc.search('*[@data-ruhl]')
91
+ end
92
+
93
+ return if nodes.empty?
94
+
95
+ tag = nodes.first
96
+ code = tag.remove_attribute('data-ruhl')
97
+ process_attribute(tag, code.value)
98
+
99
+ parse_doc(doc)
100
+ end
101
+
102
+ def process_attribute(tag, code)
103
+ actions = code.split(',')
104
+ actions.dup.each_with_index do |pair, ndx|
105
+ attribute, value = pair.split(':')
106
+
107
+ attribute.strip!
108
+
109
+ if value.nil?
110
+ results = execute_ruby(tag, attribute)
111
+ process_results(tag, results)
112
+ else
113
+ value.strip!
114
+
115
+ unless attribute =~ /^_/
116
+ tag[attribute] = execute_ruby(tag, value)
117
+ else
118
+ case attribute
119
+ when "_use"
120
+ tag.inner_html = render_block(tag, value)
121
+ when "_partial"
122
+ tag.inner_html = render_partial(tag, value)
123
+ when "_collection"
124
+ actions.delete_at(ndx)
125
+ render_collection(tag, value, actions.join(','))
126
+ return
127
+ when "_if"
128
+ return unless process_if(tag, value)
129
+ when "_unless"
130
+ return if process_unless(tag, value)
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
136
+
137
+ def process_if(tag, value)
138
+ contents = execute_ruby(tag, value)
139
+ if contents
140
+ process_results(tag, contents) unless contents == true
141
+ true
142
+ else
143
+ tag.remove
144
+ false
145
+ end
146
+ end
147
+
148
+ def process_unless(tag, value)
149
+ contents = execute_ruby(tag, value)
150
+ if contents
151
+ tag.remove
152
+ true
153
+ else
154
+ false
155
+ end
156
+ end
157
+
158
+ def process_results(tag, results)
159
+ if results.is_a?(Hash)
160
+ results.each do |key, value|
161
+ if key == :inner_html
162
+ tag.inner_html = value
163
+ else
164
+ tag[key.to_s] = value
165
+ end
166
+ end
167
+ else
168
+ tag.inner_html = results.to_s
169
+ end
170
+ end
171
+
172
+ def execute_ruby(tag, code)
173
+ unless code == '_render_'
174
+ if local_object && local_object.respond_to?(code)
175
+ local_object.send(code)
176
+ elsif block_object && block_object.respond_to?(code)
177
+ block_object.send(code)
178
+ else
179
+ scope.send(code)
180
+ end
181
+ else
182
+ _render_
183
+ end
184
+ rescue NoMethodError => e
185
+ log_context(tag,code)
186
+ raise e
187
+ end
188
+
189
+ def set_scope(current_scope)
190
+ raise Ruhl::NoScopeError unless current_scope
191
+ @scope = current_scope
192
+ end
193
+
194
+ def log_context(tag,code)
195
+ Ruhl.logger.error <<CONTEXT
196
+ Context:
197
+ tag : #{tag.inspect}
198
+ code : #{code.inspect}
199
+ local_object : #{local_object.inspect}
200
+ block_object : #{block_object.inspect}
201
+ scope : #{scope.class}
202
+ CONTEXT
203
+ end
204
+ end # Engine
205
+ end # Ruhl
data/lib/ruhl/rails.rb CHANGED
@@ -13,6 +13,7 @@ module Ruhl
13
13
  options[:layout] = layout.filename
14
14
  options[:layout_source] = layout.source
15
15
 
16
+ Rails.logger.info("calling ruhl. template: #{template.inspect}\n options: #{options.inspect}")
16
17
  Ruhl::Engine.new(template.source, options).render(@action_view)
17
18
  end
18
19
  end
data/lib/ruhl.rb CHANGED
@@ -1,207 +1,15 @@
1
1
  $:.unshift File.dirname(__FILE__)
2
2
 
3
3
  require 'nokogiri'
4
+ require 'logger'
5
+ require 'ruhl/engine'
4
6
  require 'ruhl/errors'
5
7
 
6
8
  module Ruhl
7
- class Engine
8
- attr_reader :document, :scope, :layout, :layout_source,
9
- :local_object, :block_object
10
-
11
- def initialize(html, options = {})
12
- @local_object = options[:local_object]
13
- @block_object = options[:block_object]
14
- @layout_source = options[:layout_source]
15
-
16
- if @layout = options[:layout]
17
- raise LayoutNotFoundError.new(@layout) unless File.exists?(@layout)
18
- end
19
-
20
- if @layout || @local_object || @block_object
21
- @document = Nokogiri::HTML.fragment(html)
22
- else
23
- @document = Nokogiri::HTML(html)
24
- end
25
- end
26
-
27
- def render(current_scope)
28
- set_scope(current_scope)
29
-
30
- parse_doc(document)
31
-
32
- if @layout
33
- render_with_layout
34
- else
35
- document.to_s
36
- end
37
- end
38
-
39
- # The _render_ method is used within a layout to inject
40
- # the results of the template render.
41
- #
42
- # Ruhl::Engine.new(html, :layout => path_to_layout).render(self)
43
- def _render_
44
- document.to_s
45
- end
46
-
47
- private
48
-
49
- def render_with_layout
50
- render_file( @layout_source || File.read(@layout) )
51
- end
52
-
53
- def render_partial(tag, code)
54
- file = execute_ruby(tag, code)
55
- raise PartialNotFoundError.new(file) unless File.exists?(file)
56
-
57
- render_file( File.read(file) )
58
- end
59
-
60
- def render_collection(tag, code, actions = nil)
61
- results = execute_ruby(tag, code)
62
-
63
- actions = actions.to_s.strip
64
-
65
- tag['data-ruhl'] = actions if actions.length > 0
66
- html = tag.to_html
67
-
68
- new_content = results.collect do |item|
69
- # Call to_s on the item only if there are no other actions
70
- # and there are no other nested data-ruhls
71
- if actions.length == 0 && tag.xpath('.//*[@data-ruhl]').length == 0
72
- tag.inner_html = item.to_s
73
- tag.to_html
74
- else
75
- Ruhl::Engine.new(html, :local_object => item).render(scope)
76
- end
77
- end.to_s
78
-
79
- tag.swap(new_content)
80
- end
81
-
82
- def render_block(tag, code)
83
- bo = execute_ruby(tag, code)
84
- Ruhl::Engine.new(tag.inner_html, :block_object => bo).render(scope)
85
- end
86
-
87
- def render_file(contents)
88
- doc = Nokogiri::HTML( contents )
89
- parse_doc(doc)
90
- doc.to_s
91
- end
92
-
93
- def parse_doc(doc)
94
- if (nodes = doc.xpath('*[@data-ruhl][1]')).empty?
95
- nodes = doc.search('*[@data-ruhl]')
96
- end
97
-
98
- return if nodes.empty?
99
-
100
- tag = nodes.first
101
- code = tag.remove_attribute('data-ruhl')
102
- process_attribute(tag, code.value)
103
-
104
- parse_doc(doc)
105
- end
106
-
107
- def process_attribute(tag, code)
108
- actions = code.split(',')
109
- actions.dup.each_with_index do |pair, ndx|
110
- attribute, value = pair.split(':')
111
-
112
- attribute.strip!
113
-
114
- if value.nil?
115
- results = execute_ruby(tag, attribute)
116
- process_results(tag, results)
117
- else
118
- value.strip!
119
-
120
- unless attribute =~ /^_/
121
- tag[attribute] = execute_ruby(tag, value)
122
- else
123
- case attribute
124
- when "_use"
125
- tag.inner_html = render_block(tag, value)
126
- when "_partial"
127
- tag.inner_html = render_partial(tag, value)
128
- when "_collection"
129
- actions.delete_at(ndx)
130
- render_collection(tag, value, actions.join(','))
131
- return
132
- when "_if"
133
- return unless process_if(tag, value)
134
- when "_unless"
135
- return if process_unless(tag, value)
136
- end
137
- end
138
- end
139
- end
140
- end
141
-
142
- def process_if(tag, value)
143
- contents = execute_ruby(tag, value)
144
- if contents
145
- process_results(tag, contents) unless contents == true
146
- true
147
- else
148
- tag.remove
149
- false
150
- end
151
- end
152
-
153
- def process_unless(tag, value)
154
- contents = execute_ruby(tag, value)
155
- if contents
156
- tag.remove
157
- true
158
- else
159
- false
160
- end
161
- end
162
-
163
- def process_results(tag, results)
164
- if results.is_a?(Hash)
165
- results.each do |key, value|
166
- if key == :inner_html
167
- tag.inner_html = value
168
- else
169
- tag[key.to_s] = value
170
- end
171
- end
172
- else
173
- tag.inner_html = results.to_s
174
- end
175
- end
176
-
177
- def execute_ruby(tag, code)
178
- unless code == '_render_'
179
- if local_object && local_object.respond_to?(code)
180
- local_object.send(code)
181
- elsif block_object && block_object.respond_to?(code)
182
- block_object.send(code)
183
- else
184
- scope.send(code)
185
- end
186
- else
187
- _render_
188
- end
189
- rescue NoMethodError => e
190
- puts <<CONTEXT
191
- Context:
192
- tag : #{tag.inspect}
193
- code : #{code.inspect}
194
- local_object : #{local_object.inspect}
195
- block_object : #{block_object.inspect}
196
- scope : #{scope.inspect}
197
- CONTEXT
198
- raise e
199
- end
9
+ class << self
10
+ attr_accessor :logger
11
+ end
200
12
 
201
- def set_scope(current_scope)
202
- raise Ruhl::NoScopeError unless current_scope
203
- @scope = current_scope
204
- end
13
+ self.logger = Logger.new(STDOUT)
205
14
 
206
- end
207
15
  end
data/ruhl.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{ruhl}
8
- s.version = "0.9.3"
8
+ s.version = "0.9.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Andrew Stone"]
12
- s.date = %q{2009-10-16}
12
+ s.date = %q{2009-10-17}
13
13
  s.description = %q{Make your HTML dynamic with the addition of a data-ruhl attribute.}
14
14
  s.email = %q{andy@stonean.com}
15
15
  s.extra_rdoc_files = [
@@ -21,6 +21,7 @@ Gem::Specification.new do |s|
21
21
  "Rakefile",
22
22
  "VERSION",
23
23
  "lib/ruhl.rb",
24
+ "lib/ruhl/engine.rb",
24
25
  "lib/ruhl/errors.rb",
25
26
  "lib/ruhl/rails.rb",
26
27
  "lib/ruhl/sinatra.rb",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruhl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Stone
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-16 00:00:00 -04:00
12
+ date: 2009-10-17 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -46,6 +46,7 @@ files:
46
46
  - Rakefile
47
47
  - VERSION
48
48
  - lib/ruhl.rb
49
+ - lib/ruhl/engine.rb
49
50
  - lib/ruhl/errors.rb
50
51
  - lib/ruhl/rails.rb
51
52
  - lib/ruhl/sinatra.rb