ruhl 0.9.7 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -2,392 +2,7 @@ RuHL (Ruby Hypertext Language)
2
2
 
3
3
  **gem available on gemcutter: http://gemcutter.org/gems/ruhl
4
4
 
5
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6
- :: What? ::
7
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
+ Documentation has been moved to:
8
6
 
9
- RuHL parses HTML (using Nokogiri) and by using a data-ruhl attribute, makes
10
- the contents dynamic!
11
-
12
- Let's say you have the following HTML in a file called ('hello_world.ruhl')
13
-
14
- <html>
15
- <body>
16
- <p data-ruhl="say_hello"/>
17
- </body>
18
- </html>
19
-
20
- And you have the following method available to self:
21
-
22
- def say_hello
23
- "Hello World"
24
- end
25
-
26
- If you call
27
-
28
- RuHL::Engine.new(File.read('hello_world.ruhl')).render(self)
29
-
30
- It will return:
31
-
32
- <html>
33
- <body>
34
- <p>Hello World</p>
35
- </body>
36
- </html>
37
-
38
- Notice that it removes the data-ruhl attribute.
39
-
40
-
41
- You can pass an options hash to RuHL:
42
- RuHL::Engine.new(File.read('hello_world.ruhl'), options).render(self)
43
-
44
- Right now, RuHL knows the following options:
45
-
46
- :layout => This is the file name of the layout
47
-
48
- :layout_source => If the framework (like Rails) has already read the file,
49
- pass the contents through so RuHL doesn't have to reread
50
- the file.
51
-
52
- If you don't pass :layout_source, RuHL must be able to
53
- find/read :layout
54
-
55
- :local_object => If you are rendering a show page for @person, pass the
56
- @person object into RuHL. RuHL will first try to call
57
- the methods against the local_object then try the scope.
58
-
59
- For example:
60
- <li data-ruhl="first_name">
61
-
62
- RuHL will first try @person.first_name.
63
-
64
-
65
-
66
- There are some special methods defined by RuHL (examples follow):
67
-
68
- _render_ - This is used in your layout and lets rule know where to inject
69
- the rendered sub content.
70
-
71
- _partial - Path to a partial file. RuHL must be able to find/read this file.
72
-
73
- _if - If the method returns true, processing will continue.
74
- If the method returns a value other than true, the inner_html
75
- of the tag will be set to that value.
76
- If the method returns false or nil, processing will halt and
77
- the tag will not be included on output.
78
-
79
- _unless - If the method returns true, processing will halt and the tag
80
- will not included on output.
81
- If the method returns false, processing will continue.
82
-
83
- _collection - RuHL expects the method reference to return an array of objects.
84
- RuHL will iteratate over the collection and render the contents
85
- of the tag agains the collection item. (example below)
86
-
87
- _use - The object returned is used within the scope of the tag.
88
-
89
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
90
- :: Rails ::
91
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
92
-
93
- In your config/environment.rb :
94
-
95
- config.gem 'ruhl', :lib => 'ruhl/rails'
96
-
97
- Your filenames should end in .ruhl ('show.html.ruhl')
98
-
99
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
100
- :: Sinatra ::
101
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
102
-
103
- require 'ruhl/sinatra'
104
-
105
- You can then do:
106
-
107
- get '/' do
108
- ruhl(:index, :layout => path_to_layout)
109
- end
110
-
111
- *******************************************************************************
112
- *
113
- * EXAMPLES
114
- *
115
- *******************************************************************************
116
-
117
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
118
- :: Replacing attribute values ::
119
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
120
-
121
- <meta data-ruhl="content: meta_description" content='This is a description template'
122
- id='metaDescription' name='description' />
123
-
124
- content: meta_description is telling the parser to replace attribute 'content'
125
- with results from meta_description method.
126
-
127
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
128
- :: Don't use iterators in views ::
129
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
130
-
131
- <table id="aab">
132
- <tr data-ruhl="_collection: user_list">
133
- <td data-ruhl="name">John Doe</td>
134
- <td data-ruhl="email">john@doe.com</td>
135
- </tr>
136
- </table>
137
-
138
- The above will call the :user_list method and iterate over the results. For each result it will duplicate the tag and it's contents. For the above example this means:
139
-
140
- <tr data-ruhl="_collection: user_list">
141
- <td data-ruhl="name">John Doe</td>
142
- <td data-ruhl="email">john@doe.com</td>
143
- </tr>
144
-
145
- is duplicated for each user in user_list.
146
-
147
- If user_list return an array of User objects like:
148
-
149
- [ User.create(:name => 'Rupert Boy', :email => 'rupert@stonean.com'),
150
- User.create(:name => 'Kaylee Girl', :email => 'kaylee@stonean.com'),
151
- User.create(:name => 'Monty Man', :email => 'monty@stonean.com')]
152
-
153
- <table id="aab">
154
- <tr>
155
- <td>Rupert Boy</td>
156
- <td>rupert@stonean.com</td>
157
- </tr>
158
- <tr>
159
- <td>Kaylee Girl</td>
160
- <td>kaylee@stonean.com</td>
161
- </tr>
162
- <tr>
163
- <td>Monty Man</td>
164
- <td>monty@stonean.com</td>
165
- </tr>
166
- </table>
167
-
168
-
169
-
170
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
171
- :: Using a Layout ::
172
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
173
-
174
- Layout:
175
- <html>
176
- <head>
177
- <title>This is a title template</title>
178
- </head>
179
- <body>
180
- <div data-ruhl="_render_"></div>
181
- </body>
182
- </html>
183
-
184
- Fragment:
185
- <h1 data-ruhl="generate_h1">I am a templated headline</h1>
186
- <p data-ruhl="my_content">Lorem ipsum dolor sit amet</p>
187
-
188
- To use:
189
-
190
- RuHL::Engine.new(File.read(fragment), :layout => path_to_layout).render(self)
191
-
192
- Returns the expected result of parsed Layout w/ parsed Fragment.
193
-
194
- Note the use of the _render_ method. This is a 'special' method that
195
- RuHL uses to inject the results of the parsed fragment into the layout.
196
-
197
-
198
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
199
- :: Using a Partial ::
200
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
201
-
202
- Main:
203
- <html>
204
- <head>
205
- <title>This is a title template</title>
206
- </head>
207
- <body>
208
- <div id="wrap">
209
- <div id="sidebar" data-ruhl="_partial: sidebar_partial">
210
- <h3>Sidebar links</h3>
211
- <ul>
212
- <li><a href="#">Link 1</a></li>
213
- <li><a href="#">Link 2</a></li>
214
- <li><a href="#">Link 3</a></li>
215
- <li><a href="#">Link 4</a></li>
216
- </ul>
217
- </div>
218
- <div id="main">
219
- <h1> My main content</h1>
220
- <p>Text designers would put here to test their layout</p>
221
- </div>
222
- </div>
223
- </body>
224
- </html>
225
-
226
- Sidebar:
227
- <h3>Real Sidebarlinks</h3>
228
- <ul>
229
- <li><a href="#">Real Link 1</a></li>
230
- <li><a href="#">Real Link 2</a></li>
231
- <li><a href="#">Real Link 3</a></li>
232
- <li><a href="#">Real Link 4</a></li>
233
- </ul>
234
-
235
- To use:
236
-
237
- RuHL::Engine.new(File.read(path_to_main)).render(self)
238
-
239
- Returns the expected result of parsed Main with sidebar div contents
240
- replaced with parsed sidebar partial contents.
241
-
242
- Note the use of the _partial key. This is a 'special' key that RuHL
243
- uses to inject the results of the parsed partial into the contents
244
- of the calling node.
245
-
246
-
247
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
248
- :: Conditional display of block (_if)::
249
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
250
-
251
- <html>
252
- <head>
253
- <title>This is a title template</title>
254
- </head>
255
- <body>
256
- <h1>This is the header template</h1>
257
- <div data-ruhl="_if: users?">
258
- <table>
259
- <thead>
260
- <tr>
261
- <td>First Name</td>
262
- <td>Last Name</td>
263
- <td>Email</td>
264
- </tr>
265
- </thead>
266
- <tr data-ruhl="_collection: user_list">
267
- <td data-ruhl="first_name">Andrew</td>
268
- <td data-ruhl="last_name">Stone</td>
269
- <td data-ruhl="email">andy@stonean.com</td>
270
- </tr>
271
- </table>
272
- </div>
273
- </ul>
274
- </body>
275
- </html>
276
-
277
- if users? returns false then the div (including it's contents) are not shown
278
- on output.
279
-
280
-
281
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
282
- :: Conditional display of tag (_if)::
283
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
284
-
285
- <html>
286
- <head>
287
- <title>This is a title template</title>
288
- </head>
289
- <body>
290
- <h1>This is the header template</h1>
291
- <table>
292
- <thead>
293
- <tr>
294
- <td>First Name</td>
295
- <td>Last Name</td>
296
- <td>Email</td>
297
- </tr>
298
- </thead>
299
- <tr data-ruhl="_collection: user_list">
300
- <td data-ruhl="first_name">Andrew</td>
301
- <td data-ruhl="last_name">Stone</td>
302
- <td data-ruhl="_if: email">andy@stonean.com</td>
303
- </tr>
304
- </table>
305
- </ul>
306
- </body>
307
- </html>
308
-
309
- if email.nil? then the td is not shown.
310
-
311
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
312
- :: Conditional display of tag (_unless)::
313
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
314
-
315
- <html>
316
- <head>
317
- <title>This is a title template</title>
318
- </head>
319
- <body>
320
- <h1>This is the header template</h1>
321
- <table data-ruhl="_if: users?">
322
- <thead>
323
- <tr>
324
- <td>First Name</td>
325
- <td>Last Name</td>
326
- <td>Email</td>
327
- </tr>
328
- </thead>
329
- <tr data-ruhl="_collection: user_list">
330
- <td data-ruhl="first_name">Andrew</td>
331
- <td data-ruhl="last_name">Stone</td>
332
- <td data-ruhl="_if: email">andy@stonean.com</td>
333
- </tr>
334
- </table>
335
- <p data-ruhl="_unless: users?">No Users were found.</p>
336
- </ul>
337
- </body>
338
- </html>
339
-
340
- if users? == false then the "No Users were found" message appears.
341
-
342
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
343
- :: Scope object to tag block (_use)::
344
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
345
-
346
- <html>
347
- <head>
348
- <title>My Account</title>
349
- </head>
350
- <body>
351
- <div data-ruhl="_use: current_user">
352
- <h1> Editing <span data-ruhl="full_name"/></h1>
353
- <table>
354
- <thead>
355
- <tr>
356
- <td>First Name</td>
357
- <td>Last Name</td>
358
- <td>Email</td>
359
- </tr>
360
- </thead>
361
- <tr>
362
- <td data-ruhl="first_name">Andrew</td>
363
- <td data-ruhl="last_name">Stone</td>
364
- <td data-ruhl="_if: email">andy@stonean.com</td>
365
- </tr>
366
- </table>
367
- </div>
368
- </body>
369
- </html>
370
-
371
- The table row information will be replace with the current_user details.
372
-
373
- *Note: _use can not be used with _partial as it replaces the inner_html
374
-
375
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
376
- :: Notes ::
377
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
378
-
379
- * No eval (I don't think eval is evil, it's just not the way this works)
380
-
381
- * The data-ruhl attribute is always removed from the output.
382
-
383
- * Since it's just HTML, syntax highlighting is built-in.
384
- For vim, just add this to your ~/.vimrc:
385
- au BufNewFile,BufRead *.ruhl set filetype=html
386
-
387
-
388
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
389
- :: TODO ::
390
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
391
-
392
- 1) Test more scenarios
7
+ http://stonean.com/page/ruhl
393
8
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.7
1
+ 0.10.0
data/lib/ruhl/engine.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module Ruhl
2
2
  class Engine
