hobo 0.8.5 → 0.8.6

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 (68) hide show
  1. data/CHANGES.txt +41 -0
  2. data/Manifest +1 -5
  3. data/Rakefile +10 -3
  4. data/bin/hobo +38 -15
  5. data/dryml_generators/rapid/cards.dryml.erb +7 -7
  6. data/dryml_generators/rapid/pages.dryml.erb +52 -24
  7. data/hobo.gemspec +42 -322
  8. data/init.rb +0 -7
  9. data/lib/active_record/association_collection.rb +9 -0
  10. data/lib/hobo.rb +13 -14
  11. data/lib/hobo/accessible_associations.rb +32 -7
  12. data/lib/hobo/authentication_support.rb +1 -1
  13. data/lib/hobo/controller.rb +5 -7
  14. data/lib/hobo/dryml.rb +9 -2
  15. data/lib/hobo/dryml/dryml_builder.rb +11 -12
  16. data/lib/hobo/dryml/dryml_doc.rb +22 -24
  17. data/lib/hobo/dryml/dryml_generator.rb +41 -4
  18. data/lib/hobo/dryml/part_context.rb +5 -3
  19. data/lib/hobo/dryml/template.rb +7 -7
  20. data/lib/hobo/dryml/template_environment.rb +11 -22
  21. data/lib/hobo/dryml/template_handler.rb +94 -25
  22. data/lib/hobo/find_for.rb +2 -2
  23. data/lib/hobo/hobo_helper.rb +21 -21
  24. data/lib/hobo/include_in_save.rb +9 -5
  25. data/lib/hobo/lifecycles/transition.rb +2 -2
  26. data/lib/hobo/model.rb +11 -61
  27. data/lib/hobo/model_controller.rb +28 -29
  28. data/lib/hobo/model_router.rb +12 -13
  29. data/lib/hobo/permissions.rb +47 -37
  30. data/lib/hobo/permissions/associations.rb +1 -1
  31. data/lib/hobo/scopes/association_proxy_extensions.rb +5 -6
  32. data/lib/hobo/scopes/automatic_scopes.rb +7 -4
  33. data/lib/hobo/tasks/rails.rb +4 -0
  34. data/lib/hobo/user.rb +0 -1
  35. data/lib/hobo/user_controller.rb +3 -1
  36. data/lib/hobo/view_hints.rb +17 -3
  37. data/rails_generators/hobo/hobo_generator.rb +1 -0
  38. data/rails_generators/hobo_front_controller/templates/functional_test.rb +1 -11
  39. data/rails_generators/hobo_front_controller/templates/index.dryml +1 -6
  40. data/rails_generators/hobo_rapid/hobo_rapid_generator.rb +1 -0
  41. data/rails_generators/hobo_rapid/templates/hobo-rapid.css +3 -2
  42. data/rails_generators/hobo_rapid/templates/hobo-rapid.js +24 -15
  43. data/rails_generators/hobo_rapid/templates/themes/clean/public/stylesheets/clean.css +17 -12
  44. data/rails_generators/hobo_rapid/templates/themes/clean/public/stylesheets/rapid-ui.css +6 -2
  45. data/rails_generators/hobo_rapid/templates/themes/clean/views/clean.dryml +2 -2
  46. data/rails_generators/hobo_user_model/templates/forgot_password.erb +2 -2
  47. data/rails_generators/hobo_user_model/templates/model.rb +2 -2
  48. data/taglibs/rapid.dryml +3 -2
  49. data/taglibs/rapid_core.dryml +21 -16
  50. data/taglibs/rapid_document_tags.dryml +1 -1
  51. data/taglibs/rapid_editing.dryml +7 -10
  52. data/taglibs/rapid_forms.dryml +115 -26
  53. data/taglibs/rapid_generics.dryml +13 -3
  54. data/taglibs/rapid_lifecycles.dryml +18 -1
  55. data/taglibs/rapid_navigation.dryml +50 -61
  56. data/taglibs/rapid_pages.dryml +103 -19
  57. data/taglibs/rapid_plus.dryml +54 -6
  58. data/taglibs/rapid_support.dryml +38 -1
  59. data/taglibs/rapid_user_pages.dryml +17 -5
  60. data/test/permissions/models/models.rb +24 -12
  61. data/test/permissions/models/test.sqlite3 +0 -0
  62. metadata +6 -15
  63. data/lib/extensions/test_case.rb +0 -129
  64. data/lib/hobo/composite_model.rb +0 -73
  65. data/lib/hobo/model_support.rb +0 -44
  66. data/tasks/fix_dryml.rake +0 -143
  67. data/tasks/generate_tag_reference.rake +0 -192
  68. data/test/dryml/complilation_test.rb +0 -261
