hobo 0.6.4 → 0.7.0

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.
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
@@ -112,7 +112,7 @@ module Hobo
112
112
  options = options.reverse_merge(:limit => 15)
113
113
  options[:data_filters_block] = b
114
114
  @completers ||= HashWithIndifferentAccess.new
115
- @completers[attr.to_sym] = opts
115
+ @completers[attr.to_sym] = options
116
116
  end
117
117
 
118
118
 
@@ -130,12 +130,16 @@ module Hobo
130
130
  # Make sure we have a copy of the options - it is being mutated somewhere
131
131
  opts = {}.merge(options)
132
132
  @this = find_instance(opts) unless opts[:no_find]
133
- permission_denied unless Hobo.can_call?(current_user, @this, method)
134
- if got_block
133
+ set_status(Hobo.can_call?(current_user, @this, method) ? :valid : :not_allowed)
134
+ # TODO - block should get to handle permission denied?
135
+ if not_allowed?
136
+ permission_denied
137
+ elsif got_block
135
138
  instance_eval(&block)
136
139
  else
137
140
  @this.send(method)
138
141
  end
142
+
139
143
  hobo_ajax_response unless performed?
140
144
  end
141
145
  end
@@ -209,7 +213,7 @@ module Hobo
209
213
  else
210
214
  # Black list
211
215
  except = Array(@auto_actions[:except])
212
- name.not_in?(except) || (collection_action && :collections.not_in?(except))
216
+ return !(name.in?(except) || (collection_action && :collections.in?(except)))
213
217
  end
214
218
  end
215
219
 
@@ -507,7 +511,7 @@ module Hobo
507
511
  @this.send(:clear_association_cache)
508
512
 
509
513
  changes = params[model.name.underscore]
510
- @this.attributes = changes
514
+ @this.attributes = changes
511
515
  save_and_set_status!(@this, original)
512
516
 
513
517
  # Ensure current_user isn't out of date
@@ -523,7 +527,7 @@ module Hobo
523
527
  redirect_to(params[:after_submit] || object_url(@this))
524
528
  end
525
529
  wants.js do
526
- if changes.size == 1
530
+ if changes.size == 1 && params[:render]
527
531
  # Decreasingly hacky support for the scriptaculous in-place-editor
