hobo 0.8.5 → 0.8.6

Sign up to get free protection for your applications and to get access to all the features.
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>