@@ -1,10 +1,22 @@
1
+ <!-- Contains view-layer support for Hobo's lifecycles. Note that lifecycle forms are generated automatically in `app/views/taglibs/auto/rapid/forms.dryml` - this library contains only lifecycle push-buttons. -->
2
+
3
+ <!-- A push-button to invoke a lifecycle transition either as a page-reload or as an ajax call.
4
+
5
+ ### Attributes
6
+
7
+ - `transition` - the name of the transition to invoke. Required
8
+ - `update` - one or more DOM IDs of ajax parts to update after the transition
9
+ - `label` - the label on the button. Defaults to the name of the transition
10
+
11
+ All of the [standard ajax attributes](/api_taglibs/rapid_forms) are also supported.
12
+ -->
1
13
  <def tag="transition-button" attrs="transition, update, label"><%=
2
14
  transition = transition.name unless transition.is_a?(String)
3
15
  ajax_attributes, html_attributes = attributes.partition_hash(Hobo::RapidHelper::AJAX_ATTRS)
4
16
 
5
17
  url = object_url(this, transition, :method => :put)
6
18
  add_classes!(html_attributes, "transition-button #{transition}-button")
7
- label ||= transition.titleize
19
+ label ||= transition.to_s.titleize
8
20
  if update || !ajax_attributes.empty?
9
21
  ajax_attributes[:message] ||= label
10
22
  func = ajax_updater(url, update, ajax_attributes)
@@ -16,6 +28,11 @@
16
28
  %>
17
29
  </def>
18
30
 
31
+
32
+ <!-- Renders a div containing transition buttons for every transition available to the current user.
33
+
34
+ For example, you could use this on a `Friendship` card: the person invited to have friendship would automatically see 'Accept' and 'Decline' buttons, while the person initiating the invite would see 'Retract'.
35
+ -->
19
36
  <def tag="transition-buttons">
20
37
  <div class="transitions">
21
38
  <% this.lifecycle.available_transitions_for(current_user).each do |t| %>
@@ -1,10 +1,32 @@
1
- <!-- Navigation
2
- Main nav bar, account nav bar (login, signup...), page nav
3
- -->
4
-
5
- <!--- General Navigation -->
6
-
7
- <!-- General purpose navigation bar. Renders a `<ul class="navigation">` -->
1
+ <!-- Support for navigation links, account navigation (log in, out etc.) and pagination navigation. -->
2
+
3
+ <!-- General purpose navigation bar. Renders a `<ul class="navigation">`. This tag is intended to be used in conunction with `<nav-item>`. The main feature of this pair of tags (over, say, just using a plain `<ul>` list), is that it's easy to have a 'current' CSS class added to the appropriate nav item (so you can highlight the page/section the user is)
4
+
5
+ The main navigation in the default hobo app is implemented with `<navigation>` but this tag is also appropriate for any sub-navigation.
6
+
7
+ ### Attributes
8
+
9
+ - `current` - the textual content of the nav item that should have the 'current' CSS class added (see example)
10
+
11
+ ### Example
12
+
13
+ The normal usage is to define your own navigation tag that calls `<navigation>`.
14
+
15
+ <def tag="sub-nav">
16
+ <navigation merge>
17
+ <nav-item>Red</nav-item>
18
+ <nav-item>Green</nav-item>
19
+ <nav-item>Blue</nav-item>
20
+ </navigation>
21
+ </def>
22
+
23
+ Then in your pages you can call the tag like this
24
+
25
+ - On the 'red' page: `<sub-nav current="red"/>`
26
+ - On the 'green' page: `<sub-nav current="green"/>`
27
+ - and so on.
28
+
29
+ -->
8
30
  <def tag="navigation" attrs="current">
9
31
  <ul class="navigation" merge-attrs>
10
32
  <set-scoped current-navigation="&current">
@@ -13,6 +35,8 @@
13
35
  </ul>
14
36
  </def>
15
37
 