3
- attr_reader :document, :scope, :layout, :layout_source,
4
- :local_object, :block_object
3
+ attr_reader :layout, :layout_source, :local_object, :block_object
4
+ attr_reader :document, :scope, :current_tag, :call_result, :ruhl_actions
5
5
 
6
6
  def initialize(html, options = {})
7
7
  @local_object = options[:local_object] || options[:object]
@@ -45,38 +45,37 @@ module Ruhl
45
45
  render_nodes Nokogiri::HTML( @layout_source || File.read(@layout) )
46
46
  end
47
47
 
48
- def render_partial(tag, code)
49
- file = execute_ruby(tag, code)
50
- raise PartialNotFoundError.new(file) unless File.exists?(file)
48
+ def render_partial
49
+ unless File.exists?(call_result)
50
+ raise PartialNotFoundError.new(call_result)
51
+ end
51
52
 
52
- render_nodes Nokogiri::HTML.fragment( File.read(file) )
53
+ render_nodes Nokogiri::HTML.fragment( File.read(call_result) )
53
54
  end
54
55
 
55
- def render_collection(tag, code, actions = nil)
56
- results = execute_ruby(tag, code)
57
-
58
- actions = actions.to_s.strip
56
+ def render_collection
57
+ actions = ruhl_actions.join(",").to_s.strip if ruhl_actions
59
58
 
