hobo 0.6.4 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/bin/hobo +4 -6
  2. data/hobo_files/plugin/CHANGES.txt +170 -0
  3. data/hobo_files/plugin/generators/hobo_front_controller/templates/index.dryml +9 -9
  4. data/hobo_files/plugin/generators/hobo_front_controller/templates/search.dryml +9 -9
  5. data/hobo_files/plugin/generators/hobo_migration/hobo_migration_generator.rb +7 -2
  6. data/hobo_files/plugin/generators/hobo_rapid/hobo_rapid_generator.rb +4 -4
  7. data/hobo_files/plugin/generators/hobo_rapid/templates/{hobo_rapid.css → hobo-rapid.css} +0 -0
  8. data/hobo_files/plugin/generators/hobo_rapid/templates/{hobo_rapid.js → hobo-rapid.js} +66 -47
  9. data/hobo_files/plugin/generators/hobo_rapid/templates/lowpro.js +130 -44
  10. data/hobo_files/plugin/generators/hobo_rapid/templates/{hobo_base.css → reset.css} +0 -5
  11. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/images/pencil.png +0 -0
  12. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/images/small_close.png +0 -0
  13. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/application.css +45 -0
  14. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/rapid_ui.css +167 -0
  15. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/views/application.dryml +10 -0
  16. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{bkg_bodytop.gif → bkg-bodytop.gif} +0 -0
  17. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{bkg_corner_01.gif → bkg-corner-01.gif} +0 -0
  18. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{bkg_corner_02.gif → bkg-corner-02.gif} +0 -0
  19. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{bkg_corner_03.gif → bkg-corner-03.gif} +0 -0
  20. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{bkg_corner_04.gif → bkg-corner-04.gif} +0 -0
  21. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{bkg_shadow_bottom.gif → bkg-shadow-bottom.gif} +0 -0
  22. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{bkg_shadow_left.gif → bkg-shadow-left.gif} +0 -0
  23. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{bkg_shadow_right.gif → bkg-shadow-right.gif} +0 -0
  24. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{bkg_shadow_top.gif → bkg-shadow-top.gif} +0 -0
  25. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{header_blue.gif → header-blue.gif} +0 -0
  26. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{header_dblue.gif → header-dblue.gif} +0 -0
  27. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{header_green.gif → header-green.gif} +0 -0
  28. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{header_purple.gif → header-purple.gif} +0 -0
  29. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{header_red.gif → header-red.gif} +0 -0
  30. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{txt_list_img_dblue.gif → txt-list-img-dblue.gif} +0 -0
  31. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{txt_list_img_green.gif → txt-list-img-green.gif} +0 -0
  32. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{txt_list_img_purple.gif → txt-list-img-purple.gif} +0 -0
  33. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{txt_list_img_red.gif → txt-list-img-red.gif} +0 -0
  34. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{window_corner_01.gif → window-corner-01.gif} +0 -0
  35. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{window_corner_02.gif → window-corner-02.gif} +0 -0
  36. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{window_corner_03.gif → window-corner-03.gif} +0 -0
  37. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{window_corner_04.gif → window-corner-04.gif} +0 -0
  38. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{window_shadow_bottom.gif → window-shadow-bottom.gif} +0 -0
  39. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{window_shadow_left.gif → window-shadow-left.gif} +0 -0
  40. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{window_shadow_right.gif → window-shadow-right.gif} +0 -0
  41. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/{window_shadow_top.gif → window-shadow-top.gif} +0 -0
  42. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/stylesheets/application.css +69 -69
  43. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/views/application.dryml +39 -53
  44. data/hobo_files/plugin/generators/hobo_user_model/templates/model.rb +1 -1
  45. data/hobo_files/plugin/lib/extensions.rb +0 -16
  46. data/hobo_files/plugin/lib/hobo/dryml/part_context.rb +1 -1
  47. data/hobo_files/plugin/lib/hobo/dryml/tag_parameters.rb +35 -0
  48. data/hobo_files/plugin/lib/hobo/dryml/taglib.rb +2 -2
  49. data/hobo_files/plugin/lib/hobo/dryml/template.rb +165 -236
  50. data/hobo_files/plugin/lib/hobo/dryml/template_environment.rb +158 -123
  51. data/hobo_files/plugin/lib/hobo/hobo_helper.rb +15 -4
  52. data/hobo_files/plugin/lib/hobo/model.rb +30 -11
  53. data/hobo_files/plugin/lib/hobo/model_controller.rb +13 -9
  54. data/hobo_files/plugin/lib/hobo/model_router.rb +27 -7
  55. data/hobo_files/plugin/lib/hobo/static_tags +0 -2
  56. data/hobo_files/plugin/lib/hobo/user.rb +3 -3
  57. data/hobo_files/plugin/lib/rexml.rb +10 -3
  58. data/hobo_files/plugin/tags/core.dryml +11 -16
  59. data/hobo_files/plugin/tags/rapid.dryml +147 -110
  60. data/hobo_files/plugin/tags/rapid_document_tags.dryml +22 -20
  61. data/hobo_files/plugin/tags/rapid_editing.dryml +41 -41
  62. data/hobo_files/plugin/tags/rapid_forms.dryml +51 -49
  63. data/hobo_files/plugin/tags/rapid_navigation.dryml +34 -34
  64. data/hobo_files/plugin/tags/rapid_pages.dryml +174 -174
  65. data/hobo_files/plugin/tags/rapid_plus.dryml +19 -19
  66. data/hobo_files/plugin/tags/rapid_support.dryml +5 -5
  67. data/hobo_files/plugin/tasks/dump_fixtures.rake +62 -53
  68. data/hobo_files/plugin/tasks/fix_dryml.rake +144 -0
  69. data/hobo_files/plugin/tasks/hobo_tasks.rake +0 -4
  70. metadata +43 -32
  71. data/hobo_files/plugin/lib/hobo/dryml/tag_module.rb +0 -9