38
+
39
+ <!-- Renders a single item in a `<navigation>` menu. See [`<navigation`>](/api_tag_defs/navigation). -->
16
40
  <def tag="nav-item">
17
41
  <% body = parameters.default
18
42
  body = h(this.to_s) if body.blank? -%>
@@ -23,76 +47,41 @@
23
47
  </def>
24
48
 
25
49
 
26
- <!--- Account Navigation (log in / out / signup) -->
50
+ <!-- Account Navigation (log in / out / signup)
51
+
52
+ When logged in, this renders:
53
+
54
+ - "Logged in as ..."
55
+ - Link to account page
56
+ - Log out link
57
+
58
+ When not logged in, renders:
59
+
60
+ - Log in link
61
+ - Sign up link
62
+
63
+ This is a simple tag - just look at the source if you need to know more detail.
27
64
 
65
+ -->
28
66
  <def tag="account-nav">
29
- <dev-user-changer/>
30
67
  <do with="&current_user">
31
68
  <ul class="navigation account-nav" param>
69
+ <li if="&RAILS_ENV == 'development'"><dev-user-changer/></li>
32
70
  <if test="&logged_in?">
33
71
  <li class='nav-item' param="logged-in-as"><a to="&current_user">Logged in as <name/></a></li>
34
72
  <li class='nav-item' param="account"><a action="account">Account</a></li>
35
73
  <li class='nav-item' param="log-out"><a href="&logout_url">Log out</a></li>
36
74
  </if>
37
75
  <else>
38
- <set user="&Hobo::User.default_user_model"/>
39
- <li class='nav-item' param="log-in"><a href="&login_url(user)">Log in</a></li>
40
- <li if="&signup_url(user)" class="nav-item" param="sign-up"><a href="&signup_url(user)">Sign up</a></li>
76
+ <li class='nav-item' param="log-in"><a href="&login_url">Log in</a></li>
77
+ <li if="&signup_url" class="nav-item" param="sign-up"><a href="&signup_url">Sign up</a></li>
41
78
  </else>
42
79
  </ul>
43
80
  </do>
44
81
  </def>
45
82
 
46
83
 
47
- <!--- Pagination Navigation -->
48
-
84
+ <!--- A simple wrapper around the `will_paginate` helper. All options to `will_paginate` are available as attributes -->
49
85
  <def tag="page-nav">
50
86
  <%= will_paginate this, attributes.symbolize_keys.reverse_merge(:inner_window => 2, :prev_label => "&laquo; Prev") %>
51
87
  </def>
52
-
53
-
54
- <def tag="page-n-of-count">
55
- Page <%= this.current_page %> of <%= this.page_count %>
56
- </def>
57
-
58
-
59
- <def tag="previous-page-link">
60
- <a if="&this.try.previous_page"
61
- href="&url_for(params.merge(:page => this.previous_page))">
62
- <do param="default">&laquo; Previous page</do>
63
- </a>
64
- </def>
65
-
66
-
67
- <def tag="next-page-link">
68
- <a if="&this.try.next_page"
69
- href="&url_for(params.merge(:page => this.next_page))">
70
- <do param="default">Next page &raqou;</do>
71
- </a>
72
- </def>
73
-
74
-
75
- <def tag="first-page-link">
76
- <a if="&this.try.current_page && this.current_page != 1"
77
- href="&url_for(params.merge(:page => 1))">
78
- <do param="default">&laquo; First page</do>
79
- </a>
80
- </def>
81
-
82
-
83
- <def tag="last-page-link">
84
- <a if="&this.try.current_page && this.current_page != this.page_count"
85
- href="&url_for(params.merge(:page => this.page_count))">
86
- <do param="default">Last page &raquo;</do>
87
- </a>
88
- </def>
89
-
90
-
91
- <def tag="dev-user-changer">
92
- <set user="&Hobo::User.default_user_model"/>
93
- <select-menu if="&user && RAILS_ENV == 'development'"
94
- first-option="Guest" options="&user.all(:limit => 10).*.login"
95
- onchange="location.href = '/dev/set_current_user?login=' + this.options[this.selectedIndex].value"
96
- selected="#{current_user.login}"
97
- class="dev-user-changer"/>
98
- </def>
@@ -1,17 +1,34 @@
1
+ <!-- Rapid-Pages provides tags for working with entire pages. It includes the main `<page>` tag which is the starting point for all pages in Rapid, various supporting tags for things such as stylesheet and javascript includes. Also defines the standard error pages for permission-denied and not-found.
2
+ -->
3
+
4
+ <!-- The basic page structure for all the pages in a Hobo Rapid application. Providing the doctype, page title, standard stylesheet javascript includes, the ajax progress spinner, default header with app-name, account navigation, main navigation, and live search, empty section for the page content, flash message (if any) and an empty page footer.
5
+
6
+ The easiest way to see what this tag does is to look at the source.
7
+
8
+ ### Attributes
9
+
10
+ - `title` - the page title, will have ": `<app-name>`" appended
11
+ - `full-title` - the full page title. Set this if you do not want the app name suffix.
12
+
13
+ -->
1
14
  <def tag="page" attrs="title, full-title">