60
- tag['data-ruhl'] = actions if actions.length > 0
61
- html = tag.to_html
59
+ current_tag['data-ruhl'] = actions if actions.length > 0
60
+ html = current_tag.to_html
62
61
 
63
- new_content = results.collect do |item|
62
+ new_content = call_result.collect do |item|
64
63
  # Call to_s on the item only if there are no other actions
65
64
  # 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
65
+ if actions.length == 0 && current_tag.xpath('.//*[@data-ruhl]').length == 0
66
+ current_tag.inner_html = item.to_s
67
+ current_tag.to_html
69
68
  else
70
69
  Ruhl::Engine.new(html, :local_object => item).render(scope)
71
70
  end
72
71
  end.to_s
73
72
 
74
- tag.swap(new_content)
73
+ current_tag.swap(new_content)
75
74
  end
76
75
 
77
- def render_block(tag, code)
78
- bo = execute_ruby(tag, code)
79
- Ruhl::Engine.new(tag.inner_html, :block_object => bo).render(scope)
76
+ def render_block
77
+ Ruhl::Engine.new(current_tag.inner_html,
78
+ :block_object => call_result).render(scope)
80
79
  end
81
80
 
82
81
  def render_nodes(nodes)
@@ -91,97 +90,117 @@ module Ruhl
91
90
 