@@ -20,7 +20,7 @@ class <%= class_name %> < ActiveRecord::Base
20
20
  end
21
21
 
22
22
  def creatable_by?(creator)
23
- false
23
+ true
24
24
  end
25
25
 
26
26
  def updatable_by?(updater, new)
@@ -31,22 +31,6 @@ class Module
31
31
  end
32
32
 
33
33
 
34
- def alias_tag_chain(tag, feature)
35
- if tag.to_s =~ /^[A-Z]/
36
- without = "#{tag}Without#{feature.to_s.camelize}"
37
- with = "#{tag}With#{feature.to_s.camelize}"
38
- else
39
- without = "#{tag}_without_#{feature}"
40
- with = "#{tag}_with_#{feature}"
41
- end
42
-
43
- unless instance_methods.include?(without)
44
- alias_method without, tag
45
- alias_method tag, with
46
- end
47
- end
48
-
49
-
50
34
  # Fix delegate so it doesn't go bang if 'to' is nil
51
35
  def delegate(*methods)
52
36
  options = methods.pop
@@ -20,7 +20,7 @@ module Hobo
20
20
 
21
21
  contexts.map do |dom_id, context|
22
22
  code = context.marshal(session).split("\n").map{|line| "'#{line}\\n'"}.join(" +\n ")
23
- "hoboParts.#{dom_id} = (#{code});\n"
23
+ "hoboParts['#{dom_id}'] = (#{code});\n"
24
24
  end.join
25
25
  end
26
26
 
@@ -0,0 +1,35 @@
1
+ module Hobo
2
+
3
+ module Dryml
4
+
5
+ class NoParameterError < RuntimeError; end
6
+
7
+ class TagParameters < Hash
8
+
9
+ def initialize(parameters, exclude_names=nil)
10
+ if exclude_names.blank?
11
+ update(parameters)
12
+ else
13
+ parameters.each_pair { |k, v| self[k] = v unless k.in?(exclude_names) }
14
+ end
15
+ end
16
+
17
+ def method_missing(name, default_content="")
18
+ if name.to_s =~ /\?$/
19
+ has_key?(name.to_s[0..-2].to_sym)
20
+ else
21
+ self[name]._?.call(default_content) || ""
22
+ end
23
+ end
24
+
25
+ undef_method :default
26
+
27
+ def [](param_name)
28
+ fetch(param_name, nil)
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -45,7 +45,7 @@ module Hobo::Dryml
45
45
 
46
46
  def included(base)
47
47
  @tag_aliases.each do |tag, feature|
48
- base.send(:alias_tag_chain, tag, feature)
48
+ base.send(:alias_method_chain, tag, feature)
49
49
  end
50
50
  end
51
51
 
@@ -54,7 +54,7 @@ module Hobo::Dryml
54
54
  end
55
55
  attr_reader :tag_attrs
56
56
 
57
- def _alias_tag_chain(tag, feature)
57
+ def delayed_alias_method_chain(tag, feature)
58
58
  @tag_aliases[tag] = feature
59
59
  end
60
60
 
@@ -4,15 +4,18 @@ module Hobo::Dryml
4
4
 
5
5
  class Template
6
6
 
7
- DRYML_NAME = "[a-zA-Z_][a-zA-Z0-9_]*"
7
+ DRYML_NAME = "[a-zA-Z\-][a-zA-Z0-9\-]*"
8
8
  DRYML_NAME_RX = /^#{DRYML_NAME}$/
9
+
10
+ RUBY_NAME = "[a-zA-Z_][a-zA-Z0-9_]*"
11
+ RUBY_NAME_RX = /^#{RUBY_NAME}$/
9
12
 
10
13
  CODE_ATTRIBUTE_CHAR = "&"
11
14
 