2
15
  <% full_title ||= "#{title} : #{app_name}" %>
3
16
  <html merge-attrs>
4
17
  <head param>
5
18
  <title param><%= strip_tags full_title %></title>
6
19
  <do param="stylesheets">
20
+ <!-- note that this is probably overridden in your app/views/taglibs/themes/xxx/xxx.dryml -->
7
21
  <stylesheet name="reset, hobo-rapid"/>
8
- <theme-stylesheet/>
22
+ <theme-stylesheet />
9
23
  <stylesheet name="application" param="app-stylesheet"/>
10
24
  </do>
11
25
 
12
26
  <do param="scripts">
13
27
  <javascript param name="prototype, effects, dragdrop, controls, lowpro, hobo-rapid"/>
14
- <if-ie version="lt IE 7" param="fix-ie6"><javascript name="IE7"/></if-ie>
28
+ <if-ie version="lt IE 7" param="fix-ie6">
29
+ <javascript name="IE7"/>
30
+ <javascript name="ie7-recalc"/>
31
+ </if-ie>
15
32
  <do param="custom-scripts"/>
16
33
  <javascript param="application-javascript" name="application"/>
17
34
  </do>
@@ -21,9 +38,9 @@
21
38
  <set-scoped flash-rendered="&false">
22
39
  <ajax-progress param/>
23
40
  <header class="page-header" param>
41
+ <account-nav if="&login_url(Hobo::User.default_user_model)" param/>
24
42
  <h1 param="app-name"><a href="#{base_url}/"><app-name/></a></h1>
25
43
  <live-search param if="&defined_route? :site_search"/>
26
- <account-nav if="&login_url(Hobo::User.default_user_model)" param/>
27
44
  <main-nav current="&title" param/>
28
45
  </header>
29
46
  <section with-flash-messages param="content"/>
@@ -35,7 +52,7 @@
35
52
  </def>
36
53
 
37
54
 
38
-
55
+ <!-- Renderes dynamically generated JavaScript required by `hobo-rapid.js`, including the information required to perform automatic part updates -->
39
56
  <def tag="page-scripts">
40
57
  <script type="text/javascript" param="default">
41
58
  <hobo-rapid-javascripts/>
@@ -44,12 +61,22 @@
44
61
  </def>
45
62
 
46
63
 
64
+ <!-- nodoc. -->
47
65
  <def tag="index-page" polymorphic/>
66
+ <!-- nodoc. -->
48
67
  <def tag="new-page" polymorphic/>
68
+ <!-- nodoc. -->
49
69
  <def tag="show-page" polymorphic/>
70
+ <!-- nodoc. -->
50
71
  <def tag="edit-page" polymorphic/>
51
72
 
73
+ <!-- The page rendered by default in the case of a permission-denied error
74
+
75
+ ### Attributes
52
76
 
77
+ - `message` - The main message to display. Defaults to "That operation is not allowed"
78
+
79
+ -->
53
80
  <def tag="permission-denied-page" attrs="message">
54
81
  <% message ||= "That operation is not allowed" %>
55
82
  <page merge>
@@ -57,12 +84,25 @@
57
84
  <content: param>
58
85
  <header param="content-header">
59
86
  <h2 param="heading"><message/></h2>
87
+ <div class="debug" if="&Rails.env.development?">
88
+ <h3>Exception:</h3>
89
+ <pre><%= h @permission_error.pretty_inspect %></pre>
90
+ <h3>params:</h3>
91
+ <pre><%= h params.pretty_inspect %></pre>
92
+ </div>
60
93
  </header>