92
91
  return if nodes.empty?
93
92
 
94
- tag = nodes.first
95
- code = tag.remove_attribute('data-ruhl')
96
- process_attribute(tag, code.value)
93
+ @current_tag = nodes.first
94
+
95
+ @ruhl_actions = current_tag.remove_attribute('data-ruhl').value.split(',')
96
+
97
+ process_attribute
97
98
 
98
99
  parse_doc(doc)
99
100
  end
100
101
 
101
- def process_attribute(tag, code)
102
- actions = code.split(',')
103
- actions.dup.each_with_index do |pair, ndx|
104
- attribute, value = pair.split(':')
105
-
106
- attribute.strip!
102
+ def process_attribute
103
+ catch(:done) do
104
+ ruhl_actions.dup.each_with_index do |action, ndx|
105
+ # Remove action from being applied twice.
106
+ ruhl_actions.delete_at(ndx)
107
+
108
+ process_action(action)
109
+ end
110
+ end
111
+ end
112
+
113
+ def process_action(action)
114
+ attribute, value = action.split(':')
107
115
 
108
- if value.nil?
109
- results = execute_ruby(tag, attribute)
110
- process_results(tag, results)
116
+ code = (value || attribute)
117
+ @call_result = execute_ruby(code.strip)
118
+
119
+ if value.nil?
120
+ process_results
121
+ else
122
+ if attribute =~ /^_/
123
+ process_ruhl(attribute, value)
111
124
  else
