hobo 0.7.0 → 0.7.1

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