61
94
  </content:>
62
95
  </page>
63
96
  </def>
64
97
 
65
98
 
99
+ <!-- The page rendered by default in the case of a not-found error
100
+
101
+ ### Attributes
102
+
103
+ - `message` - The main message to display. Defaults to "The page you were looking for could not be found"
104
+
105
+ -->
66
106
  <def tag="not-found-page" attrs="message">
67
107
  <% message ||= "The page you were looking for could not be found" %>
68
108
  <page merge>
@@ -76,6 +116,20 @@
76
116
  </def>
77
117
 
78
118
 
119
+ <!-- Renders one of five HTML DOCTYPE declarations, according to the `version` attribute.
120
+
121
+ ### Attributes
122
+ - 'version' - the doctype version, must be one of:
123
+
124
+ - HTML 4.01 STRICT
125
+ - HTML 4.01 TRANSITIONAL
126
+ - XHTML 1.0 STRICT
127
+ - XHTML 1.0 TRANSITIONAL
128
+ - XHTML 1.1
129
+
130
+ See the source for the actual output
131
+
132
+ -->
79
133
  <def tag="doctype" attrs="version"><%=
80
134
  case version.upcase
81
135
  when "HTML 4.01 STRICT"
@@ -96,6 +150,13 @@
96
150
  end
97
151
  %></def>
98
152
 
153
+
154
+ <!-- Renders an `<html>` tag along with the DOCTYPE specified in the `doctype` attribute.
155
+
156
+ ### Attributes
157
+
158
+ - `doctype` - the version of the DOCTYPE required. See the `version` attribute to `<doctype>`
159
+ -->
99
160
  <def tag="html" attrs="doctype">
100
161
  <% doctype ||= 'XHTML 1.0 TRANSITIONAL' -%>
101
162
  <doctype version="&doctype"/>
@@ -106,27 +167,51 @@
106
167
  </def>
107
168
 
108
169
  <!-- empty tags should be written as <br> in HTML and <br /> in XHTML -->
170
+ <!-- nodoc. -->
109
171
  <def tag="empty-tag" attrs="tag-name"><%= element(tag_name, attributes, nil, true, true) %></def>
172
+ <!-- nodoc. -->
110
173
  <def tag="base"><empty-tag tag-name="base" merge/></def>
174
+ <!-- nodoc. -->
111
175
  <def tag="meta"><empty-tag tag-name="meta" merge/></def>
176
+ <!-- nodoc. -->
112
177
  <def tag="link"><empty-tag tag-name="link" merge/></def>
178
+ <!-- nodoc. -->
113
179
  <def tag="img"><empty-tag tag-name="img" merge/></def>
180
+ <!-- nodoc. -->
114
181
  <def tag="br"><empty-tag tag-name="br" merge/></def>
182
+ <!-- nodoc. -->
115
183
  <def tag="hr"><empty-tag tag-name="hr" merge/></def>
184
+ <!-- nodoc. -->
116
185
  <def tag="frame"><empty-tag tag-name="frame" merge/></def>
186
+ <!-- nodoc. -->
117
187
  <def tag="area"><empty-tag tag-name="area" merge/></def>
188
+ <!-- nodoc. -->
118
189
  <def tag="param"><empty-tag tag-name="param" merge/></def>
190
+ <!-- nodoc. -->
119
191
  <def tag="col"><empty-tag tag-name="col" merge/></def>
120
192
 
193
+
194
+ <!-- Renders a conditional comment in order to have some content ignored by all browsers other than Internet Explorer
195
+
196
+ ### Example
197
+
198
+
199
+ <if-ie version="lt IE 7"> ... </if-ie>
200
+
201
+ -->
121
202
  <def tag="if-ie" attrs="version">
122
203
  <%= "<!--[if #{version || 'IE'}]>" %><do param="default"/><%= "<![endif]-->" %>
123
204
  </def>
124
205
 
206
+ <!-- Simple wrapper for the `stylesheet_link_tag` helper. The `name` attribute can be a comma-separated list of stylesheet names.
207
+ -->
125
208
  <def tag="stylesheet" attrs="name">
126
209
  <%= stylesheet_link_tag *(comma_split(name) + [attributes]) %>
127
210
  </def>
128
211
 
129
212
 