112
- value.strip!
113
-
114
- unless attribute =~ /^_/
115
- tag[attribute] = execute_ruby(tag, value).to_s
116
- else
117
- case attribute
118
- when "_use"
119
- tag.inner_html = render_block(tag, value)
120
- when "_partial"
121
- tag.inner_html = render_partial(tag, value)
122
- when "_collection"
123
- actions.delete_at(ndx)
124
- render_collection(tag, value, actions.join(','))
125
- return
126
- when "_if"
127
- return unless process_if(tag, value)
128
- when "_unless"
129
- return if process_unless(tag, value)
130
- end
131
- end
125
+ current_tag[attribute] = call_result.to_s
132
126
  end
133
127
  end
134
128
  end
129
+
130
+ def process_ruhl(attribute, value)
131
+ case attribute
132
+ when "_use_if"
133
+ ruhl_if { ruhl_use }
134
+ when "_use", "_collection"
135
+ ruhl_use
136
+ when "_partial"
137
+ current_tag.inner_html = render_partial
138
+ when "_if"
139
+ ruhl_if
140
+ when "_unless"
141
+ ruhl_unless
142
+ end
143
+ end
144
+
145
+ def ruhl_use
146
+ if call_result.kind_of?(Enumerable) and !call_result.instance_of?(String)
147
+ render_collection
148
+ throw :done
149
+ else
150
+ current_tag.inner_html = render_block
151
+ end
152
+ end
135
153
 
136
- def process_if(tag, value)
137
- contents = execute_ruby(tag, value)
138
- if contents
139
- process_results(tag, contents) unless contents == true
140
- true
154
+ def ruhl_if
155
+ if stop_processing?
156
+ current_tag.remove
157
+ throw :done
141
158
  else
142
- tag.remove
143
- false
159
+ if continue_processing?
160
+ yield if block_given?
161
+ else
162
+ process_results
163
+ end
144
164
  end
145
165
  end
146
166
 
147
- def process_unless(tag, value)
148
- contents = execute_ruby(tag, value)
149
- if contents
150
- tag.remove
151
- true
152
- else
153
- false
167
+ def ruhl_unless
168
+ if call_result
169
+ unless call_result_empty?
170
+ current_tag.remove
171
+ throw :done
172
+ end
154
173
  end
155
174
  end
156
175
 
157
- def process_results(tag, results)
158
- if results.is_a?(Hash)
159
- results.each do |key, value|
176
+ def process_results
177
+ if call_result.is_a?(Hash)
178
+ call_result.each do |key, value|
160
179
  if key == :inner_html
161
- tag.inner_html = value.to_s
180
+ current_tag.inner_html = value.to_s
162
181
  else
163
- tag[key.to_s] = value.to_s
182
+ current_tag[key.to_s] = value.to_s
164
183
  end
165
184
  end
166
185
  else
167
- tag.inner_html = results.to_s
186
+ current_tag.inner_html = call_result.to_s
168
187
  end
169
188
  end
170
189
 
171
- def execute_ruby(tag, code)
172
- unless code == '_render_'
173
- if local_object && local_object.respond_to?(code)
174
- local_object.send(code)
175
- elsif block_object && block_object.respond_to?(code)
190
+ def execute_ruby(code)
191
+ if code == '_render_'
192
+ _render_
193
+ else
194
+ if block_object && block_object.respond_to?(code)
176
195
  block_object.send(code)
196
+ elsif local_object && local_object.respond_to?(code)
197
+ local_object.send(code)
177
198
  else
178
199
  scope.send(code)
179
200
  end
180
- else
181
- _render_
182
201
  end
183
202
  rescue NoMethodError => e
184
- log_context(tag,code)
203
+ log_context(code)
185
204
  raise e
186
205
  end
187
206
 
@@ -190,10 +209,24 @@ module Ruhl
190
209
  @scope = current_scope
