hobo 0.7.0 → 0.7.1

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 (48) hide show
  1. data/hobo_files/plugin/CHANGES.txt +220 -23
  2. data/hobo_files/plugin/generators/hobo_front_controller/templates/index.dryml +18 -25
  3. data/hobo_files/plugin/generators/hobo_migration/hobo_migration_generator.rb +20 -15
  4. data/hobo_files/plugin/generators/hobo_model/templates/model.rb +3 -3
  5. data/hobo_files/plugin/generators/hobo_rapid/hobo_rapid_generator.rb +3 -3
  6. data/hobo_files/plugin/generators/hobo_rapid/templates/hobo-rapid.css +1 -2
  7. data/hobo_files/plugin/generators/hobo_rapid/templates/hobo-rapid.js +21 -4
  8. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/images/fieldbg.gif +0 -0
  9. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/images/spinner.gif +0 -0
  10. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/application.css +154 -26
  11. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/rapid-ui.css +144 -0
  12. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/views/application.dryml +1 -1
  13. data/hobo_files/plugin/generators/hobo_user_controller/templates/controller.rb +1 -1
  14. data/hobo_files/plugin/generators/hobo_user_model/templates/model.rb +8 -11
  15. data/hobo_files/plugin/init.rb +0 -2
  16. data/hobo_files/plugin/lib/active_record/has_many_association.rb +0 -9
  17. data/hobo_files/plugin/lib/active_record/has_many_through_association.rb +0 -10
  18. data/hobo_files/plugin/lib/hobo.rb +57 -44
  19. data/hobo_files/plugin/lib/hobo/bundle.rb +222 -0
  20. data/hobo_files/plugin/lib/hobo/controller.rb +2 -5
  21. data/hobo_files/plugin/lib/hobo/dryml.rb +8 -7
  22. data/hobo_files/plugin/lib/hobo/dryml/dryml_builder.rb +10 -21
  23. data/hobo_files/plugin/lib/hobo/dryml/taglib.rb +107 -80
  24. data/hobo_files/plugin/lib/hobo/dryml/template.rb +27 -20
  25. data/hobo_files/plugin/lib/hobo/enum_string.rb +1 -1
  26. data/hobo_files/plugin/lib/hobo/field_declaration_dsl.rb +7 -0
  27. data/hobo_files/plugin/lib/hobo/guest.rb +4 -0
  28. data/hobo_files/plugin/lib/hobo/hobo_helper.rb +37 -9
  29. data/hobo_files/plugin/lib/hobo/model.rb +79 -17
  30. data/hobo_files/plugin/lib/hobo/model_controller.rb +59 -60
  31. data/hobo_files/plugin/lib/hobo/model_router.rb +16 -4
  32. data/hobo_files/plugin/lib/hobo/rapid_helper.rb +2 -1
  33. data/hobo_files/plugin/lib/hobo/user.rb +10 -7
  34. data/hobo_files/plugin/lib/hobo/user_controller.rb +6 -6
  35. data/hobo_files/plugin/{tags → taglibs}/core.dryml +5 -4
  36. data/hobo_files/plugin/{tags → taglibs}/rapid.dryml +54 -7
  37. data/hobo_files/plugin/{tags → taglibs}/rapid_document_tags.dryml +0 -0
  38. data/hobo_files/plugin/{tags → taglibs}/rapid_editing.dryml +4 -2
  39. data/hobo_files/plugin/{tags → taglibs}/rapid_forms.dryml +1 -4
  40. data/hobo_files/plugin/{tags → taglibs}/rapid_navigation.dryml +1 -2
  41. data/hobo_files/plugin/taglibs/rapid_pages.dryml +411 -0
  42. data/hobo_files/plugin/{tags → taglibs}/rapid_plus.dryml +0 -0
  43. data/hobo_files/plugin/{tags → taglibs}/rapid_support.dryml +9 -6
  44. data/hobo_files/plugin/tasks/fix_dryml.rake +0 -1
  45. metadata +16 -14
  46. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/rapid_ui.css +0 -167
  47. data/hobo_files/plugin/lib/hobo/plugins.rb +0 -75
  48. data/hobo_files/plugin/tags/rapid_pages.dryml +0 -341
@@ -22,9 +22,9 @@ module Hobo
22
22
 