528
532
  new_val = Hobo::Dryml.render_tag(@template, "view",
529
533
  :with => @this, :field => changes.keys.first,
@@ -648,7 +652,7 @@ module Hobo
648
652
  def permission_denied(options={})
649
653
  if respond_to? :permission_denied_response
650
654
  permission_denied_response
651
- elsif render_tag("PermissionDeniedPage", { :with => @this }, :status => 403)
655
+ elsif render_tag("permission-denied-page", { :with => @this }, :status => 403)
652
656
  # cool
653
657
  else
654
658
  message = options[:message] || "Permission Denied"
@@ -660,7 +664,7 @@ module Hobo
660
664
  def not_found
661
665
  if respond_to? :not_found_response
662
666
  not_found_response
663
- elsif render_tag("NotFoundPage", { :with => @this }, :status => 404)
667
+ elsif render_tag("not-found-page", { :with => @this }, :status => 404)
664
668
  # cool
665
669
  else
666
670
  render(:text => "The page you requested cannot be found.", :status => 404)
@@ -680,7 +684,7 @@ module Hobo
680
684
  true
681
685
  else
682
686
  # This returns false if no such tag exists
683
- render_tag("#{page_kind.to_s.camelize}Page", :with => @this)
687
+ render_tag("#{page_kind.to_s.dasherize}-page", :with => @this)
684
688
  end
685
689
  rescue ActionView::TemplateError => wrapper
686
690
  e = wrapper.original_exception if wrapper.respond_to? :original_exception
@@ -2,10 +2,20 @@ module Hobo
2
2
 
3
3
  class ModelRouter
4
4
 
5
+ @linkable = Hash.new {|h, k| h[k] = Hash.new {|h, k| h[k] = {} } }
6
+
5
7
  APP_ROOT = "#{RAILS_ROOT}/app"
6
8
 
7
9
  class << self
8
10
 
11
+ def linkable(subsite, klass, action)
12
+ @linkable[subsite][klass.name][action] = true
13
+ end
14
+
15
+ def linkable?(subsite, klass, action)
16
+ @linkable[subsite][klass.name][action]
17
+ end
18
+
9
19
  def add_routes(map)
10
20
  begin
11
21
  ActiveRecord::Base.connection.reconnect! unless ActiveRecord::Base.connection.active?
@@ -17,6 +27,7 @@ module Hobo
17
27
  require "#{APP_ROOT}/controllers/application" unless Object.const_defined? :ApplicationController
18
28
  require "#{APP_ROOT}/assemble.rb" if File.exists? "#{APP_ROOT}/assemble.rb"
19
29
 
30
+ # Add non-subsite routes
20
31
  add_routes_for(map, nil)
21
32
 
22
33
  # Any directory inside app/controllers defines a subsite
@@ -88,15 +99,16 @@ module Hobo
88
99
  def resource_routes
89
100
  # We re-implement resource routing - routes are not created for
90
101
  # actions that the controller does not provide
91
- named_route(plural, plural, :action => "index", :conditions => { :method => :get })
102
+ linkable_route(plural, plural, :index, :conditions => { :method => :get })
92
103
 
93
- named_route("new_#{singular}", "#{plural}/new", :action => "new", :conditions => { :method => :get })
94
- named_route("edit_#{singular}", "#{plural}/:id/edit", :action => "edit", :conditions => { :method => :get })
95
- named_route(singular, "#{plural}/:id", :action => "show", :conditions => { :method => :get })
104
+ linkable_route("new_#{singular}", "#{plural}/new", :new, :conditions => { :method => :get })
105
+ linkable_route("edit_#{singular}", "#{plural}/:id/edit", :edit, :conditions => { :method => :get })
106
+
107
+ linkable_route(singular, "#{plural}/:id", :show, :conditions => { :method => :get })
96
108
 
97
- named_route("create_#{singular}", plural, :action => "create", :conditions => { :method => :post })
98
- named_route("update_#{singular}", "#{plural}/:id", :action => "update", :conditions => { :method => :put })
99
- named_route("destroy_#{singular}", "#{plural}/:id", :action => "destroy", :conditions => { :method => :delete })
109
+ linkable_route("create_#{singular}", plural, :create, :conditions => { :method => :post })
110
+ linkable_route("update_#{singular}", "#{plural}/:id", :update, :conditions => { :method => :put })
111
+ linkable_route("destroy_#{singular}", "#{plural}/:id", :destroy, :conditions => { :method => :delete })
100
112
  end
101
113
 
102
114
 
@@ -156,9 +168,17 @@ module Hobo
156
168
  map.named_route(name, route, options)
157
169
  format_route = options.delete(:format) != false
158
170
  map.named_route("formatted_#{name}", "#{route}.:format", options) if format_route
171
+ true
172
+ else
173
+ false
159
174
  end
160
175
  end
161
176
 
177
+
178
+ def linkable_route(name, route, action, options)
179
+ named_route(name, route, options.merge(:action => action.to_s)) and self.class.linkable(subsite, model, action)
180
+ end
181
+
162
182
 
163
183
  def name_with_subsite(name)
164
184
  subsite ? "#{subsite}_#{name}" : name
@@ -74,7 +74,6 @@ strong
74
74
  style
75
75
  sub
76
76
  sup
77
- table
78
77
  tbody
79
78
  td
80
79
  textarea
@@ -85,5 +84,4 @@ title
85
84
  tr
86
85
  tt
87
86
  u
88
- ul
89
87
  var
@@ -71,9 +71,9 @@ module Hobo
71
71
  u = find(:first, :conditions => ["#{@login_attr} = ?", login]) # need to get the salt
72
72
 
73
73
  if u && u.authenticated?(password)
74
- if u.respond_to?(:last_login_at) || u.respond_to?(:logins_count)
74
+ if u.respond_to?(:last_login_at) || u.respond_to?(:login_count)
75
75
  u.last_login_at = Time.now if u.respond_to?(:last_login_at)
76
- u.logins_count = (u.logins_count.to_i + 1) if u.respond_to?(:logins_count)
76
+ u.login_count = (u.login_count.to_i + 1) if u.respond_to?(:login_count)
77
77
  u.save
78
78
  end
79
79
  u
@@ -126,7 +126,7 @@ module Hobo
126
126
  # Before filter that encrypts the password before having it stored in the database.
127
127
  def encrypt_password
128
128
  return if password.blank?
129
- self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
129
+ self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if salt.blank?
130
130
  self.crypted_password = encrypt(password)
131
131
  end
132
132
 
@@ -34,9 +34,10 @@ module REXML
34
34
 
35
35
  class BaseParser
36
36
 
37
+ DRYML_NAME_STR= "#{NCNAME_STR}(?::(?:#{NCNAME_STR})?)?"
37
38
  DRYML_ATTRIBUTE_PATTERN = /\s*(#{NAME_STR})(?:\s*=\s*(["'])(.*?)\2)?/um
38
-
39
- DRYML_TAG_MATCH = /^<((?>#{NAME_STR}))\s*((?>\s+#{NAME_STR}(?:\s*=\s*(["']).*?\3)?)*)\s*(\/)?>/um
39
+ DRYML_TAG_MATCH = /^<((?>#{DRYML_NAME_STR}))\s*((?>\s+#{NAME_STR}(?:\s*=\s*(["']).*?\3)?)*)\s*(\/)?>/um
40
+ DRYML_CLOSE_MATCH = /^\s*<\/(#{DRYML_NAME_STR})\s*>/um
40
41
 
41
42
  attr_writer :dryml_mode
42
43
  def dryml_mode?
@@ -171,7 +172,7 @@ module REXML
171
172
  if @source.buffer[1] == ?/
172
173
  last_tag, line_no = @tags.pop
173
174
  #md = @source.match_to_consume('>', CLOSE_MATCH)
174
- md = @source.match(CLOSE_MATCH, true)
175
+ md = @source.match(dryml_mode? ? DRYML_CLOSE_MATCH : CLOSE_MATCH, true)
175
176
 
176
177
  valid_end_tag = if dryml_mode?
177
178
  last_tag =~ /^#{Regexp.escape(md[1])}(:.*)?/
@@ -339,6 +340,10 @@ module REXML
339
340
  @has_end_tag
340
341
  end
341
342
 
343
+ def parameter_tag?
344
+ expanded_name =~ /:$/
345
+ end
346
+
342
347
  end
343
348
 
344
349
  class Attribute
@@ -379,6 +384,8 @@ end
379
384
 
380
385
  module Hobo::Dryml
381
386
 
387
+
388
+ # A REXML source that keeps track of where in the buffer it is
382
389
  class RexSource < REXML::Source
383
390
 
384
391
  def initialize(src)
@@ -1,15 +1,10 @@
1
- <def tag="call_tag" attrs="tag">
2
- <%= send(tag, attributes, &tagbody) %>
3
- </def>
4
-
5
-
6
- <def tag="CallTemplate" attrs="template">
7
- <%= send(template, attributes, all_parameters) %>
1
+ <def tag="call-tag" attrs="tag">
2
+ <%= send(tag, attributes, parameters) %>
8
3
  </def>
9
4
 
10
5
 
11
6
  <def tag="wrap" attrs="tag, when">
12
- <% body = tagbody.call %>
7
+ <% body = parameters.default %>
13
8
  <%= when_ ? call_tag(tag, attributes, &proc { body }) : body %>
14
9
  </def>
15
10
 
@@ -19,18 +14,18 @@
19
14
  </def>
20
15
 
21
16
 
22
- <def tag="repeat" attrs="even_odd, join"><%=
17
+ <def tag="repeat" attrs="even-odd, join"><%=
23
18
  if !this.blank?
24
19
  if even_odd
25
20
  map_this do
26
21
  klass = [attributes[:class], cycle("even", "odd")].compact.join(' ')
27
- content_tag(even_odd, tagbody.call, attributes.merge(:class => klass, :hobo_model_id => dom_id(this)))
22
+ element(even_odd, attributes.merge(:class => klass, "hobo-model-id" => dom_id(this)), parameters.default)
28
23
  end.join(join)
29
24
  else
30
25
  scope.new_scope do
31
26
  scope[:even_odd] = "odd"
32
27
  map_this do
33
- res = tagbody.call
28
+ res = parameters.default
34
29
  scope.even_odd = scope.even_odd == "even" ? "odd" : "even"
35
30
  res
36
31
  end.join(join)
@@ -42,24 +37,24 @@
42
37
  %></def>
43
38
 
44
39
 
45
- <def tag="do"><tagbody/></def>
46
- <def tag="with"><tagbody/></def>
40
+ <def tag="do"><%= parameters.default %></def>
41
+ <def tag="with"><%= parameters.default %></def>
47
42
 
48
43
 
49
44
  <def tag="if" attrs="test"><%=
50
45
  test = all_attributes.fetch(:test, this)
51
- res = (cond = !test.blank?) ? tagbody.call : ""
46
+ res = (cond = !test.blank?) ? parameters.default : ""
52
47
  Hobo::Dryml.last_if = cond
53
48
  res
54
49
  %></def>
55
50
 
56
51
 
57
- <def tag="else"><tagbody unless="&Hobo::Dryml.last_if"/></def>
52
+ <def tag="else"><%= parameters.default unless Hobo::Dryml.last_if %></def>
58
53
 
59
54
 
60
55
  <def tag="unless" attrs="test"><%=
61
56
  test = all_attributes.fetch(:test, this)
62
- res = (cond = test.blank?) ? tagbody.call : ""
57
+ res = (cond = test.blank?) ? parameters.default : ""
63
58
  Hobo::Dryml.last_if = cond
64
59
  res
65
60
  %></def>
@@ -8,107 +8,124 @@
8
8
  <include src="rapid_navigation"/>
9
9
  <include src="rapid_plus"/>
10
10
 
11
- <def tag="FieldList" attrs="tag">
11
+ <def tag="field-list" attrs="tag">
12
12
  <% tag ||= scope.in_form ? "input" : "editor" %>
13
- <field_list merge_attrs="&attributes - attrs_for(:with_fields)">
14
- <with_fields merge_attrs="&attributes & attrs_for(:with_fields)">
15
- <field_list_item>
16
- <item_label param="#{this_field.to_s.sub('?', '')}_label">
13
+ <labelled-item-list merge-attrs="&attributes - attrs_for(:with_fields)">
14
+ <with-fields merge-attrs="&attributes & attrs_for(:with_fields)">
15
+ <labelled-item>
16
+ <item-label param="#{this_field.to_s.sub('?', '')}-label">
17
17
  <do param="label"><%= this_field.to_s.titleize %></do>
18
- </item_label>
19
- <item_value param="#{this_field.to_s.sub('?', '')}_view">
20
- <do param="view"><call_tag tag="&tag" param="#{this_field.to_s.sub('?', '')}_tag"/></do>
21
- </item_value>
22
- </field_list_item>
23
- </with_fields>
24
- </field_list>
18
+ </item-label>
19
+ <item-value param="#{this_field.to_s.sub('?', '')}-view">
20
+ <do param="view"><call-tag tag="&tag" param="#{this_field.to_s.sub('?', '')}-tag"/></do>
21
+ </item-value>
22
+ </labelled-item>
23
+ </with-fields>
24
+ </labelled-item-list>
25
25
  </def>
26
26
 
27
27
 
28
- <def tag="item"><% scope.items << tagbody.call %></def>
28
+ <def tag="item"><% scope.items << parameters.default %></def>
29
29
 
30
- <def tag="nil_view"><%= scope.nil_view || "(Not Available)" %></def>
30
+ <def tag="nil-view"><%= scope.nil_view || "(Not Available)" %></def>
31
31
 
32
- <def tag="UL">
33
- <ul merge_attrs unless="&this.empty?">
34
- <repeat>
35
- <li param if="&can_view?" class="#{scope.even_odd} #{this_type.name.underscore}"
36
- merge_attrs="&{:hobo_model_id => dom_id(this)} if this.respond_to?(:typed_id)">
37
- <tagbody><a/></tagbody>
38
- </li>
39
- </repeat>
40
- </ul>
32
+ <def tag="ul">
33
+ <% if all_parameters.li? # don't use dryml if, because it will mess up <ul/><else> %>
34
+ <unless test="&this.empty?">
35
+ <% element "ul", attributes do %>
36
+ <repeat>
37
+ <li param if="&can_view?" class="#{scope.even_odd} #{this_type.name.underscore.dasherize}"
38
+ merge-attrs="&{'hobo-model-id' => dom_id(this)} if this.respond_to?(:typed_id)">
39
+ <do param="default"><a/></do>
40
+ </li>
41
+ </repeat>
42
+ <% end %>
43
+ </unless>
44
+ <% else %>
45
+ <%= element("ul", attributes, all_parameters.default) %>
46
+ <% end %>
41
47
  </def>
42
48
 
43
49
 
44
- <def tag="Table" attrs="fields, field_tag, empty">
45
- <% field_tag ||= "view" %>
46
- <table merge_attrs="&attributes - attrs_for(:with_fields)" unless="&this.empty? && !empty">
47
- <thead if="&all_parameters[:thead] || fields" param>
48
- <tr param="field_heading_row">
49
- <with_field_names merge_attrs="&all_attributes & attrs_for(:with_fields)">
50
- <th param="#{scope.field_name}_heading"><%= scope.field_name.titleize %></th>
51
- </with_field_names>
52
- <th if="&all_parameters[:controls]" class="controls"/>
53
- </tr>
54
- </thead>
55
- <tbody>
56
- <repeat>
57
- <tr param if="&can_view?"
58
- class="#{scope.even_odd} #{this_type.name.underscore}"
59
- hobo_model_id="#{dom_id(this)}">
60
- <if test="&fields">
61
- <with_fields merge_attrs="&all_attributes & attrs_for(:with_fields)">
62
- <td param="#{this_field.to_s.sub('?', '').gsub('.', '_')}_view"><call_tag tag="&field_tag"/></td>
63
- </with_fields>
64
- <td class="controls" param="controls" if="&all_parameters[:controls]">
65
- <a param="edit_link">Edit</a>
66
- <delete_button param/>
67
- </td>
68
- </if>
50
+ <def tag="table" attrs="fields, field-tag, empty">
51
+ <if test="&!(fields || all_parameters.tr?)">
52
+ <%= element("table", attributes, all_parameters.default) %>
53
+ </if>
54
+ <else>
55
+ <% field_tag ||= "view" %>
56
+ <unless test="&this.empty? && !empty">
57
+ <% element "table", attributes - attrs_for(:with_fields) do %>
58
+ <thead if="&all_parameters[:thead] || fields" param>
59
+ <tr param="field-heading-row">
60
+ <with-field-names merge-attrs="&all_attributes & attrs_for(:with_fields)">
61
+ <th param="#{scope.field_name}-heading"><%= scope.field_name.titleize %></th>
62
+ </with-field-names>
63
+ <th if="&all_parameters[:controls]" class="controls"/>
69
64
  </tr>
70
- </repeat>
71
- </tbody>
72
- <tfoot if="&all_parameters[:tfoot]" param/>
73
- </table>
65
+ </thead>
66
+ <tbody>
67
+ <repeat>
68
+ <tr param if="&can_view?"
69
+ class="#{scope.even_odd} #{this_type.name.underscore}"
70
+ hobo-model-id="#{dom_id(this)}">
71
+ <if test="&fields">
72
+ <with-fields merge-attrs="&all_attributes & attrs_for(:with_fields)" force-all>
73
+ <td param="#{this_field.to_s.sub('?', '').gsub('.', '-')}-view"><call-tag tag="&field_tag"/></td>
74
+ </with-fields>
75
+ <td class="controls" param="controls" if="&all_parameters[:controls]">
76
+ <a param="edit-link">Edit</a>
77
+ <delete-button param/>
78
+ </td>
79
+ </if>
80
+ </tr>
81
+ </repeat>
82
+ </tbody>
83
+ <tfoot if="&all_parameters[:tfoot]" param/>
84
+ <% end %>
85
+ </unless>
86
+ </else>
74
87
  </def>
75
88
 
76
89
 
77
90
  <def tag="image" attrs="src">
78
- <img src="#{base_url}/images/#{src}" merge_attrs/>
91
+ <img src="#{base_url}/images/#{src}" merge-attrs/>
79
92
  </def>
80
93
 
81
94
 
82
95
  <def tag="spinner">
83
- <img src="#{base_url}/hobothemes/#{Hobo.current_theme}/images/spinner.gif" class="hidden" merge_attrs/>
96
+ <img src="#{base_url}/hobothemes/#{Hobo.current_theme}/images/spinner.gif" class="hidden" merge-attrs/>
84
97
  </def>
85
98
 
86
99
 
87
- <def tag="theme_image" attrs="src">
88
- <img src="#{theme_asset('images/' + src)}" merge_attrs/>
100
+ <def tag="theme-image" attrs="src">
101
+ <img src="#{theme_asset('images/' + src)}" merge-attrs/>
89
102
  </def>
90
103
 
91
104
 
92
105
  <def tag="card">
93
106
  <%= poly = call_polymorphic_tag('card', attributes) %>
94
- <div class="card" unless="&poly"><type_name/>: <a/></div>
107
+ <div class="card" unless="&poly"><type-name/>: <a/></div>
95
108
  </def>
96
109
 
97
110
 
98
- <def tag="hobo_rapid_javascripts" attrs="tiny_mce"><%=
99
- res = '<script type="text/javascript">var hoboParts = {};'
100
- unless Hobo.all_models.empty?
101
- # Tell JS code how to pluralize names, unless they follow the simple rule
102
- names = Hobo.all_models.map do |m|
103
- "#{m}: '#{m.pluralize}'" unless m.pluralize == m + 's'
104
- end.compact
105
- res += "var pluralisations = {#{names * ', '}}; "
106
- end
107
- base = [base_url, subsite].compact.join("/")
108
- res += "urlBase = '#{base}'; hoboPagePath = '#{view_name}'</script>"
109
-
110
- if tiny_mce
111
- res += javascript_include_tag("tiny_mce/tiny_mce_src") + %{
111
+ <def tag="hobo-rapid-javascripts" attrs="tiny-mce"><%=
112
+ res = '<script type="text/javascript">var hoboParts = {};'
113
+ unless Hobo.all_models.empty?
114
+ # Tell JS code how to pluralize names, unless they follow the simple rule
115
+ names = Hobo.all_models.map do |m|
116
+ "#{m}: '#{m.pluralize}'" unless m.pluralize == m + 's'
117
+ end.compact
118
+ res << "var pluralisations = {#{names * ', '}}; "
119
+ end
120
+ base = [base_url, subsite].compact.join("/")
121
+ res << "urlBase = '#{base}'; hoboPagePath = '#{view_name}'"
122
+ if request_forgery_protection_token
123
+ res << "; formAuthToken = { name: '#{request_forgery_protection_token}', value: '#{form_authenticity_token}' }"
124
+ end
125
+ res << "</script>"
126
+
127
+ if tiny_mce
128
+ res += javascript_include_tag("tiny_mce/tiny_mce_src") + %{
112
129
  <script type="text/javascript">
113
130
  tinyMCE.init({ mode: "textareas", editor_selector: "tiny_mce",
114
131
  plugins: 'save',
@@ -119,8 +136,8 @@
119
136
  theme_advanced_buttons3 : ""
120
137
  });
121
138
  </script>}
122
- end
123
- res
139
+ end
140
+ res
124
141
  %></def>
125
142
 
126
143
 
@@ -145,7 +162,7 @@
145
162
  end
146
163
  %></def>
147
164
 
148
- <def tag="type_name" attrs="type, plural, lowercase"><%=
165
+ <def tag="type-name" attrs="type, plural, lowercase"><%=
149
166
  type ||= if this.is_a?(Class)
150
167
  this
151
168
  elsif this.respond_to? :proxy_reflection
@@ -160,15 +177,15 @@
160
177
  %></def>
161
178
 
162
179
 
163
- <def tag="a" attrs="action, to, params, query_params, href, format, subsite"><%=
164
- content = tagbody.call if tagbody
180
+ <def tag="a" attrs="action, to, params, query-params, href, format, subsite"><%=
181
+ content = parameters.default
165
182
 
166
183
  params = self.query_params.merge(params || HashWithIndifferentAccess.new) if query_params
167
184
 
168
185
  if href || attributes[:name]
169
186
  # Regular link
170
187
  href += "?" + params.map { |n, v| "#{n}=#{v}" }.join('&') if params
171
- content_tag(:a, content, attributes.update(:href => href))
188
+ element(:a, attributes.update(:href => href), content)
172
189
  else
173
190
  target = to || this
174
191
 
@@ -188,9 +205,9 @@
188
205
  end
189
206
 
190
207
  href = object_url(target, "new", params._?.merge(:subsite => subsite))
191
- add_classes!(attributes, "new_#{new_class_name.underscore}_link")
208
+ add_classes!(attributes, "new-#{new_class_name.underscore}-link")
192
209
  content = "New #{new_class_name.titleize}" if content.blank?
193
- content_tag(:a, content, attributes.update(:href => href))
210
+ element(:a, attributes.update(:href => href), content)
194
211
  else
195
212
  Hobo::Dryml.last_if = false
196
213
  ""
@@ -203,20 +220,29 @@
203
220
  target = target.member_class
204
221
  end
205
222
 
206
- href = object_url(target, action, params._?.merge(:subsite => subsite))
207
- add_classes!(attributes, "#{target.class.name.underscore}_link")
223
+ content = name if content.blank?
208
224
 
209
- href.sub!(/\?|$/, ".#{format}\\0") unless format.blank?
225
+ # Do we want automatic disabling of links to thinks that are not
226
+ # linkable?
227
+ only_if_linkable = format.blank?
228
+ href = object_url(target, action, (params || {}).merge(:subsite => subsite, :if_available => only_if_linkable))
229
+ if href.nil?
230
+ # This target is registered with ModelRouter as not linkable
231
+ content
232
+ else
233
+ add_classes!(attributes, "#{target.class.name.underscore}-link")
210
234
 
211
- # Set default link text if none given
212
- content = name if content.blank?
213
- content_tag(:a, content, attributes.update(:href => href))
235
+ href.sub!(/\?|$/, ".#{format}\\0") unless format.blank?
236
+
237
+ # Set default link text if none given
238
+ element(:a, attributes.update(:href => href), content)
239
+ end
214
240
  end
215
241
  end
216
242
  %></def>
217
243
 
218
244
 
219
- <def tag="view" attrs="inline, block, if_blank, no_wrapper, truncate"><%=
245
+ <def tag="view" attrs="inline, block, if-blank, no-wrapper, truncate"><%=
220
246
  raise HoboError, "view of non-viewable field '#{this_field}' of #{this_parent.typed_id rescue this_parent}" unless
221
247
  can_view?
222
248
 
@@ -230,7 +256,7 @@
230
256
  end
231
257
  else
232
258
  attrs = add_classes(attributes, "view", type_id, type_and_field)
233
- attrs[:hobo_model_id] = this_field_dom_id if this_parent && this_parent.respond_to?(:typed_id)
259
+ attrs['hobo-model-id'] = this_field_dom_id if this_parent && this_parent.respond_to?(:typed_id)
234
260
 
235
261
  view_tag = find_polymorphic_tag("view")
236
262
 
@@ -256,7 +282,7 @@
256
282
  else
257
283
  :span
258
284
  end
259
- content_tag(wrapper, the_view, attrs - view_attrs)
285
+ element(wrapper, attrs - view_attrs, the_view)
260
286
  end
261
287
  end
262
288
  end
@@ -265,13 +291,13 @@
265
291
  %></def>
266
292
 
267
293
 
268
- <def tag="belongs_to_view"><a/></def>
294
+ <def tag="belongs-to-view"><a/></def>
269
295
 
270
- <def tag="has_many_view"><%= this.empty? ? "(none)" : map_this { a }.join(", ") %></def>
296
+ <def tag="has-many-view"><%= this.empty? ? "(none)" : map_this { a }.join(", ") %></def>
271
297
 
272
- <def tag="view" for="Date" attrs="format"><%= format ? this.strftime(format) : this.to_s(:long) %></def>
298
+ <def tag="view" for="Date" attrs="format"><%= this && (format ? this.strftime(format) : this.to_s(:long)) %></def>
273
299
 
274
- <def tag="view" for="Time" attrs="format"><%= format ? this.strftime(format) : this.to_s(:long) %></def>
300
+ <def tag="view" for="Time" attrs="format"><%= this && (format ? this.strftime(format) : this.to_s(:long)) %></def>
275
301
 
276
302
  <def tag="view" for="Numeric" attrs="format"><%= format ? format % this : this.to_s %></def>
277
303
 
@@ -289,8 +315,7 @@
289
315
 
290
316
  <def tag="view" for="TrueClass"><%= this ? 'Yes' : 'No' %></def>
291
317
 
292
- <def tag="count" attrs="label, prefix, unless_none, if_any"><%=
293
- if_any = unless_none if if_any.nil?
318
+ <def tag="count" attrs="label, prefix, if-any"><%=
294
319
  raise Exception.new("asked for count of a string") if this.is_a?(String)
295
320
 
296
321
  if this.is_a?(Class) and this < ActiveRecord::Base
@@ -307,8 +332,8 @@
307
332
  end
308
333
  end
309
334
 
310
- Hobo::Dryml.last_if = c > 0 if unless_none
311
- if unless_none && c == 0
335
+ Hobo::Dryml.last_if = c > 0 if if_any
336
+ if if_any && c == 0
312
337
  ""
313
338
  else
314
339
  main = label.blank? ? c : pluralize(c, label)
@@ -323,8 +348,9 @@
323
348
  %></def>
324
349
 
325
350
 
326
- <def tag="theme_stylesheet">
327
- <link href="<%= base_url %>/hobothemes/<%= Hobo.current_theme %>/stylesheets/application.css"
351
+ <def tag="theme-stylesheet" attrs="name">
352
+ <% name ||= 'application' -%>
353
+ <link href="<%= base_url %>/hobothemes/<%= Hobo.current_theme %>/stylesheets/<%= name %>.css"
328
354
  media="screen" rel="Stylesheet" type="text/css" />
329
355
  </def>
330
356
 
@@ -335,25 +361,25 @@
335
361
  <!-- The Tags defined below here are a bit rough and will be improved
336
362
  in the future - use at your own risk. -->
337
363
 
338
- <def tag="has_many_table" attrs="part_id, delete_buttons, headings, id">
339
- <table_for headings="&headings" merge_attrs="&true">
364
+ <def tag="has-many-table" attrs="part-id, delete-buttons, headings, id">
365
+ <table-for headings="&headings" merge-attrs="&true">
340
366
 
341
- <tagbody/>
367
+ <do param="default"/>
342
368
 
343
369
  <if test="&delete_buttons != false and can_delete?(this)">
344
- <td><DeleteButton/></td>
370
+ <td><delete-button/></td>
345
371
  </if>
346
- </table_for>
372
+ </table-for>
347
373
  <else>
348
374
  <p>There are no <%= this_type.klass.name.titleize.pluralize.downcase %></p>
349
375
  </else>
350
376
  <div>
351
- <CreateButton update="&id || part_id"/>
377
+ <create-button update="&id || part_id"/>
352
378
  </div>
353
379
  </def>
354
380
 
355
381
 
356
- <def tag="add_by_name" attrs="action_name, add_text, update, part_id">
382
+ <def tag="add-by-name" attrs="action-name, add-text, update, part-id">
357
383
  <% add_to = this
358
384
  refl = this_type
359
385
  joins = this_parent.send(refl.through_reflection.name)
@@ -363,13 +389,13 @@ in the future - use at your own risk. -->
363
389
  "enter its name"
364
390
  source = refl.source_reflection.name
365
391
  %>
366
- <tagbody with="&joins"/>
392
+ <do param="default" with="&joins"/>
367
393
  <with with="&joins.new_without_appending">
368
394
  <if test="can_create?">
369
- <form update="&[update, part_id]" message="&action_name" hidden_fields="*">
395
+ <form update="&[update, part_id]" message="&action_name" hidden-fields="*">
370
396
  <p>
371
397
  <%= add_text %>:
372
- <belongs_to_autocompleting_field field="&source" where_not_in="&dom_id(add_to)" class="autosubmit"/>
398
+ <belongs-to-autocompleting-field field="&source" where-not-in="&dom_id(add_to)" class="autosubmit"/>
373
399
  </p>
374
400
  </form>
375
401
  </if>
@@ -379,11 +405,22 @@ in the future - use at your own risk. -->
379
405
 
380
406
  <def tag="you" attrs="have, are">
381
407
  <if test="&this == current_user">you <%= if have then 'have' elsif are then 'are' end %></if>
382
- <else><tagbody><name/> <%= if have then 'has' elsif are then 'is' end %></tagbody></else>
408
+ <else><do param="default"><name/> <%= if have then 'has' elsif are then 'is' end %></do></else>
383
409
  </def>
384
410
 
385
411
 
386
412
  <def tag="You" attrs="have, are">
387
413
  <if test="&this == current_user">You <%= if have then 'have' elsif are then 'are' end %></if>
388
- <else><tagbody><name/> <%= if have then 'has' elsif are then 'is' end %></tagbody></else>
414
+ <else><do param="default"><name/> <%= if have then 'has' elsif are then 'is' end %></do></else>
415
+ </def>
416
+
417
+ <def tag="your">
418
+ <if test="&this == current_user">your</if>
419
+ <else><do param="default"><%= n = name; n.ends_with?('s') ? "#{n}'" : "#{n}'s" %></do></else>
420
+ </def>
421
+
422
+
423
+ <def tag="Your">
424
+ <if test="&this == current_user">Your</if>
425
+ <else><do param="default"><%= n = name; n.ends_with?('s') ? "#{n}'" : "#{n}'s" %></do></else>
389
426
  </def>