213
+ <!-- Simple wrapper for the `javascript_include_tag` helper. The `name` attribute can be a comma-separated list of script file names.
214
+ -->
130
215
  <def tag="javascript" attrs="name">
131
216
  <if test="&name.is_a?(Symbol)">
132
217
  <%= javascript_include_tag name %>
@@ -139,36 +224,35 @@
139
224
  </def>
140
225
 
141
226
 
227
+ <!-- Renders a Rails flash message wrapped in a `<div>` tag
228
+
229
+ ### Attributes
230
+
231
+ - `type` - which flash message to display. Defaults to `:notice`
232
+
233
+ ### CSS Classes
234
+
235
+ The flash is output in a `<div class="flash notice">`, where `notice` is the `type` specified.
236
+
237
+ -->
142
238
  <def tag="flash-message" attrs="type">
143
239
  <% type = type ? type.to_sym : :notice -%>
144
240
  <div class="flash #{type}" if="&flash[type]" merge-attrs><%= flash[type] %></div>
145
241
  </def>
146
242
 
147
243
 
244
+ <!-- Renders `<flash-message>` for every flash type given in the `names` attribute (comma separated), or for all flash messages that have been set if `names` is not given -->
148
245
  <def tag="flash-messages" attrs="names"><%=
149
246
  scope.flash_rendered = true
150
247
  names = names.nil? ? flash.keys : comma_split(names)
151
248
  names.map { |name| flash_message :type => name }
152
249
  %></def>
153
250
 
251
+ <!-- Renders `<div id="ajax-progress"><div><span id="ajax-progress-text"></span></div></div>`. The theme will style this as an ajax progress 'spinner' -->
154
252
  <def tag="ajax-progress">
155
- <div id="ajax-progress">
253
+ <div id="ajax-progress" merge-attrs>
156
254
  <div>
157
255
  <span id="ajax-progress-text"></span>
158
256
  </div>
159
257
  </div>
160
258
  </def>