12
- SPECIAL_ATTRIBUTES = %w(param merge merge_params merge_attrs
13
- for_type
15
+ SPECIAL_ATTRIBUTES = %w(param merge merge-params merge-attrs
16
+ for-type
14
17
  if unless repeat
15
- part part_locals
18
+ part part-locals
16
19
  restore)
17
20
 
18
21
  @build_cache = {}
@@ -134,8 +137,7 @@ module Hobo::Dryml
134
137
 
135
138
 
136
139
  def element_to_erb(el)
137
- dryml_exception("parameter tags (<#{el.name}>) are no more, wake up and smell the coffee", el) if
138
- el.name.starts_with?(":")
140
+ dryml_exception("old-style parameter tag (<#{el.name}>)", el) if el.name.starts_with?(":")
139
141
 
140
142
  @last_element = el
141
143
  case el.dryml_name
@@ -145,7 +147,7 @@ module Hobo::Dryml
145
147
  # return nothing - the include has no presence in the erb source
146
148
  tag_newlines(el)
147
149
 
148
- when "set_theme"
150
+ when "set-theme"
149
151
  require_attribute(el, "name", /^#{DRYML_NAME}$/)
150
152
  @builder.add_build_instruction(:set_theme, :name => el.attributes['name'])
151
153
 
@@ -155,25 +157,18 @@ module Hobo::Dryml
155
157
  when "def"
156
158
  def_element(el)
157
159
 
158
- when "tagbody"
159
- tagbody_element(el)
160
-
161
160
  when "set"
162
161
  set_element(el)
163
162
 
164
- when "set_scoped"
163
+ when "set-scoped"
165
164
  set_scoped_element(el)
166
165
 
167
- when "default_tagbody"
168
- default_tagbody_element(el)
166
+ when "param-content"
167
+ param_content_element(el)
169
168
 
170
169
  else
171
170
  if el.dryml_name.not_in?(Hobo.static_tags) || el.attributes['param'] || el.attributes['restore']
172
- if el.dryml_name =~ /^[A-Z]/
173
- template_call(el)
174
- else
175
- tag_call(el)
176
- end
171
+ tag_call(el)
177
172
  else
178
173
  static_element_to_erb(el)
179
174
  end
@@ -204,7 +199,7 @@ module Hobo::Dryml
204
199
  def set_element(el)
205
200
  assigns = el.attributes.map do |name, value|
206
201
  dryml_exception(el, "invalid name in set") unless name =~ /^#{DRYML_NAME}(\.#{DRYML_NAME})*$/
207
- "#{name} = #{attribute_to_ruby(value)}; "
202
+ "#{ruby_name name} = #{attribute_to_ruby(value)}; "
208
203
  end.join
209
204
  code = apply_control_attributes("begin; #{assigns}; end", el)
210
205
  "<% #{assigns}#{tag_newlines(el)} %>"
@@ -213,8 +208,8 @@ module Hobo::Dryml
213
208
 
214
209
  def set_scoped_element(el)
215
210
  assigns = el.attributes.map do |name, value|
216
- dryml_exception(el, "invalid name in set_scoped") unless name =~ DRYML_NAME_RX
217
- "scope[:#{name}] = #{attribute_to_ruby(value)}; "
211
+ dryml_exception(el, "invalid name in set-scoped") unless name =~ DRYML_NAME_RX
212
+ "scope[:#{ruby_name name}] = #{attribute_to_ruby(value)}; "
218
213
  end.join
219
214
  "<% scope.new_scope { #{assigns}#{tag_newlines(el)} %>#{children_to_erb(el)}<% } %>"
220
215
  end
@@ -222,19 +217,32 @@ module Hobo::Dryml
222
217
 
223
218
  def declared_attributes(def_element)
224
219
  attrspec = def_element.attributes["attrs"]
225
- attr_names = attrspec ? attrspec.split(/\s*,\s*/).every(:to_sym) : []
220
+ attr_names = attrspec ? attrspec.split(/\s*,\s*/).map{ |n| n.underscore.to_sym } : []
226
221
  invalids = attr_names & ([:with, :field, :this] + SPECIAL_ATTRIBUTES.every(:to_sym))
227
222
  dryml_exception("invalid attrs in def: #{invalids * ', '}", def_element) unless invalids.empty?
228
223
  attr_names
229
224
  end
225
+
226
+
227
+ def ruby_name(dryml_name)
228
+ dryml_name.gsub('-', '_')
229
+ end
230
+
231
+
232
+ def with_containing_tag_name(el)
233
+ old = @containing_tag_name
234
+ @containing_tag_name = el.dryml_name
235
+ yield
236
+ @containing_tag_name = old
237
+ end
230
238
 
231
239
 
232
240
  def def_element(el)
233
241
  require_toplevel(el)
234
242
  require_attribute(el, "tag", DRYML_NAME_RX)
235
243
  require_attribute(el, "attrs", /^\s*#{DRYML_NAME}(\s*,\s*#{DRYML_NAME})*\s*$/, true)
236
- require_attribute(el, "alias_of", DRYML_NAME_RX, true)
237
- require_attribute(el, "extend_with", DRYML_NAME_RX, true)
244
+ require_attribute(el, "alias-of", DRYML_NAME_RX, true)
245
+ require_attribute(el, "extend-with", DRYML_NAME_RX, true)
238
246
 
239
247
  unsafe_name = el.attributes["tag"]
240
248
  name = Hobo::Dryml.unreserve(unsafe_name)
@@ -257,32 +265,28 @@ module Hobo::Dryml
257
265
  old_def_name = @def_name
258
266
  @def_name = @def_name ? "#{@def_name}_#{unsafe_name}" : unsafe_name
259
267
 
260
- alias_of = el.attributes['alias_of']
261
- extend_with = el.attributes['extend_with']
268
+ alias_of = el.attributes['alias-of']
269
+ extend_with = el.attributes['extend-with']
262
270
 
263
- dryml_exception("def cannot have both alias_of and extend_with", el) if alias_of && extend_with
264
- dryml_exception("def with alias_of must be empty", el) if alias_of and el.size > 0
271
+ dryml_exception("def cannot have both alias-of and extend-with", el) if alias_of && extend_with
272
+ dryml_exception("def with alias-of must be empty", el) if alias_of and el.size > 0
265
273
 
266
274
 
267
275
  @builder.add_build_instruction(:alias_method,
268
- :new => name.to_sym, :old => alias_of.to_sym) if alias_of
276
+ :new => ruby_name(name).to_sym, :old => ruby_name(alias_of).to_sym) if alias_of
269
277
 
270
278
  res = if alias_of
271
279
  "<% #{tag_newlines(el)} %>"
272
280
  else
273
281
  src = ""
274
282
  if extend_with
275
- src << "<% _alias_tag_chain :#{name}, :#{extend_with} %>"
276
- name = extended_name(name, extend_with)
283
+ src << "<% delayed_alias_method_chain :#{ruby_name name}, :#{ruby_name extend_with} %>"
284
+ name = "#{name}-with-#{extend_with}"
277
285
  end
278
- src << if template_name?(name)
279
- template_method(name, el)
280
- else
281
- tag_method(name, el)
282
- end
283
- src << "<% _register_tag_attrs(:#{name}, #{declared_attributes(el).inspect}) %>"
286
+ src << tag_method(name, el) +
287
+ "<% _register_tag_attrs(:#{ruby_name name}, #{declared_attributes(el).inspect.underscore}) %>"
284
288
 
285
- logger.debug(restore_erb_scriptlets(src)) if el.attributes["debug_source"]
289
+ logger.debug(restore_erb_scriptlets(src)) if el.attributes["debug-source"]
286
290
 
287
291
  @builder.add_build_instruction(:def,
288
292
  :src => restore_erb_scriptlets(src),
@@ -295,62 +299,36 @@ module Hobo::Dryml
295
299
  end
296
300
 
297
301
 
298
- def extended_name(name, feature)
299
- if template_name?(name)
300
- "#{name}With#{feature.camelize}"
301
- else
302
- "#{name}_with_#{feature}"
303
- end
304
- end
305
-
306
-
307
- def template_call?(el)
308
- template_name?(el.dryml_name)
309
- end
310
-
311
-
312
- def template_name?(name)
313
- name =~ /^[A-Z]/
314
- end
315
-
316
-
317
- def param_names_in_template(el)
302
+ def param_names_in_definition(el)
318
303
  REXML::XPath.match(el, ".//*[@param]").map do |e|
319
304
  name = get_param_name(e)
320
305
  dryml_exception("invalid param name: #{name.inspect}", e) unless
321
- is_code_attribute?(name) || name =~ DRYML_NAME_RX || name =~ /#\{/
306
+ is_code_attribute?(name) || name =~ RUBY_NAME_RX || name =~ /#\{/
322
307
  name.to_sym unless is_code_attribute?(name)
323
308
  end.compact
324
309
  end
325
310
 
326
311
 
327
- def template_method(name, el)
328
- param_names = param_names_in_template(el)
312
+ def tag_method(name, el)
313
+ param_names = param_names_in_definition(el)
329
314
 
330
- "<% def #{name}(all_attributes={}, all_parameters={}, &__block__); " +
331
- "parameters = all_parameters - #{param_names.inspect}; " +
315
+ "<% def #{ruby_name name}(all_attributes={}, all_parameters={}); " +
316
+ "parameters = Hobo::Dryml::TagParameters.new(all_parameters, #{param_names.inspect.underscore}); " +
317
+ "all_parameters = Hobo::Dryml::TagParameters.new(all_parameters); " +
332
318
  tag_method_body(el) +
333
319
  "; end %>"
334
320
  end
335
321
 
336
-
337
- def tag_method(name, el)
338
- "<% def #{name}(all_attributes={}, &__block__); " +
339
- "parameters = nil; " +
340
- tag_method_body(el) +
341
- "; end %>"
342
- end
343
-
344
-
345
- def tag_method_body(el, attributes_var="all_attributes", block_var="__block__")
322
+
323
+ def tag_method_body(el)
346
324
  attrs = declared_attributes(el)
347
325
 
348
326
  # A statement to assign values to local variables named after the tag's attrs
349
327
  # The trailing comma on `attributes` is supposed to be there!
350
- setup_locals = attrs.map{|a| "#{Hobo::Dryml.unreserve(a)}, "}.join + "attributes, = " +
351
- "_tag_locals(#{attributes_var}, #{attrs.inspect})"
328
+ setup_locals = attrs.map{|a| "#{Hobo::Dryml.unreserve(a).underscore}, "}.join + "attributes, = " +
329
+ "_tag_locals(all_attributes, #{attrs.inspect})"
352
330
 
353
- start = "_tag_context(#{attributes_var}, #{block_var}) do |tagbody| #{setup_locals}"
331
+ start = "_tag_context(all_attributes) do #{setup_locals}"
354
332
 
355
333
  "#{start} " +
356
334
  # reproduce any line breaks in the start-tag so that line numbers are preserved
@@ -359,38 +337,11 @@ module Hobo::Dryml
359
337
  "<% _erbout; end"
360
338
  end
361
339
 
362
-
363
- def tagbody_element(el)
364
- dryml_exception("tagbody can only appear inside a <def>", el) unless
365
- find_ancestor(el) {|e| e.name == 'def'}
366
- dryml_exception("tagbody cannot appear inside a part", el) if
367
- find_ancestor(el) {|e| e.attributes['part']}
368
- tagbody_call(el)
369
- end
370
-
371
-
372
- def tagbody_call(el)
373
- attributes = []
374
- with = el.attributes['with']
375
- field = el.attributes['field']
376
- attributes << ":with => #{attribute_to_ruby(with)}" if with
377
- attributes << ":field => #{attribute_to_ruby(field)}" if field
378
-
379
- default_body = if el.children.empty?
380
- "nil"
381
- else
382
- "proc { %>#{children_to_erb(el)}<% }"
383
- end
384
-
385
- call = apply_control_attributes("do_tagbody(tagbody, {#{attributes * ', '}}, #{default_body})", el)
386
- "<% _output(#{call}) %>"
387
- end
388
-
389
-
390
- def default_tagbody_element(el)
340
+
341
+ def param_content_element(el)
391
342
  name = el.attributes['for'] || @containing_tag_name
392
- local_name = default_tagbody_name(name)
393
- "<% #{local_name} && #{local_name}.call %>"
343
+ local_name = param_content_local_name(name)
344
+ "<%= #{local_name} && #{local_name}.call %>"
394
345
  end
395
346
 
396
347
 
@@ -398,8 +349,9 @@ module Hobo::Dryml
398
349
  require_attribute(el, "part", DRYML_NAME_RX)
399
350
  part_name = el.attributes['part']
400
351
  dom_id = el.attributes['id'] || part_name
352
+ part_name = ruby_name(part_name)
401
353
 
402
- part_locals = el.attributes["part_locals"]
354
+ part_locals = el.attributes["part-locals"]
403
355
 
404
356
  part_src = "<% def #{part_name}_part(#{part_locals._?.gsub('@', '')}) #{tag_newlines(el)}; new_context do %>" +
405
357
  content +
@@ -417,28 +369,23 @@ module Hobo::Dryml
417
369
 
418
370
  if param_name
419
371
  def_tag = find_ancestor(el) {|e| e.name == "def"}
420
- dryml_exception("param is not allowed outside of template definitions", el) if
421
- def_tag.nil? || !template_name?(def_tag.attributes["tag"])
372
+ dryml_exception("param is not allowed outside of tag definitions", el) if def_tag.nil?
373
+
374
+ ruby_name(param_name == "&true" ? el.dryml_name : param_name)
375
+ else
376
+ nil
422
377
  end
423
-
424
- res = param_name == "&true" ? el.dryml_name : param_name
425
-
426
- dryml_exception("param '#{res}' is for a template call must be capitalised", el) if
427
- res && template_call?(el) && !template_name?(res)
428
- dryml_exception("param '#{res}' is for a block-tag call and must not be capitalised", el) if
429
- res && !template_call?(el) && template_name?(res)
430
-
431
- res
432
378
  end
433
379
 
434
380
 
435
381
  def call_name(el)
436
- Hobo::Dryml.unreserve(el.dryml_name)
382
+ dryml_exception("invalid tag name", el) unless el.dryml_name =~ /^#{DRYML_NAME}(\.#{DRYML_NAME})*$/
383
+ Hobo::Dryml.unreserve(ruby_name(el.dryml_name))
437
384
  end
438
385
 
439
386
 
440
387
  def polymorphic_call_type(el)
441
- t = el.attributes['for_type']
388
+ t = el.attributes['for-type']
442
389
  if t.nil?
443
390
  nil
444
391
  elsif t == "&true"
@@ -450,42 +397,42 @@ module Hobo::Dryml
450
397
  elsif is_code_attribute?(t)
451
398
  t[1..-1]
452
399
  else
453
- dryml_exception("invalid for_type attribute", el)
400
+ dryml_exception("invalid for-type attribute", el)
454
401
  end
455
402
  end
456
403
 
457
404
 
458
- def template_call(el)
405
+ def tag_call(el)
459
406
  name = call_name(el)
460
407
  param_name = get_param_name(el)
461
408
  attributes = tag_attributes(el)
462
409
  newlines = tag_newlines(el)
463
410
 
464
- parameters = tag_newlines(el) + tag_parameters(el)
411
+ parameters = tag_newlines(el) + parameter_tags_hash(el)
465
412
 
466
- is_param_default_call = el.attributes['restore']
413
+ is_param_restore = el.attributes['restore']
467
414
 
468
415
  call = if param_name
469
416
  param_name = attribute_to_ruby(param_name, :symbolize => true)
470
- args = "#{attributes}, #{parameters}, all_parameters[#{param_name}]"
471
- to_call = if is_param_default_call
417
+ args = "#{attributes}, #{parameters}, all_parameters, #{param_name}"
418
+ to_call = if is_param_restore
472
419
  # The tag is available in a local variable
473
420
  # holding a proc
474
- name
421
+ param_restore_local_name(name)
475
422
  elsif (call_type = polymorphic_call_type(el))
476
- "find_polymorphic_template(:#{name}, #{call_type})"
423
+ "find_polymorphic_tag(:#{name.underscore}, #{call_type})"
477
424
  else
478
- ":#{name}"
425
+ ":#{name.underscore}"
479
426
  end
480
- "call_template_parameter(#{to_call}, #{args})"
427
+ "call_tag_parameter(#{to_call}, #{args})"
481
428
  else
482
- if is_param_default_call
429
+ if is_param_restore
483
430
  # The tag is a proc available in a local variable
484
- "#{default_parameter_name(name)}.call(#{attributes}, #{parameters})"
431
+ "#{param_restore_local_name(name)}.call(#{attributes}, #{parameters})"
485
432
  elsif (call_type = polymorphic_call_type(el))
486
- "send(find_polymorphic_template(:#{name}, #{call_type}), #{attributes}, #{parameters})"
433
+ "send(find_polymorphic_tag(:#{name.underscore}, #{call_type}), #{attributes}, #{parameters})"
487
434
  else
488
- "#{name}(#{attributes}, #{parameters})"
435
+ "#{name.underscore}(#{attributes}, #{parameters})"
489
436
  end
490
437
  end
491
438
 
@@ -501,41 +448,69 @@ module Hobo::Dryml
501
448
  end
502
449
 
503
450
 
504
- # Tag parameters are parameters to templates.
505
- def tag_parameters(el)
506
- dryml_exception("content is not allowed directly inside template calls", el) if
507
- el.children.find { |e| e.is_a?(REXML::Text) && !e.to_s.blank? }
508
-
451
+ def parameter_tags_hash(el)
452
+ call_type = nil
453
+
509
454
  param_items = el.map do |node|
510
455
  case node
511
456
  when REXML::Text
512
- # Just whitespace
457
+ text = node.to_s
458
+ if text.blank?
459
+ # include whitespace in hash literal to keep line numbers
460
+ # matching
461
+ text
462
+ else
463
+ case call_type
464
+ when nil
465
+ call_type = :default_param_only
466
+ text
467
+ when :default_param_only
468
+ text
469
+ when :named_params
470
+ dryml_exception("mixed content and parameter tags", el)
471
+ end
472
+ end
513
473
  node.to_s
514
474
  when REXML::Element
515
475
  e = node
516
- param_name = get_param_name(e)
517
- if param_name
518
- if template_call?(e)
519
- ":#{e.name} => merge_template_parameter(#{template_proc(e)}, all_parameters[:#{param_name}]), "
476
+ is_parameter_tag = e.parameter_tag?
477
+
478
+ # Make sure there isn't a mix of parameter tags and normal content
479
+ case call_type
480
+ when nil
481
+ call_type = is_parameter_tag ? :named_params : :default_param_only
482
+ when :named_params
483
+ dryml_exception("mixed parameter tags and non-parameter tags", el) unless is_parameter_tag
484
+ when :default_param_only
485
+ dryml_exception("mixed parameter tags and non-parameter tags", el) if is_parameter_tag
486
+ end
487
+
488
+ if is_parameter_tag
489
+ param_name = get_param_name(e)
490
+ if param_name
491
+ ":#{ruby_name e.name} => merge_tag_parameter(#{param_proc(e)}, all_parameters[:#{param_name}]), "
520
492
  else
521
- ":#{e.name} => merge_block_tag_parameter(#{template_proc(e)}, all_parameters[:#{param_name}]), "
493
+ ":#{ruby_name e.name} => #{param_proc(e)}, "
522
494
  end
523
- else
524
- ":#{e.name} => #{template_proc(e)}, "
525
495
  end
526
496
  end
527
497
  end.join
528
498
 
499
+ if call_type == :default_param_only
500
+ with_containing_tag_name(el) do
501
+ param_items = " :default => #{default_param_proc(el)}, "
502
+ end
503
+ end
529
504
 
530
- merge_params = el.attributes['merge_params'] || merge_attribute(el)
505
+ merge_params = el.attributes['merge-params'] || merge_attribute(el)
531
506
  if merge_params
532
507
  extra_params = if merge_params == "&true"
533
508
  "parameters"
534
- elsif is_code_attribute?(merge_params)
535
- merge_params[1..-1]
536
- else
537
- dryml_exception("invalid merge_params", el)
538
- end
509
+ elsif is_code_attribute?(merge_params)
510
+ merge_params[1..-1]
511
+ else
512
+ dryml_exception("invalid merge_params", el)
513
+ end
539
514
  "{#{param_items}}.merge((#{extra_params}) || {})"
540
515
  else
541
516
  "{#{param_items}}"
@@ -543,96 +518,46 @@ module Hobo::Dryml
543
518
  end
544
519
 
545
520
 
546
- def template_proc(el)
521
+ def default_param_proc(el)
522
+ "proc { |#{param_content_local_name(el.dryml_name)}| new_context { %>#{children_to_erb(el)}<% } #{tag_newlines(el)}}"
523
+ end
524
+
525
+
526
+ def param_restore_local_name(name)
527
+ "_#{name.underscore}_restore"
528
+ end
529
+
530
+
531
+ def param_proc(el)
532
+ param_name = el.dryml_name
547
533
  nl = tag_newlines(el)
534
+
548
535
  if (repl = el.attribute("replace"))
549
536
  dryml_exception("replace attribute must not have a value", el) if repl.has_rhs?
550
537
  dryml_exception("replace parameters must not have attributes", el) if el.attributes.length > 1
551
538
 
552
- "proc {|#{default_parameter_name(el.dryml_name)}| new_context { %>#{children_to_erb(el)}<% } #{nl}}"
539
+ "proc { |#{param_restore_local_name(param_name)}| new_context { %>#{children_to_erb(el)}<% } #{nl}}"
553
540
  else
554
541
  attributes = el.attributes.map do
555
- |name, value| ":#{name} => #{attribute_to_ruby(value, el)}" unless name.in?(SPECIAL_ATTRIBUTES)
542
+ |name, value| ":#{ruby_name name} => #{attribute_to_ruby(value, el)}" unless name.in?(SPECIAL_ATTRIBUTES)
556
543
  end.compact
557
-
558
- if template_call?(el || modifiers.first)
559
- parameters = el ? tag_parameters(el) : "{}"
560
- "proc { [{#{attributes * ', '}}, #{parameters}] #{nl}}"
561
- else
562
- if el && el.has_end_tag?
563
- old = @containing_tag_name
564
- @containing_tag_name = el.dryml_name
565
- body = children_to_erb(el)
566
- @containing_tag_name = old
567
-
568
- attributes << ":tagbody => proc {|#{default_tagbody_name(el.dryml_name)}| new_context { %>#{body}<% } } "
569
- end
570
- "proc { {#{attributes * ', '}} #{nl}}"
571
- end
544
+
545
+ nested_parameters_hash = parameter_tags_hash(el)
546
+ "proc { [{#{attributes * ', '}}, #{nested_parameters_hash}] #{nl}}"
572
547
  end
573
548
  end
574
549
 
575
550
 
576
- def default_parameter_name(name)
577
- "_#{name}__default"
551
+ def param_content_local_name(name)
552
+ "_#{name.underscore}__default_content"
578
553
  end
579
554
 
580
-
581
- def default_tagbody_name(name)
582
- "_#{name}_default_tagbody"
583
- end
584
-
585
-
586
- def tag_call(el)
587
- name = call_name(el)
588
- param_name = get_param_name(el)
589
- attributes = tag_attributes(el)
590
- newlines = tag_newlines(el)
591
-
592
- is_param_default_call = el.attributes['restore']
593
-
594
- call = if param_name
595
- to_call = if is_param_default_call
596
- # The tag is available in a local variable
597
- # holding a proc
598
- name
599
- elsif (call_type = polymorphic_call_type(el))
600
- "find_polymorphic_tag(:#{name}, #{call_type})"
601
- else
602
- ":#{name}"
603
- end
604
- param_name = attribute_to_ruby(param_name, :symbolize => true)
605
- "call_block_tag_parameter(#{to_call}, #{attributes}, all_parameters[#{param_name}])"
606
- else
607
- if is_param_default_call
608
- "#{default_parameter_name(name)}.call_with_block(#{attributes})"
609
- elsif (call_type = polymorphic_call_type(el))
610
- "send(find_polymorphic_tag(:#{name}, #{call_type}), #{attributes})"
611
- else
612
- "#{name}(#{attributes unless attributes == '{}'})"
613
- end
614
- end
615
-
616
- if el.children.empty?
617
- call = apply_control_attributes(call, el)
618
- maybe_make_part_call(el, "<%= #{call} #{newlines}%>")
619
- else
620
- old = @containing_tag_name
621
- @containing_tag_name = el.dryml_name
622
- children = children_to_erb(el)
623
- @containing_tag_name = old
624
555
 
625
- call_statement = "#{call} do |#{default_tagbody_name(el.dryml_name)}| #{newlines}%>#{children}<% end"
626
- call = "<% _output(" + apply_control_attributes(call_statement, el) + ") %>"
627
- maybe_make_part_call(el, call)
628
- end
629
- end
630
-
631
556
  def maybe_make_part_call(el, call)
632
557
  part_name = el.attributes['part']
633
558
  if part_name
634
559
  part_id = part_name && "<%= #{attribute_to_ruby(el.attributes['id'] || part_name)} %>"
635
- "<span class='part_wrapper' id='#{part_id}'>" + part_element(el, call) + "</span>"
560
+ "<span class='part-wrapper' id='#{part_id}'>" + part_element(el, call) + "</span>"
636
561
  else
637
562
  call
638
563
  end
@@ -642,22 +567,26 @@ module Hobo::Dryml
642
567
  def tag_attributes(el)
643
568
  attributes = el.attributes
644
569
  items = attributes.map do |n,v|
645
- ":#{n} => #{attribute_to_ruby(v)}" unless n.in?(SPECIAL_ATTRIBUTES)
570
+ dryml_exception("invalid attribute name '#{n}'", el) unless n =~ DRYML_NAME_RX
571
+
572
+ unless n.in?(SPECIAL_ATTRIBUTES)
573
+ ":#{ruby_name n} => #{attribute_to_ruby(v)}"
574
+ end
646
575
  end.compact
647
576
 
648
577
  # if there's a ':' el.name is just the part after the ':'
649
- items << ":field => \"#{el.name}\"" if el.name != el.expanded_name
578
+ items << ":field => \"#{el.name}\"" if el.name != el.dryml_name
650
579
 
651
580
  items = items.join(", ")
652
581
 
653
- merge_attrs = attributes['merge_attrs'] || merge_attribute(el)
582
+ merge_attrs = attributes['merge-attrs'] || merge_attribute(el)
654
583
  if merge_attrs
655
584
  extra_attributes = if merge_attrs == "&true"
656
585
  "attributes"
657
586
  elsif is_code_attribute?(merge_attrs)
658
587
  merge_attrs[1..-1]
659
588
  else
660
- dryml_exception("invalid merge_attrs", el)
589
+ dryml_exception("invalid merge-attrs", el)
661
590
  end
662
591
  "merge_attrs({#{items}},(#{extra_attributes}) || {})"
663
592
  else
@@ -670,7 +599,7 @@ module Hobo::Dryml
670
599
  attrs = el.attributes.map do |n, v|
671
600
  next if n.in? SPECIAL_ATTRIBUTES
672
601
  val = restore_erb_scriptlets(v).gsub('"', '\"').gsub(/<%=(.*?)%>/, '#{\1}')
673
- %(:#{n} => "#{val}")
602
+ %('#{n}' => "#{val}")
674
603
  end.compact
675
604
 
676
605
  # If there's a part but no id, the id defaults to the part name
@@ -679,9 +608,9 @@ module Hobo::Dryml
679
608
  end
680
609
 
681
610
  # Convert the attributes hash to a call to merge_attrs if
682
- # there's a merge_attrs attribute
683
- attrs = if (merge_attrs = el.attributes['merge_attrs'])
684
- dryml_exception("merge_attrs was given a string", el) unless is_code_attribute?(merge_attrs)
611
+ # there's a merge-attrs attribute
612
+ attrs = if (merge_attrs = el.attributes['merge-attrs'])
613
+ dryml_exception("merge-attrs was given a string", el) unless is_code_attribute?(merge_attrs)
685
614
 
686
615
  "merge_attrs({#{attrs * ', '}}, " +
687
616
  "((__merge_attrs__ = (#{merge_attrs[1..-1]})) == true ? attributes : __merge_attrs__))"
@@ -692,7 +621,7 @@ module Hobo::Dryml
692
621
  if el.children.empty?
693
622
  dryml_exception("part attribute on empty static tag", el) if part
694
623
 
695
- "<%= " + apply_control_attributes("tag(:#{el.name}, #{attrs} #{tag_newlines(el)})", el) + " %>"
624
+ "<%= " + apply_control_attributes("element(:#{el.name}, #{attrs} #{tag_newlines(el)})", el) + " %>"
696
625
  else
697
626
  if part
698
627
  body = part_element(el, children_to_erb(el))
@@ -700,14 +629,14 @@ module Hobo::Dryml
700
629
  body = children_to_erb(el)
701
630
  end
702
631
 
703
- output_tag = "tag(:#{el.name}, #{attrs}, true) + new_context { %>#{body}</#{el.name}><% }"
632
+ output_tag = "element(:#{el.name}, #{attrs}, new_context { %>#{body}<% })"
704
633
  "<% _output(" + apply_control_attributes(output_tag, el) + ") %>"
705
634
  end
706
635
  end
707
636
 
708
637
 
709
638
  def static_element_to_erb(el)
710
- if %w(part merge_attrs if unless repeat).any? {|x| el.attributes[x]}
639
+ if %w(part merge-attrs if unless repeat).any? {|x| el.attributes[x]}
711
640
  static_tag_to_method_call(el)
712
641
  else
713
642
  start_tag_src = el.start_tag_source.gsub(REXML::CData::START, "").gsub(REXML::CData::STOP, "")