23
23
  def hobo_login(options={})
24
24
  options = LazyHash.new(options)
25
+ login_attr = model.login_attr.to_s.titleize.downcase
25
26
  options.reverse_merge!(:success_notice => "You have logged in.",
26
- :failure_notice => "You did not provide a valid #{model.login_attr.to_s.titleize.downcase} and password.",
27
- :disabled_notice => "You account is not currently available.")
27
+ :failure_notice => "You did not provide a valid #{login_attr} and password.")
28
28
 
29
29
  if request.post?
30
30
  user = model.authenticate(params[:login], params[:password])
@@ -39,7 +39,7 @@ module Hobo
39
39
  if block_given? && !yield
40
40
  # block returned false - cancel this login
41
41
  self.current_user = old_user
42
- flash[:notice] ||= options[:disabled_notice]
42
+ hobo_render(:account_disabled)
43
43
  else
44
44
  if params[:remember_me] == "1"
45
45
  current_user.remember_me
@@ -49,9 +49,9 @@ module Hobo
49
49
  redirect_back_or_default(options[:redirect_to] || home_page) unless performed?
50
50
  end
51
51
  end
52
- else
53
- hobo_render unless performed?
54
52
  end
53
+
54
+ hobo_render unless performed?
55
55
  end
56
56
 
57
57
 
@@ -79,7 +79,7 @@ module Hobo
79
79
 
80
80
 
81
81
  def hobo_logout(options={})