161
-
162
-
163
- <def tag="default-page-title"><%= t = this.to_s; ; "#{t.blank? ? '' : t + ' - '}#{app_name}" %></def>
164
-
165
-
166
- <def tag="with-primary-collection" attrs="name"><%
167
- ivar = "@#{this.class.name.underscore}_#{name}"
168
-
169
- if (collection = instance_variable_get(ivar))
170
- %><do with="&collection" param="default"/><%
171
- else
172
- %><do field="&name" param="default"/><%
173
- end
174
- %></def>
@@ -1,6 +1,15 @@
1
+ <!-- Tags that define higher level interactive 'widgets' -->
2
+
3
+ <!-- An enhanced version of Rapid's `<table>` that has support for column sorting, searching and pagination.
4
+
5
+ This tag calls `<table merge-params>`, so the parameters for `<table>` are also available.
6
+
7
+ An [worked example](/tutorials/agility#improve_the_project_page_with_a_searchable_sortable_table) of this tag is available in the [Agility Tutorial](/tutorials/agility)
8
+
9
+ -->
1
10
  <def tag="table-plus" attrs="sort-field, sort-direction, sort-columns" >
2
11
  <% sort_field ||= @sort_field; sort_direction ||= @sort_direction; sort_columns ||= {} %>
3
- <% sort_columns['this'] ||= this.member_class.name_attribute %>
12
+ <% sort_columns['this'] ||= this.member_class.try.name_attribute %>
4
13
  <div class="table-plus" merge-attrs="&attributes - attrs_for(:with_fields) - attrs_for(:table)">
5
14
  <div class="header" param="header">
6
15
  <div class="search">
@@ -41,15 +50,34 @@
41
50
  </def>
42
51
 
43
52
 
53
+ <!-- An enhanced version of Rapid's `<collection>` tag that supports drag-and-drop re-ordering.
54
+
55
+ Each item in the collection has a `<div class="ordering-handle" param="handle">` added, which can be used to drag the item up and down.
56
+
57
+ ### Attributes
58
+
59
+ - `sortable-options` - a hash of options to pass to the `sortable_elemnt` helper. Default are:
60
+
61
+ { :constraint => :vertical,
62
+ :overlap => :vertical,
63
+ :scroll => :window,
64
+ :handle => 'ordering-handle',
65
+ :complete => [visual_effect(:highlight, attributes[:id])] }
66
+
67
+ ### Controller support
68
+
69
+ This tag assumes the controller has a `reorder` action. This action is added automatically by Hobo's model-controller if the model declares `acts_as_list`. See also [Drag and Drop Reordering](/manual/controllers#drag_and_drop_reordering) in the [Controllers and Routing](/manual/controllers) chapter of the manual.
70
+ -->
44
71
  <def tag="sortable-collection" attrs="sortable-options"><%
45
72
  singular_name = this.member_class.name.underscore
46
73
  attributes[:id] ||= "#{singular_name}_ordering"
47
- reorder_url = send("reorder_#{singular_name.pluralize}_url")
74
+ route_method = subsite ? "#{subsite}_reorder_#{singular_name.pluralize}_url" : "reorder_#{singular_name.pluralize}_url"
75
+ reorder_url = send(route_method)
48
76
  %>
49
77
  <collection class="sortable" merge>
50
78
  <item: id="#{singular_name}_#{this.id}" param>
51
79
  <div class="ordering-handle" param="handle">&uarr;<br/>&darr;</div>
52
- <card param/>
80
+ <do param="default"><card param/></do>
53
81
  </item:>
54
82
  </collection>
55
83
  <%= if Hobo::Dryml.last_if
@@ -67,6 +95,7 @@
67
95
  </def>
68
96
 
69
97
 
98
+ <!-- Captures the common pattern of a list of "the first few" cards, along with a link to the rest. -->
70
99
  <def tag="preview-with-more" attrs="name">
71
100
  <% name ||= collection_name.pluralize -%>
72
101
  <section class="#{name.gsub(' ', '-').dasherize} preview-with-more" param="default">
@@ -77,12 +106,21 @@
77
106
  </def>
78
107
 
79
108
 
109
+ <!-- Renders a gravatar (see [gravatar.com](http://gravatar.com)) image in side a link to `this`. Requires `this` to have an `email_address` field. Normally called with a user record in context.
110
+
111
+ ### Attributes
112
+
113
+ - `size` - Size in pixels of the image. Defaults to 80.
114
+ - `rating` - The rating allowed. Defaults to 'g'. See [gravatar.com](http://gravatar.com) for information on ratings.
115
+
116
+ -->
80
117
  <def tag="gravatar" attrs="size, rating">
81
118
  <% size ||= 80; rating ||= 'g'; digest = Digest::MD5.hexdigest(this.email_address) -%>
82
119
  <a class="gravatar"><img class="gravatar" src="http://www.gravatar.com/avatar/#{digest}?s=#{size}&r=#{rating}" merge-attrs/></a>
83
120
  </def>
84
121
 
85
122
 
123
+ <!-- Provides an ajax-powered *find-as-you-type* live search field which is hooked up to Hobo's site-side search feature. At the moment this tag is not very flexible. It is not easy to use if for anything other than Hobo's site-wide search. -->
86
124
  <def tag="live-search">
87
125
  <div class="search">
88
126
  <label for="search-field">Search</label><input type="search" class="live-search"/>
@@ -94,12 +132,22 @@
94
132
  </section>
95
133
  </def>
96
134
 
135
+ <!-- A `<select>` menu intended to act as a filter for index pages.
136
+
137
+ See [Filtering stories by status](/tutorials/agility#filtering_stories_by_status) in the [Agility Tutorial](/tutorials/agility) for an example.
138
+
139
+ ### Attributes
97
140
 
98
- <def tag="filter-menu" attrs="param-name, options, no-filter">
141
+ - `param-name` - the name of the HTTP parameter to use for the filter
142
+ - `options` - an array of options for the menu.
143
+ - `no-filter` - The text of the first option which indicates no filter is in effect. Defaults to 'All'
144
+ -->
145
+ <def tag="filter-menu" attrs="param-name, options, no-filter, id">
99
146
  <% no_filter ||= "All" %>
100
- <form action="&request.request_uri" method="get" class="filter-menu">
147
+ <form action="&request.request_uri" method="get" class="filter-menu" merge-attrs="id">
101
148
  <div>
102
- <select-menu name="&param_name" options="&options" selected="&params[param_name.gsub('-', '_')]"
149
+ <% selected = options.detect {|o| o.to_s==params[param_name.gsub('-', '_')] } %>
150
+ <select-menu name="&param_name" options="&options" selected="&selected"
103
151
  first-option="&no_filter" merge-params/>
104
152
  </div>
105
153
  </form>