191
210
  end
192
211
 
193
- def log_context(tag,code)
212
+ def stop_processing?
213
+ call_result.nil? ||
214
+ call_result == false ||
215
+ call_result_empty?
216
+ end
217
+
218
+ def continue_processing?
219
+ call_result == true || !call_result_empty?
220
+ end
221
+
222
+ def call_result_empty?
223
+ call_result.kind_of?(Enumerable) && call_result.empty?
224
+ end
225
+
226
+ def log_context(code)
194
227
  Ruhl.logger.error <<CONTEXT
195
228
  Context:
196
- tag : #{tag.inspect}
229
+ tag : #{current_tag.inspect}
197
230
  code : #{code.inspect}
198
231
  local_object : #{local_object.inspect}
199
232
  block_object : #{block_object.inspect}
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.7"
8
+ s.version = "0.10.0"
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-18}
12
+ s.date = %q{2009-10-24}
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 = [
@@ -32,6 +32,7 @@ Gem::Specification.new do |s|
32
32
  "spec/html/fragment.html",
33
33
  "spec/html/hash.html",
34
34
  "spec/html/if.html",
35
+ "spec/html/if_on_collection.html",
35
36
  "spec/html/layout.html",
36
37
  "spec/html/loop.html",
37
38
  "spec/html/main_with_form.html",
@@ -40,6 +41,7 @@ Gem::Specification.new do |s|
40
41
  "spec/html/seo.html",
41
42
  "spec/html/sidebar.html",
42
43
  "spec/html/use.html",
44
+ "spec/html/use_if.html",
43
45
  "spec/rcov.opts",
44
46
  "spec/ruhl_spec.rb",
45
47
  "spec/spec.opts",
@@ -0,0 +1,23 @@
1
+ <html>
2
+ <head>
3
+ <title>This is a title template</title>
4
+ </head>
5
+ <body>
6
+ <h1>This is the header template</h1>
7
+ <table data-ruhl="_if: user_list">
8
+ <thead>
9
+ <tr>
10
+ <td>First Name</td>
11
+ <td>Last Name</td>
12
+ <td>Email</td>
13
+ </tr>
14
+ </thead>
15
+ <tr data-ruhl="_collection: user_list">
16
+ <td data-ruhl="first_name">Andrew</td>
17
+ <td data-ruhl="last_name">Stone</td>
18
+ <td data-ruhl="_if: email">andy@stonean.com</td>
19
+ </tr>
20
+ </table>
21
+ <p data-ruhl="_unless: user_list, no_users_message"/>
22
+ </body>
23
+ </html>
@@ -0,0 +1,28 @@
1
+ <html>
2
+ <head>
3
+ <title>This is a title template</title>
4
+ </head>
5
+ <body>
6
+ <div id="sidebar" data-ruhl="_use_if: user">
7
+ <h1>My Account</h1>
8
+ <form action="/account" class="edit_user" id="edit_user" method="post">
9
+
10
+ <label for='user_first_name'>First Name:</label>
11
+ <input id="user_first_name" name="user[first_name]" size="30" type="text"
12
+ data-ruhl="value: first_name" />
13
+
14
+ <label for='user_last_name'>Last Name:</label>
15
+ <input id="user_last_name" name="user[last_name]" size="30" type="text"
16
+ data-ruhl="value: last_name" />
17
+
18
+ <label for='user_email'>Email:</label>
19
+ <input id="user_email" name="user[email]" size="30" type="text"
20
+ data-ruhl="value: email" />
21
+
22
+ <div class='btn_row'>
23
+ <input id="user_submit" name="commit" type="submit" value="Login" />
24
+ </div>
25
+ </form>
26
+ </div>
27
+ </body>
28
+ </html>
data/spec/ruhl_spec.rb CHANGED
@@ -82,11 +82,35 @@ describe Ruhl do
82
82
  end
83
83
  end
84
84
 
85
+ shared_examples_for "if with no users" do
86
+ it "table should not render" do
87
+ nodes = @doc.xpath('/html/body//*')
88
+ nodes.children.length.should == 2
89
+ nodes.children[0].to_s.should == "This is the header template"
90
+ end
91
+
92
+ it "no user message should render" do
93
+ nodes = @doc.xpath('/html/body//*')
94
+ nodes.children[1].to_s.should == @co.no_users_message
95
+ end
96
+ end
97
+
98
+ shared_examples_for "if with users" do
99
+ it "table should render" do
100
+ nodes = @doc.xpath('/html/body//*')
101
+ nodes.children.length.should > 1
102
+
103
+ table = @doc.xpath('/html/body/table/tr//td')
104
+ table.children[12].to_s.should == "NoMail"
105
+ table.children[13].to_s.should == "Man"
106
+ end
107
+ end
108
+
85
109
  describe "if.html" do
86
- describe "no users" do
110
+ describe "users? is false" do
87
111
  before do
88
112
  class ContextObject
89
- def users?(tag = nil)
113
+ def users?
90
114
  false
91
115
  end
92
116
  end
@@ -95,22 +119,13 @@ describe Ruhl do
95
119
  @doc = create_doc
96
120
  end
97
121
 
98
- it "table should not render" do
99
- nodes = @doc.xpath('/html/body//*')
100
- nodes.children.length.should == 2
101
- nodes.children[0].to_s.should == "This is the header template"
102
- end
103
-
104
- it "no user message should render" do
105
- nodes = @doc.xpath('/html/body//*')
106
- nodes.children[1].to_s.should == @co.no_users_message
107
- end
122
+ it_should_behave_like "if with no users"
108
123
  end
109
124
 
110
- describe "has users" do
125
+ describe "users? is true" do
111
126
  before do
112
127
  class ContextObject
113
- def users?(tag = nil)
128
+ def users?
114
129
  true
115
130
  end
116
131
  end
@@ -119,14 +134,45 @@ describe Ruhl do
119
134
  @doc = create_doc
120
135
  end
121
136
 
122
- it "table should render" do
123
- nodes = @doc.xpath('/html/body//*')
124
- nodes.children.length.should > 1
137
+ it_should_behave_like "if with users"
138
+ end
139
+ end
140
+
141
+ describe "if_on_collection.html" do
142
+ describe "user_list is empty" do
143
+ before do
144
+ class ContextObject
145
+ def user_list
146
+ []
147
+ end
148
+ end
149
+
150
+ @html = File.read html(:if_on_collection)
151
+ @doc = create_doc
152
+ end
153
+
154
+ it_should_behave_like "if with no users"
155
+ end
156
+
157
+ describe "user_list is not empty" do
158
+ before do
159
+ class ContextObject
160
+ def user_list
161
+ [
162
+ TestUser.new('Jane', 'Doe', 'jane@stonean.com'),
163
+ TestUser.new('John', 'Joe', 'john@stonean.com'),
164
+ TestUser.new('Jake', 'Smo', 'jake@stonean.com'),
165
+ TestUser.new('Paul', 'Tin', 'paul@stonean.com'),
166
+ TestUser.new('NoMail', 'Man')
167
+ ]
168
+ end
169
+ end
125
170
 
126
- table = @doc.xpath('/html/body/table/tr//td')
127
- table.children[12].to_s.should == "NoMail"
128
- table.children[13].to_s.should == "Man"
171
+ @html = File.read html(:if_on_collection)
172
+ @doc = create_doc
129
173
  end
174
+
175
+ it_should_behave_like "if with users"
130
176
  end
131
177
  end
132
178
 
@@ -177,12 +223,7 @@ describe Ruhl do
177
223
  end
178
224
  end
179
225
 
180
- describe "use.html" do
181
- before do
182
- @html = File.read html(:use)
183
- @doc = create_doc
184
- end
185
-
226
+ shared_examples_for "if with user" do
186
227
  it "first name will be set" do
187
228
  @doc.xpath('/html/body/div//input')[0]['value'].should == "Jane"
188
229
  end
@@ -195,6 +236,24 @@ describe Ruhl do
195
236
  @doc.xpath('/html/body/div//input')[2]['value'].should == "jane@stonean.com"
196
237
  end
197
238
  end
239
+
240
+ describe "use.html" do
241
+ before do
242
+ @html = File.read html(:use)
243
+ @doc = create_doc
244
+ end
245
+
246
+ it_should_behave_like "if with user"
247
+ end
248
+
249
+ describe "use_if.html" do
250
+ before do
251
+ @html = File.read html(:use_if)
252
+ @doc = create_doc
253
+ end
254
+
255
+ it_should_behave_like "if with user"
256
+ end
198
257
 
199
258
  describe "collection_of_strings.html" do
200
259
  before do
data/spec/spec_helper.rb CHANGED
@@ -29,47 +29,47 @@ class TestUser
29
29
  @nicknames = ['Auntie','Pattern']
30
30
  end
31
31
 
32
- def radio_input(tag = nil)
32
+ def radio_input
33
33
  { :inner_html => first_name, :id => "user_#{id.to_s}",
34
34
  :name => "user[id]", :value => last_name.downcase}
35
35
  end
36
36
  end
37
37
 
38
- def user(tag = nil)
38
+ def user
39
39
  TestUser.new('Jane', 'Doe', 'jane@stonean.com')
40
40
  end
41
41
 
42
42
 
43
43
  class ContextObject
44
- def generate_h1(tag = nil)
44
+ def generate_h1
45
45
  "data from presenter"
46
46
  end
47
47
 
48
- def data_from_method(tag = nil)
48
+ def data_from_method
49
49
  "I am data from a method"
50
50
  end
51
51
 
52
- def generate_description(tag = nil)
52
+ def generate_description
53
53
  "I am a custom meta description"
54
54
  end
55
55
 
56
- def generate_keywords(tag = nil)
56
+ def generate_keywords
57
57
  "I, am, custom, keywords"
58
58
  end
59
59
 
60
- def my_content(tag = nil)
60
+ def my_content
61
61
  "hello from my content."
62
62
  end
63
63
 
64
- def sidebar_partial(tag = nil)
64
+ def sidebar_partial
65
65
  html(:sidebar)
66
66
  end
67
67
 
68
- def form_partial(tag = nil)
68
+ def form_partial
69
69
  html(:form)
70
70
  end
71
71
 
72
- def user_list(tag = nil)
72
+ def user_list
73
73
  [
74
74
  TestUser.new('Jane', 'Doe', 'jane@stonean.com'),
75
75
  TestUser.new('John', 'Joe', 'john@stonean.com'),
@@ -79,15 +79,15 @@ class ContextObject
79
79
  ]
80
80
  end
81
81
 
82
- def users?(tag = nil)
82
+ def users?
83
83
  true
84
84
  end
85
85
 
86
- def no_users_message(tag = nil)
86
+ def no_users_message
87
87
  "Sorry no users found"
88
88
  end
89
89
 
90
- def states_for_select(tag = nil)
90
+ def states_for_select
91
91
  state = Struct.new(:abbr, :name)
92
92
  [ state.new('AL', 'Alabama'),
93
93
  state.new('AK', 'Alaska'),
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.7
4
+ version: 0.10.0
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-18 00:00:00 -04:00
12
+ date: 2009-10-24 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -57,6 +57,7 @@ files:
57
57
  - spec/html/fragment.html
58
58
  - spec/html/hash.html
59
59
  - spec/html/if.html
60
+ - spec/html/if_on_collection.html
60
61
  - spec/html/layout.html
61
62
  - spec/html/loop.html
62
63
  - spec/html/main_with_form.html
@@ -65,6 +66,7 @@ files:
65
66
  - spec/html/seo.html
66
67
  - spec/html/sidebar.html
67
68
  - spec/html/use.html
69
+ - spec/html/use_if.html
68
70
  - spec/rcov.opts
69
71
  - spec/ruhl_spec.rb
70
72
  - spec/spec.opts