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
@@ -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>