82
- options = options.reverse_merge(:notice => "You have been logged out.",
82
+ options = options.reverse_merge(:notice => "You have logged out.",
83
83
  :redirect_to => base_url)
84
84
 
85
85
  current_user.forget_me if logged_in?
@@ -1,5 +1,5 @@
1
1
  <def tag="call-tag" attrs="tag">
2
- <%= send(tag, attributes, parameters) %>
2
+ <%= send(tag.gsub('-', '_'), attributes, parameters) %>
3
3
  </def>
4
4
 
5
5
 
@@ -9,9 +9,10 @@
9
9
  </def>
10
10
 
11
11
 
12
- <def tag="partial" attrs="as">
13
- <%= render(:partial => find_partial(this, as), :locals => { :this => this }) %>
14
- </def>
12
+ <def tag="partial" attrs="name, locals"><%=
13
+ locals ||= {}
14
+ render(:partial => name, :locals => locals.merge(:this => this))
15
+ %></def>
15
16
 
16
17
 
17
18
  <def tag="repeat" attrs="even-odd, join"><%=
@@ -9,10 +9,10 @@
9
9
  <include src="rapid_plus"/>
10
10
 
11
11
  <def tag="field-list" attrs="tag">
12
- <% tag ||= scope.in_form ? "input" : "editor" %>
12
+ <% tag ||= scope.in_form ? "input" : "view" %>
13
13
  <labelled-item-list merge-attrs="&attributes - attrs_for(:with_fields)">
14
14
  <with-fields merge-attrs="&attributes & attrs_for(:with_fields)">
15
- <labelled-item>
15
+ <labelled-item unless="&tag == 'input' && !can_edit?">
16
16
  <item-label param="#{this_field.to_s.sub('?', '')}-label">
17
17
  <do param="label"><%= this_field.to_s.titleize %></do>
18
18
  </item-label>
@@ -103,8 +103,17 @@
103
103
 
104
104
 
105
105
  <def tag="card">
106
- <%= poly = call_polymorphic_tag('card', attributes) %>
107
- <div class="card" unless="&poly"><type-name/>: <a/></div>
106
+ <if test="&can_view?">
107
+ <%= poly = call_polymorphic_tag('card', attributes) %>
108
+ <div class="card #{linkable? ? 'linkable' : 'content'} #{type_name :dasherize => true}" unless="&poly">
109
+ <a if="&linkable?"/>
110
+ <div class="content" param="content">
111
+ <primary-content if="&!linkable?"/>
112
+ </div>
113
+ <creation-details/>
114
+ <span class="dependents"><count-dependents /></span>
115
+ </div>
116
+ </if>
108
117
  </def>
109
118
 
110
119
 
@@ -162,7 +171,7 @@
162
171
  end
163
172
  %></def>
164
173
 
165
- <def tag="type-name" attrs="type, plural, lowercase"><%=
174
+ <def tag="type-name" attrs="type, plural, lowercase, dasherize"><%=
166
175
  type ||= if this.is_a?(Class)
167
176
  this
168
177
  elsif this.respond_to? :proxy_reflection
@@ -170,7 +179,7 @@
170
179
  else
171
180
  this.class
172
181
  end
173
- name = type.name.titleize
182
+ name = dasherize ? type.name.underscore.dasherize : type.name.titleize
174
183
  name = name.pluralize if plural
175
184
  name = name.downcase if lowercase
176
185
  name
@@ -291,7 +300,7 @@
291
300
  %></def>
292
301
 
293
302
 
294
- <def tag="belongs-to-view"><a/></def>
303
+ <def tag="belongs-to-view"><a merge-attrs/></def>
295
304
 
296
305
  <def tag="has-many-view"><%= this.empty? ? "(none)" : map_this { a }.join(", ") %></def>
297
306
 
@@ -424,3 +433,41 @@ in the future - use at your own risk. -->
424
433
  <if test="&this == current_user">Your</if>
425
434
  <else><do param="default"><%= n = name; n.ends_with?('s') ? "#{n}'" : "#{n}'s" %></do></else>
426
435
  </def>
436
+
437
+
438
+ <def tag="creation-details">
439
+ <span class="creation-details">
440
+ <view with="&this.send(this.class.creator_attribute)" class="creator" if="&this.class.creator_attribute" />
441
+ <view:created_at class="created-at" if="&this.respond_to?(:created_at)"/>
442
+ </span>
443
+ </def>
444
+
445
+ <def tag="primary-content">
446
+ <view class="primary-content" field="&this.class.primary_content_attribute" if="&this.class.primary_content_attribute"/>
447
+ </def>
448
+
449
+ <def tag="live-search">
450
+ <div class="search">
451
+ <label for="search-field">Search</label><input type="search" id="search-field" name="search-field" class="search-bhv search"/>
452
+ <spinner id="search-spinner"/>
453
+ </div>
454
+ <section class="hidden" id="search-results-panel">
455
+ <h2>Search Results</h2>
456
+ <section id="search-results">&nbsp;</section>
457
+ </section>
458
+ </def>
459
+
460
+ <def tag="count-dependents">
461
+ <% assoc = this.class.dependent_collections.first if this.class.dependent_collections.length == 1 %>
462
+ <count field="&assoc" if="&assoc"/>
463
+ </def>
464
+
465
+
466
+ <def tag="a-or-an" attrs="word"><%=
467
+ (word =~ /^[aeiouh]/ ? "an " : "a ") + word
468
+ %></def>
469
+
470
+
471
+ <def tag="A-or-An" attrs="word"><%=
472
+ (word =~ /^[aeiouh]/ ? "An " : "A ") + word
473
+ %></def>
@@ -138,11 +138,13 @@
138
138
  </def>
139
139
 
140
140
 
141
- <def tag="boolean-checkbox-editor" attrs="update"><%
141
+ <def tag="boolean-checkbox-editor" attrs="update, message"><%
142
142
  raise HoboError.new("Not allowed to edit") unless can_edit?
143
143
  f = ajax_updater(object_url(this_parent),
144
- "Change #{this_field.to_s.titleize}", update,
144
+ message || "Change #{this_field.to_s.titleize}",
145
+ update,
145
146
  :method => "put",
147
+ :spinner_next_to => Hobo.raw_js("this"),
146
148
  :params => { this_parent.class.name.underscore => {
147
149
  this_field => Hobo.raw_js('this.checked')
148
150
  } })
@@ -157,9 +157,6 @@
157
157
  <%= text_field_tag(name, this, attributes) %>
158
158
  </def>
159
159
 
160
-
161
-
162
-
163
160
  <def tag="input" for="Hobo::EnumString" attrs="labels,titleize">
164
161
  <% labels ||= {} %>
165
162
  <% titleize = true if titleize.nil? %>
@@ -313,7 +310,7 @@
313
310
  <section class="error-messages" merge-attrs if="&this.errors.length > 0">
314
311
  <h2 param="heading">In order to proceed please correct the following:</h2>
315
312
  <ul:errors.full_messages param>
316
- <li param><%= this %></li>
313
+ <li: param><%= this %></li:>
317
314
  </ul>
318
315
  </section>
319
316
  </def>
@@ -92,7 +92,6 @@
92
92
  <def tag="magic-nav">
93
93
  <navigation merge-attrs>
94
94
  <nav-item href="#{base_url}/">Home</nav-item>
95
- <nav-item repeat="&Hobo.models.select{|m| [0..2]}"><name/></nav-item>
96
- <nav-item href="&search_url" if="&defined_route? :search">Search</nav-item>
95
+ <nav-item repeat="&front_models[0..5]"><name/></nav-item>
97
96
  </navigation>
98
97
  </def>
@@ -0,0 +1,411 @@
1
+ <def tag="base-page" attrs="title, doctype">
2
+ <% title ||= default_page_title %>
3
+ <doctype param version="&doctype || 'HTML 4.01 STRICT'"/>
4
+ <html>
5
+ <head param>
6
+ <title param><%= title.gsub(/<.*?>/, '') %></title>
7
+ <do param="stylesheets">
8
+ <stylesheet name="reset"/>
9
+ <stylesheet name="hobo-rapid"/>
10
+ <stylesheet name="application"/>
11
+ </do>
12
+
13
+ <do param="scripts">
14
+ <javascript param name="prototype, effects, dragdrop, controls, lowpro, hobo-rapid, application"/>
15
+ <hobo-rapid-javascripts param/>
16
+ </do>
17
+ </head>
18
+
19
+ <body onload="Hobo.applyEvents();" param/>
20
+ </html>
21
+ </def>
22
+
23
+ <def tag="simple-layout">
24
+ <base-page merge>
25
+ <body: param>
26
+ <ajax-progress/>
27
+ <header class="page-header" param>
28
+ <heading param="app-name"><a href="/#{base_url}"><app-name/></a></heading>
29
+ <live-search param/>
30
+ <nav param>
31
+ <account-nav if="&Hobo::UserController.user_models.first" param/>
32
+ <magic-nav class="main-nav" param="main-nav"/>
33
+ </nav>
34
+ </header>
35
+ <section class="page-content" param="content">
36
+ <header class="content-header" param="content-header"/>
37
+ <flash-message param/>
38
+ <section class="content-body" param="content-body"/>
39
+ <footer class="content-footer" param="content-footer"/>
40
+ </section>
41
+ <footer class="page-footer" param/>
42
+ </body:>
43
+ </base-page>
44
+ </def>
45
+
46
+
47
+ <def tag="aside-layout">
48
+ <simple-layout merge>
49
+ <body: class="aside-layout" param/>
50
+ <content: param>
51
+ <section class="main-content" param="main-content">
52
+ <param-content for="content"/>
53
+ </section>
54
+ <aside class="aside-content" param/>
55
+ </content:>
56
+ </simple-layout>
57
+ </def>
58
+
59
+
60
+ <def tag="default-layout" alias-of="simple-layout"/>
61
+
62
+
63
+ <def tag="page" attrs="layout"><% layout ||= "default" %><call-tag tag="#{layout}-layout" merge/></def>
64
+
65
+
66
+ <def tag="index-page" attrs="layout">
67
+ <% model_name = @model.name.titleize %>
68
+ <page layout="&layout" title="All #{model_name.pluralize}" merge>
69
+ <body: class="index-page #{@model.name.underscore}" param/>
70
+ <content-header: param>
71
+ <heading param><%= model_name.pluralize %></heading>
72
+ <p class="note" param>There <do with="&@model"><count part="item-count" prefix="are"/></do></p>
73
+ </content-header>
74
+
75
+ <content-body: param>
76
+ <nav param="top-pagination-nav"><page-nav/></nav>
77
+
78
+ <card repeat/>
79
+
80
+ <nav param="bottom-pagination-nav"><page-nav/></nav>
81
+ </content-body>
82
+
83
+ <content-footer: param>
84
+ <a to="&@model" action="new" param="new-link" if="&linkable?(@model, :new)"/>
85
+ <else>
86
+ <do with="&new_for_current_user @model">
87
+ <section class="create-new" if="&can_create?">
88
+ <h2>New <type-name/></h2>
89
+ <form><field-list/><submit label="Create #{type_name}"/></form>
90
+ </section>
91
+ </do>
92
+ </else>
93
+ </content-footer>
94
+ </page>
95
+ </def>
96
+
97
+
98
+ <def tag="new-page" attrs="layout">
99
+ <page layout="&layout" title="New #{type_name}" merge>
100
+ <body: class="new-page #{type_name.underscore}" param/>
101
+ <content-header: param>
102
+ <heading param>New <type-name title/></heading>
103
+ </content-header>
104
+
105
+ <content-body: param>
106
+ <error-messages param/>
107
+
108
+ <form param>
109
+ <field-list skip-associations="has_many" param/>
110
+ <div class="actions" param="actions">
111
+ <submit label="Create #{type_name}" param/><do param="back-link"> or <a>Cancel</a></do>
112
+ </div>
113
+ </form>
114
+ </content-body>
115
+ </page>
116
+ </def>
117
+
118
+
119
+ <def tag="show-page" attrs="layout">
120
+ <% has_many_assocs = this.class.reflections.values.map do |refl|
121
+ this.send(refl.name) if Hobo.simple_has_many_association?(refl)
122
+ end.compact
123
+ show_all_cards = this.class.dependent_collections.first if this.class.dependent_collections.length == 1
124
+ %>
125
+ <page layout="&layout" merge title="#{name :no_wrapper => true}">
126
+ <body: class="show-page #{type_name.underscore}" param/>
127
+ <content-header: param>
128
+ <if with="&this.dependent_on.reject{|x| x.is_a?(Hobo::User)}.first">
129
+ <div class="container"><a/></div>
130
+ </if>
131
+
132
+ <heading param><%= this %></heading>
133
+ <creation-details/>
134
+ <a class="dependent-collection-count" href="##{show_all_cards.to_s.underscore}" if="&show_all_cards"><count-dependents/></a>
135
+ <a action="edit" if="&can_edit?" class="edit">Edit <type-name/></a>
136
+ </content-header>
137
+
138
+ <content-body: param>
139
+ <primary-content param/>
140
+
141
+ <field-list skip="&[this.class.name_attribute, this.class.primary_content_attribute, this.class.creator_attribute, this.class.dependent_on.first].compact "
142
+ skip-associations="has_many" param/>
143
+
144
+ <if test="&show_all_cards">
145
+ <section class="dependent-collection" field="&show_all_cards">
146
+ <a name="#{show_all_cards.to_s.underscore}"/>
147
+ <h2><%= show_all_cards.to_s.titleize %></h2>
148
+ <do part="dependent-collection" part-locals="show_all_cards">
149
+ <ul><li:><card/></li:></ul>
150
+ <else>No <%= show_all_cards.to_s %> have been added yet.</else>
151
+ </do>
152
+
153
+ <do with="&new_for_current_user">
154
+ <section class="create-new" if="&!linkable?(:new) && can_create?">
155
+ <h2>Add <A-or-An word="&show_all_cards.to_s.singularize.titleize"/></h2>
156
+ <form update="dependent-collection" message="Adding #{show_all_cards.to_s.singularize.titleize}..." reset-form>
157
+ <field-list skip="#{@this.class.reverse_reflection(@this.send(show_all_cards).proxy_reflection.name).name}"
158
+ skip-associations="has_many" param/>
159
+ <submit label="Create #{show_all_cards.to_s.singularize.titleize}"/>
160
+ </form>
161
+ </section>
162
+ </do>
163
+ </section>
164
+ </if>
165
+ <else>
166
+ <section class="preview-collections">
167
+ <with-fields associations="has_many">
168
+ <section class="#{this_field.dasherize}">
169
+ <h2>Recent <this-field.titleize/></h2>
170
+ <card repeat="&this.recent.all"/>
171
+ <a class="more">More... (<count/>)</a>
172
+ </section>
173
+ </with-fields>
174
+ </section>
175
+ </else>
176
+
177
+ <nav class="new-links" param="new-links">
178
+ <ul with="&has_many_assocs">
179
+ <li: replace><li if="&can_create? && linkable?(:new)"><a action="new"/></li></li>
180
+ </ul>
181
+ </nav>
182
+
183
+ </content-body>
184
+ </page>
185
+ </def>
186
+
187
+
188
+ <def tag="edit-page" attrs="layout">
189
+ <page layout="&layout" merge>
190
+ <body: class="edit-page #{this.class.name.underscore}" param/>
191
+ <content-header: param>
192
+ <heading><if test="&this.respond_to? :name"><name/></if><else><type-name/></else></heading>
193
+ <delete-button in-place="&false" label="Remove This #{this.class.name}" param/>
194
+ </content-header>
195
+
196
+ <content-body: param>
197
+ <error-messages param/>
198
+ <form param>
199
+ <field-list skip-associations="has_many" param/>
200
+ <div class="actions" param="actions">
201
+ <submit label="Save Changes" param/><do param="back-link"> or <a>Cancel</a></do>
202
+ </div>
203
+ </form>
204
+
205
+ </content-body>
206
+ </page>
207
+ </def>
208
+
209
+
210
+ <def tag="new-in-collection-page" attrs="layout">
211
+ <set association-name="&@association.proxy_reflection.name.to_s.singularize.titleize"/>
212
+ <page layout="&layout" title="New #{type_name}" merge>
213
+ <body: class="new-in-collection-page #{type_name(:with => @owner)} #{type_name}" param/>
214
+ <content-header: param>
215
+ <heading param>New <association-name/></heading>
216
+ <sub-heading param>For: <a with="&@owner" /></sub-heading>
217
+ </content-header>
218
+
219
+ <content-body: param>
220
+ <error-messages/>
221
+
222
+ <form param>
223
+ <field-list skip="#{@owner.class.reverse_reflection(@association.proxy_reflection.name).name}"
224
+ skip-associations="has_many" param/>
225
+ <div class="actions" param="actions">
226
+ <submit label="Create #{association_name}" param/><do param="back-link"> or <a with="&@owner">Cancel</a></do>
227
+ </div>
228
+ </form>
229
+ </content-body>
230
+ </page>
231
+ </def>
232
+
233
+
234
+ <def tag="show-collection-page" attrs="layout">
235
+ <% title = "#{@reflection.name.to_s.titleize} for #{name(:with => @owner)}" %>
236
+ <page layout="&layout" title="&title" merge>
237
+ <body: class="show-collection-page #{type_name(:with => @owner)} #{type_name(:pluralize => true)}"
238
+ param/>
239
+ <content-header: param>
240
+ <nav>Back to <a with="&@owner"/></nav>
241
+ <heading><%= title %></heading>
242
+ <sub-heading><count with="&@pages.item_count" label="&@reflection.klass.name.titleize"/></sub-heading>
243
+ </content-header>
244
+
245
+ <content-body: param>
246
+ <nav param="top-pagination-nav"><page-nav/></nav>
247
+
248
+ <card repeat/>
249
+
250
+ <nav param="bottom-pagination-nav"><page-nav param/></nav>
251
+
252
+ <nav if="&Hobo.simple_has_many_association?(@association)" param="new-link">
253
+ <a to="&@association" action="new"/>
254
+ </nav>
255
+ </content-body>
256
+ </page>
257
+ </def>
258
+
259
+
260
+ <def tag="signup-page" attrs="layout">
261
+ <page layout="&layout" title="Sign up to #{app_name}" merge>
262
+ <body: class="signup-page" param/>
263
+
264
+ <live-search: replace/>
265
+ <nav: replace/>
266
+
267
+ <content-header: param>
268
+ <heading param>Sign Up</heading>
269
+ </content-header>
270
+
271
+ <content-body: param>
272
+ <error-messages/>
273
+ <form action="&request.request_uri" param>
274
+ <field-list fields="login, password, password_confirmation" param>
275
+ <password-confirmation-label:>Confirm Password</password-confirmation-label>
276
+ </field-list>
277
+
278
+ <submit label='Sign Up'/>
279
+ </form>
280
+ </content-body>
281
+
282
+ </page>
283
+ </def>
284
+
285
+
286
+ <def tag="login-page" attrs="remember-me, layout">
287
+ <page layout="&layout" title="Log in to #{app_name}" merge>
288
+
289
+ <body: class="login-page" param/>
290
+
291
+ <live-search: replace/>
292
+ <nav: replace/>
293
+
294
+ <content-header: param>
295
+ <heading param>Log In</heading>
296
+ </content-header>
297
+
298
+ <content-body: param>
299
+ <form action="&request.request_uri" class="login" param>
300
+ <labelled-item-list>
301
+ <labelled-item>
302
+ <item-label param="login-label"><%= model.login_attr.to_s.titleize %></item-label>
303
+ <item-value><input type="text" name="login" id="login" class="string" param="login-input" /></item-value>
304
+ </labelled-item>
305
+
306
+ <labelled-item>
307
+ <item-label param="password-label">Password</item-label>
308
+ <item-value><input type="password" name="password" id="password" class="string" param="password-input"/></item-value>
309
+ </labelled-item>
310
+
311
+ <labelled-item if="&remember_me">
312
+ <item-label class="field-label" param="remember-me-label">Remember me:</item-label>
313
+ <item-value><input type="checkbox" name="remember_me" id="remember-me" param="remember-me-input"/></item-value>
314
+ </labelled-item>
315
+ </labelled-item-list>
316
+ <submit label='Log in' param/>
317
+ </form>
318
+ </content-body>
319
+ </page>
320
+ </def>
321
+
322
+
323
+ <def tag="account-disabled-page" attrs="layout">
324
+
325
+ <page layout="&layout" title="#{app_name} - account not available" merge>
326
+
327
+ <body: class="account-disabled-page" param/>
328
+
329
+ <content-header: param><heading param>Account is not availble</heading></content>
330
+
331
+ <content-body: param>
332
+ <p>Your account is not available at this time.</p>
333
+ </content-body>
334
+ </page>
335
+
336
+ </def>
337
+
338
+
339
+
340
+ <def tag="permission-denied-page">
341
+ <page merge>
342
+ <content-header: param>
343
+ <heading param>That operation is not allowed</heading>
344
+ </content-header>
345
+ </page>
346
+ </def>
347
+
348
+ <def tag="not-found-page">
349
+ <page merge>
350
+ <content-header: param>
351
+ <heading param>The page you were looking for could not be found</heading>
352
+ </content-header>
353
+ </page>
354
+ </def>
355
+
356
+ <def tag="doctype" attrs="version"><%=
357
+ case version.upcase
358
+ when "HTML 4.01 STRICT"
359
+ '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" ' +
360
+ '"http://www.w3.org/TR/html4/strict.dtd">'
361
+ when "HTML 4.01 TRANSITIONAL"
362
+ '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" ' +
363
+ '"http://www.w3.org/TR/html4/loose.dtd">'
364
+ when "XHTML 1.0 STRICT"
365
+ '!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ' +
366
+ '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
367
+ when "XHTML 1.0 TRANSITIONAL"
368
+ '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ' +
369
+ '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
370
+ when "XHTML 1.1"
371
+ '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" ' +
372
+ '"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'
373
+ end
374
+ %></def>
375
+
376
+ <def tag="stylesheet" attrs="name, media">
377
+ <repeat with="&comma_split(name)">
378
+ <link href="#{base_url}/stylesheets/#{this}.css" media="#{ media || 'all' }"
379
+ rel="stylesheet" type="text/css" />
380
+ </repeat>
381
+ </def>
382
+
383
+ <def tag="javascript" attrs="name">
384
+ <if test="&name.is_a?(Symbol)">
385
+ <%= javascript_include_tag name %>
386
+ </if>
387
+ <else>
388
+ <repeat with="&comma_split(name)">
389
+ <%= javascript_include_tag this %>
390
+ </repeat>
391
+ </else>
392
+ </def>
393
+
394
+ <def tag="flash-message" attrs="type">
395
+ <% type = type ? type.to_sym : :notice %>
396
+ <div class="flash #{type}" if="&flash[type]" merge-attrs><%= flash[type] %></div>
397
+ </def>
398
+
399
+ <def tag="ajax-progress">
400
+ <div id="ajax-progress">
401
+ <div>
402
+ <span id="ajax-progress-text"></span>
403
+ </div>
404
+ </div>
405
+ </def>
406
+
407
+
408
+ <def tag="app-name"><%= @hobo_app_name ||= File.basename(Dir.chdir(RAILS_ROOT) { Dir.getwd }).strip.titleize %></def>
409
+
410
+ <def tag="default-page-title"><%= t = this.to_s; ; "#{t.blank? ? '' : t + ' - '}#{app_name}" %></def>
411
+