hobo 0.7.2 → 0.7.3
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.
- data/bin/hobo +24 -7
- data/hobo_files/plugin/CHANGES.txt +501 -0
- data/hobo_files/plugin/generators/hobo/hobo_generator.rb +8 -6
- data/hobo_files/plugin/generators/hobo/templates/application.dryml +3 -0
- data/hobo_files/plugin/generators/hobo/templates/dryml-support.js +132 -0
- data/hobo_files/plugin/generators/hobo_front_controller/hobo_front_controller_generator.rb +4 -5
- data/hobo_files/plugin/generators/hobo_model_resource/hobo_model_resource_generator.rb +75 -0
- data/hobo_files/plugin/generators/hobo_model_resource/templates/controller.rb +7 -0
- data/hobo_files/plugin/generators/hobo_model_resource/templates/functional_test.rb +8 -0
- data/hobo_files/plugin/generators/hobo_model_resource/templates/helper.rb +2 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/hobo-rapid.js +30 -11
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/application.css +149 -92
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/rapid-ui.css +0 -48
- data/hobo_files/plugin/init.rb +45 -13
- data/hobo_files/plugin/lib/action_view_extensions/base.rb +4 -3
- data/hobo_files/plugin/lib/active_record/association_proxy.rb +18 -0
- data/hobo_files/plugin/lib/active_record/association_reflection.rb +5 -0
- data/hobo_files/plugin/lib/active_record/has_many_association.rb +7 -11
- data/hobo_files/plugin/lib/active_record/has_many_through_association.rb +8 -0
- data/hobo_files/plugin/lib/extensions/test_case.rb +1 -1
- data/hobo_files/plugin/lib/hobo.rb +38 -60
- data/hobo_files/plugin/lib/hobo/authentication_support.rb +1 -1
- data/hobo_files/plugin/lib/hobo/bundle.rb +131 -34
- data/hobo_files/plugin/lib/hobo/composite_model.rb +1 -1
- data/hobo_files/plugin/lib/hobo/controller.rb +7 -8
- data/hobo_files/plugin/lib/hobo/dev_controller.rb +21 -0
- data/hobo_files/plugin/lib/hobo/dryml/dryml_builder.rb +14 -8
- data/hobo_files/plugin/lib/hobo/dryml/dryml_support_controller.rb +13 -0
- data/hobo_files/plugin/lib/hobo/dryml/taglib.rb +6 -7
- data/hobo_files/plugin/lib/hobo/dryml/template.rb +207 -73
- data/hobo_files/plugin/lib/hobo/dryml/template_environment.rb +67 -55
- data/hobo_files/plugin/lib/hobo/dryml/template_handler.rb +53 -3
- data/hobo_files/plugin/lib/hobo/hobo_helper.rb +75 -107
- data/hobo_files/plugin/lib/hobo/model.rb +236 -429
- data/hobo_files/plugin/lib/hobo/model_controller.rb +277 -437
- data/hobo_files/plugin/lib/hobo/model_router.rb +62 -29
- data/hobo_files/plugin/lib/hobo/rapid_helper.rb +48 -9
- data/hobo_files/plugin/lib/hobo/scopes.rb +98 -0
- data/hobo_files/plugin/lib/hobo/scopes/association_proxy_extensions.rb +31 -0
- data/hobo_files/plugin/lib/hobo/scopes/automatic_scopes.rb +282 -0
- data/hobo_files/plugin/lib/hobo/scopes/defined_scope_proxy_extender.rb +88 -0
- data/hobo_files/plugin/lib/hobo/scopes/scope_reflection.rb +18 -0
- data/hobo_files/plugin/lib/hobo/scopes/scoped_proxy.rb +59 -0
- data/hobo_files/plugin/lib/hobo/undefined.rb +2 -0
- data/hobo_files/plugin/lib/hobo/user.rb +31 -14
- data/hobo_files/plugin/lib/hobo/user_controller.rb +41 -27
- data/hobo_files/plugin/taglibs/core.dryml +9 -11
- data/hobo_files/plugin/taglibs/rapid.dryml +51 -108
- data/hobo_files/plugin/taglibs/rapid_editing.dryml +25 -25
- data/hobo_files/plugin/taglibs/rapid_forms.dryml +111 -79
- data/hobo_files/plugin/taglibs/rapid_generics.dryml +74 -0
- data/hobo_files/plugin/taglibs/rapid_navigation.dryml +23 -21
- data/hobo_files/plugin/taglibs/rapid_pages.dryml +83 -169
- data/hobo_files/plugin/taglibs/rapid_plus.dryml +16 -2
- data/hobo_files/plugin/taglibs/rapid_support.dryml +3 -3
- data/hobo_files/plugin/taglibs/rapid_user_pages.dryml +104 -0
- metadata +60 -55
- data/hobo_files/plugin/generators/hobo_migration/hobo_migration_generator.rb +0 -276
- data/hobo_files/plugin/generators/hobo_migration/templates/migration.rb +0 -9
- data/hobo_files/plugin/lib/active_record/table_definition.rb +0 -34
- data/hobo_files/plugin/lib/extensions.rb +0 -375
- data/hobo_files/plugin/lib/hobo/email_address.rb +0 -12
- data/hobo_files/plugin/lib/hobo/enum_string.rb +0 -50
- data/hobo_files/plugin/lib/hobo/field_declaration_dsl.rb +0 -43
- data/hobo_files/plugin/lib/hobo/field_spec.rb +0 -68
- data/hobo_files/plugin/lib/hobo/html_string.rb +0 -7
- data/hobo_files/plugin/lib/hobo/lazy_hash.rb +0 -40
- data/hobo_files/plugin/lib/hobo/markdown_string.rb +0 -11
- data/hobo_files/plugin/lib/hobo/migrations.rb +0 -12
- data/hobo_files/plugin/lib/hobo/model_queries.rb +0 -117
- data/hobo_files/plugin/lib/hobo/password_string.rb +0 -7
- data/hobo_files/plugin/lib/hobo/percentage.rb +0 -14
- data/hobo_files/plugin/lib/hobo/predicate_dispatch.rb +0 -78
- data/hobo_files/plugin/lib/hobo/proc_binding.rb +0 -32
- data/hobo_files/plugin/lib/hobo/text.rb +0 -3
- data/hobo_files/plugin/lib/hobo/textile_string.rb +0 -25
- data/hobo_files/plugin/lib/hobo/where_fragment.rb +0 -28
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
<include src="rapid_forms"/>
|
|
8
8
|
<include src="rapid_navigation"/>
|
|
9
9
|
<include src="rapid_plus"/>
|
|
10
|
+
<include src="rapid_generics"/>
|
|
11
|
+
|
|
10
12
|
|
|
11
13
|
<def tag="field-list" attrs="tag">
|
|
12
14
|
<% tag ||= scope.in_form ? "input" : "view" %>
|
|
@@ -73,7 +75,7 @@
|
|
|
73
75
|
<td param="#{this_field.to_s.sub('?', '').gsub('.', '-')}-view"><call-tag tag="&field_tag"/></td>
|
|
74
76
|
</with-fields>
|
|
75
77
|
<td class="controls" param="controls" if="&all_parameters[:controls]">
|
|
76
|
-
<a param="edit-link">Edit</a>
|
|
78
|
+
<a param="edit-link" action="edit">Edit</a>
|
|
77
79
|
<delete-button param/>
|
|
78
80
|
</td>
|
|
79
81
|
</if>
|
|
@@ -97,39 +99,9 @@
|
|
|
97
99
|
</def>
|
|
98
100
|
|
|
99
101
|
|
|
100
|
-
<def tag="theme-image" attrs="src">
|
|
101
|
-
<img src="#{theme_asset('images/' + src)}" merge-attrs/>
|
|
102
|
-
</def>
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
<def tag="card">
|
|
106
|
-
<if test="&can_view?">
|
|
107
|
-
<%= poly = call_polymorphic_tag('card', attributes, parameters) %>
|
|
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>
|
|
117
|
-
</def>
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
<def tag="collection">
|
|
121
|
-
<%= poly = call_polymorphic_tag('collection', attributes, parameters) %>
|
|
122
|
-
<ul class="collection" merge-attrs unless="&poly">
|
|
123
|
-
<li:><card param/></li:>
|
|
124
|
-
</ul>
|
|
125
|
-
<p class="empty-collection-message" if="&this.empty?" param="empty-message">
|
|
126
|
-
There are no <type-name plural/>
|
|
127
|
-
</p>
|
|
128
|
-
</def>
|
|
129
|
-
|
|
130
|
-
|
|
131
102
|
<def tag="hobo-rapid-javascripts" attrs="tiny-mce"><%=
|
|
132
103
|
res = '<script type="text/javascript">var hoboParts = {};'
|
|
104
|
+
# FIXME: This should interrogate the model-router - not the models
|
|
133
105
|
unless Hobo.all_models.empty?
|
|
134
106
|
# Tell JS code how to pluralize names, unless they follow the simple rule
|
|
135
107
|
names = Hobo.all_models.map do |m|
|
|
@@ -147,7 +119,7 @@
|
|
|
147
119
|
if tiny_mce
|
|
148
120
|
res += javascript_include_tag("tiny_mce/tiny_mce_src") + %{
|
|
149
121
|
<script type="text/javascript">
|
|
150
|
-
tinyMCE.init({ mode: "textareas", editor_selector: "
|
|
122
|
+
tinyMCE.init({ mode: "textareas", editor_selector: "tiny-mce",
|
|
151
123
|
plugins: 'save',
|
|
152
124
|
theme_advanced_buttons1 : "bold, italic, separator, " +
|
|
153
125
|
"bullist, outdent, indent, separator, " +
|
|
@@ -183,13 +155,8 @@
|
|
|
183
155
|
%></def>
|
|
184
156
|
|
|
185
157
|
<def tag="type-name" attrs="type, plural, lowercase, dasherize"><%=
|
|
186
|
-
type ||= if this.is_a?(Class)
|
|
187
|
-
|
|
188
|
-
elsif this.respond_to? :proxy_reflection
|
|
189
|
-
this.proxy_reflection.klass
|
|
190
|
-
else
|
|
191
|
-
this.class
|
|
192
|
-
end
|
|
158
|
+
type ||= (this if this.is_a?(Class)) || this.try.member_class || this.class
|
|
159
|
+
|
|
193
160
|
name = dasherize ? type.name.underscore.dasherize : type.name.titleize
|
|
194
161
|
name = name.pluralize if plural
|
|
195
162
|
name = name.downcase if lowercase
|
|
@@ -216,15 +183,15 @@
|
|
|
216
183
|
# Link to a new object form
|
|
217
184
|
new_record = target.new
|
|
218
185
|
new_record.set_creator(current_user)
|
|
219
|
-
|
|
220
|
-
|
|
186
|
+
href = object_url(target, "new", params._?.merge(:subsite => subsite))
|
|
187
|
+
|
|
188
|
+
if href && can_create?(new_record)
|
|
221
189
|
new_class_name = if target.respond_to?(:proxy_reflection)
|
|
222
190
|
target.proxy_reflection.klass.name
|
|
223
191
|
else
|
|
224
192
|
target.name
|
|
225
193
|
end
|
|
226
194
|
|
|
227
|
-
href = object_url(target, "new", params._?.merge(:subsite => subsite))
|
|
228
195
|
add_classes!(attributes, "new-#{new_class_name.underscore}-link")
|
|
229
196
|
content = "New #{new_class_name.titleize}" if content.blank?
|
|
230
197
|
element(:a, attributes.update(:href => href), content)
|
|
@@ -235,17 +202,9 @@
|
|
|
235
202
|
else
|
|
236
203
|
# Link to an existing object
|
|
237
204
|
|
|
238
|
-
if target.is_a?(Array) && !target.respond_to?(:proxy_reflection) && target.respond_to?(:member_class)
|
|
239
|
-
# Not much to go on here - last guess is that this is an index page
|
|
240
|
-
target = target.member_class
|
|
241
|
-
end
|
|
242
|
-
|
|
243
205
|
content = name if content.blank?
|
|
244
206
|
|
|
245
|
-
|
|
246
|
-
# linkable?
|
|
247
|
-
only_if_linkable = format.blank?
|
|
248
|
-
href = object_url(target, action, (params || {}).merge(:subsite => subsite, :if_available => only_if_linkable))
|
|
207
|
+
href = object_url(target, action, (params || {}).merge(:subsite => subsite))
|
|
249
208
|
if href.nil?
|
|
250
209
|
# This target is registered with ModelRouter as not linkable
|
|
251
210
|
content
|
|
@@ -268,21 +227,23 @@
|
|
|
268
227
|
|
|
269
228
|
res = if this.nil? && if_blank.nil?
|
|
270
229
|
this_type.is_a?(Class) && this_type <= String ? "" : nil_view
|
|
271
|
-
elsif
|
|
272
|
-
if
|
|
230
|
+
elsif refl = this_field_reflection
|
|
231
|
+
if refl.macro == :belongs_to
|
|
273
232
|
belongs_to_view(attributes)
|
|
274
|
-
elsif
|
|
233
|
+
elsif refl.macro == :has_many
|
|
275
234
|
has_many_view(attributes)
|
|
276
235
|
end
|
|
277
236
|
else
|
|
278
|
-
attrs = add_classes(attributes, "view", type_id, type_and_field)
|
|
279
|
-
attrs['hobo-model-id'] = this_field_dom_id if this_parent && this_parent.respond_to?(:typed_id)
|
|
280
237
|
|
|
281
238
|
view_tag = find_polymorphic_tag("view")
|
|
282
239
|
|
|
283
240
|
if view_tag == "view" # i.e. it didn't find a type specific tag
|
|
284
241
|
raise HoboError, "Cannot view: #{this.inspect} (field is #{this_field}, type is #{this.class})"
|
|
285
242
|
else
|
|
243
|
+
attrs = add_classes(attributes, "view", type_and_field)
|
|
244
|
+
id = dom_id
|
|
245
|
+
attrs['hobo-model-id'] = id unless id == "nil"
|
|
246
|
+
|
|
286
247
|
view_attrs = attrs_for(view_tag)
|
|
287
248
|
the_view = send(view_tag, attrs & view_attrs)
|
|
288
249
|
|
|
@@ -325,32 +286,29 @@
|
|
|
325
286
|
|
|
326
287
|
<def tag="view" for="html"><%= this %></def>
|
|
327
288
|
|
|
328
|
-
<def tag="view" for="
|
|
289
|
+
<def tag="view" for="markdown"><%= this.to_html %></def>
|
|
290
|
+
|
|
291
|
+
<def tag="view" for="textile"><%= this.to_html %></def>
|
|
329
292
|
|
|
330
|
-
<def tag="view" for="
|
|
293
|
+
<def tag="view" for="password">[password withheld]</def>
|
|
331
294
|
|
|
332
|
-
<def tag="view" for="
|
|
295
|
+
<def tag="view" for="string"><%= h(this).gsub("\n", "<br/>") %></def>
|
|
333
296
|
|
|
334
|
-
<def tag="view" for="
|
|
297
|
+
<def tag="view" for="boolean"><%= this ? 'Yes' : 'No' %></def>
|
|
335
298
|
|
|
336
|
-
<def tag="view" for="TrueClass"><%= this ? 'Yes' : 'No' %></def>
|
|
337
299
|
|
|
338
|
-
<def tag="count" attrs="label, prefix, if-any"><%=
|
|
300
|
+
<def tag="count" attrs="label, prefix, if-any, lowercase"><%=
|
|
339
301
|
raise Exception.new("asked for count of a string") if this.is_a?(String)
|
|
340
302
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
else
|
|
351
|
-
this.length
|
|
352
|
-
end
|
|
353
|
-
end
|
|
303
|
+
c = this.try.to_int || this.try.total_entries || this.try.count || this.try.length
|
|
304
|
+
|
|
305
|
+
label ||= if this.is_a?(Class)
|
|
306
|
+
this.name
|
|
307
|
+
else
|
|
308
|
+
(this.try.association_name || this.try.member_class._?.name)
|
|
309
|
+
end.to_s.singularize.titleize
|
|
310
|
+
|
|
311
|
+
label = label.downcase if lowercase
|
|
354
312
|
|
|
355
313
|
Hobo::Dryml.last_if = c > 0 if if_any
|
|
356
314
|
if if_any && c == 0
|
|
@@ -360,7 +318,7 @@
|
|
|
360
318
|
|
|
361
319
|
if prefix.in? %w(are is)
|
|
362
320
|
p = c == 1 ? "is" : "are"
|
|
363
|
-
p + ' ' + main
|
|
321
|
+
p + ' ' + main.to_s
|
|
364
322
|
else
|
|
365
323
|
main
|
|
366
324
|
end
|
|
@@ -370,14 +328,11 @@
|
|
|
370
328
|
|
|
371
329
|
<def tag="theme-stylesheet" attrs="name">
|
|
372
330
|
<% name ||= 'application' -%>
|
|
373
|
-
<link href="
|
|
331
|
+
<link href="#{base_url}/hobothemes/#{Hobo.current_theme}/stylesheets/#{name}.css"
|
|
374
332
|
media="screen" rel="Stylesheet" type="text/css" />
|
|
375
333
|
</def>
|
|
376
334
|
|
|
377
335
|
|
|
378
|
-
<def tag="clearer"><div class='clearer'> </div></def>
|
|
379
|
-
|
|
380
|
-
|
|
381
336
|
<!-- The Tags defined below here are a bit rough and will be improved
|
|
382
337
|
in the future - use at your own risk. -->
|
|
383
338
|
|
|
@@ -386,12 +341,12 @@ in the future - use at your own risk. -->
|
|
|
386
341
|
|
|
387
342
|
<do param="default"/>
|
|
388
343
|
|
|
389
|
-
<if test="&delete_buttons != false
|
|
344
|
+
<if test="&delete_buttons != false && can_delete?(this)">
|
|
390
345
|
<td><delete-button/></td>
|
|
391
346
|
</if>
|
|
392
347
|
</table-for>
|
|
393
348
|
<else>
|
|
394
|
-
<p>There are no <%=
|
|
349
|
+
<p>There are no <%= this.member_class.name.titleize.pluralize.downcase %></p>
|
|
395
350
|
</else>
|
|
396
351
|
<div>
|
|
397
352
|
<create-button update="&id || part_id"/>
|
|
@@ -423,16 +378,9 @@ in the future - use at your own risk. -->
|
|
|
423
378
|
</def>
|
|
424
379
|
|
|
425
380
|
|
|
426
|
-
<def tag="you" attrs="have, are">
|
|
427
|
-
<if test="&this == current_user">you <%= if have then 'have' elsif are then 'are' end %></if>
|
|
428
|
-
<else><do param="default"><name/> <%= if have then 'has' elsif are then 'is' end %></do></else>
|
|
429
|
-
</def>
|
|
381
|
+
<def tag="you" attrs="have, are, do, titleize"><if test="&this == current_user"><%= "#{titleize ? 'Y' : 'y'}ou #{'have' if have}#{'are' if are}#{'do' if do_}" %></if><else><do param="default"><name/> <%= "#{'has' if have}#{'is' if are}#{'does' if do_}" %></do></else></def>
|
|
430
382
|
|
|
431
|
-
|
|
432
|
-
<def tag="You" attrs="have, are">
|
|
433
|
-
<if test="&this == current_user">You <%= if have then 'have' elsif are then 'are' end %></if>
|
|
434
|
-
<else><do param="default"><name/> <%= if have then 'has' elsif are then 'is' end %></do></else>
|
|
435
|
-
</def>
|
|
383
|
+
<def tag="You"><you merge titleize/></def>
|
|
436
384
|
|
|
437
385
|
<def tag="your">
|
|
438
386
|
<if test="&this == current_user">your</if>
|
|
@@ -446,17 +394,6 @@ in the future - use at your own risk. -->
|
|
|
446
394
|
</def>
|
|
447
395
|
|
|
448
396
|
|
|
449
|
-
<def tag="creation-details">
|
|
450
|
-
<span class="creation-details">
|
|
451
|
-
<view with="&this.send(this.class.creator_attribute)" class="creator" if="&this.class.creator_attribute" />
|
|
452
|
-
<view:created_at class="created-at" if="&this.respond_to?(:created_at)"/>
|
|
453
|
-
</span>
|
|
454
|
-
</def>
|
|
455
|
-
|
|
456
|
-
<def tag="primary-content">
|
|
457
|
-
<view class="primary-content" field="&this.class.primary_content_attribute" if="&this.class.primary_content_attribute"/>
|
|
458
|
-
</def>
|
|
459
|
-
|
|
460
397
|
<def tag="live-search">
|
|
461
398
|
<div class="search">
|
|
462
399
|
<label for="search-field">Search</label><input type="search" id="search-field" name="search-field" class="search-bhv search"/>
|
|
@@ -468,11 +405,6 @@ in the future - use at your own risk. -->
|
|
|
468
405
|
</section>
|
|
469
406
|
</def>
|
|
470
407
|
|
|
471
|
-
<def tag="count-dependents">
|
|
472
|
-
<% assoc = this.class.dependent_collections.first if this.class.dependent_collections.length == 1 %>
|
|
473
|
-
<count field="&assoc" if="&assoc"/>
|
|
474
|
-
</def>
|
|
475
|
-
|
|
476
408
|
|
|
477
409
|
<def tag="a-or-an" attrs="word"><%=
|
|
478
410
|
(word =~ /^[aeiouh]/i ? "an " : "a ") + word
|
|
@@ -482,3 +414,14 @@ in the future - use at your own risk. -->
|
|
|
482
414
|
<def tag="A-or-An" attrs="word"><%=
|
|
483
415
|
(word =~ /^[aeiouh]/i ? "An " : "A ") + word
|
|
484
416
|
%></def>
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
<def tag="filter-menu" attrs="param-name, options, no-filter">
|
|
420
|
+
<form action="&request.request_uri" method="get" class="filter-menu">
|
|
421
|
+
<hidden-field name="filter-parameter" value="¶m_name"/>
|
|
422
|
+
<select-menu name="¶m_name" options="&options" selected="¶ms[param_name.gsub('-', '_')]" first-option="&no_filter" merge-params/>
|
|
423
|
+
</form>
|
|
424
|
+
</def>
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
<def tag="comma-list" attrs="separator"><%= this.join(separator || ", ") %></def>
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<def tag="editor" ><%=
|
|
2
2
|
if !can_edit?
|
|
3
3
|
view(attributes)
|
|
4
|
-
elsif
|
|
5
|
-
if
|
|
4
|
+
elsif (refl = this_field_reflection)
|
|
5
|
+
if refl.macro == :belongs_to
|
|
6
6
|
belongs_to_editor(attributes)
|
|
7
7
|
else
|
|
8
8
|
has_many_editor(attributes)
|
|
9
9
|
end
|
|
10
10
|
else
|
|
11
|
-
attrs = add_classes(attributes,
|
|
11
|
+
attrs = add_classes(attributes, type_id, type_and_field, "editor")
|
|
12
12
|
call_polymorphic_tag("editor", attrs) or
|
|
13
13
|
raise HoboError.new("<editor> not implemented for #{this.class.name}\##{this_field} " +
|
|
14
14
|
"(#{this.inspect}:#{this_type})")
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
<def tag="editor" for="big_integer"><%= in_place_editor "in_place_textfield_bhv", attributes %></def>
|
|
45
45
|
|
|
46
46
|
<def tag="editor" for="Hobo::EnumString">
|
|
47
|
-
<string-select-editor values="&this_type.values"/>
|
|
47
|
+
<string-select-editor values="&this_type.values" merge/>
|
|
48
48
|
</def>
|
|
49
49
|
|
|
50
50
|
|
|
@@ -56,31 +56,31 @@
|
|
|
56
56
|
else
|
|
57
57
|
completer_model = completer_model.constantize if completer_model.is_a? String
|
|
58
58
|
end
|
|
59
|
-
id ||=
|
|
59
|
+
id ||= dom_id + "_completer"
|
|
60
60
|
url = object_url(completer_model, "completions",
|
|
61
61
|
{ :for => completer_attr }.update(attributes.select_hash {|k,v| k.to_s.starts_with? "where_"}))
|
|
62
62
|
%>
|
|
63
63
|
<input type="text" name="#{name}" id="#{id}" class="autocomplete-bhv"
|
|
64
64
|
autocomplete-url="#{url}" value="#{value}"
|
|
65
65
|
merge-attrs/>
|
|
66
|
-
|
|
66
|
+
<div id="#{id}-completions" class="completions-popup" style="display:none"></div>
|
|
67
67
|
</def>
|
|
68
68
|
|
|
69
69
|
|
|
70
70
|
<def tag="belongs-to-menu-editor"><%
|
|
71
71
|
raise HoboError.new("Not allowed to edit") unless can_edit?
|
|
72
|
-
link_id = "#{
|
|
72
|
+
link_id = "#{dom_id}_editor" %>
|
|
73
73
|
<span id="#{link_id}" part="rapid-belongs-to-edit">
|
|
74
|
-
<% select_options =
|
|
74
|
+
<% select_options = this_field_reflection.klass.find(:all).select {|x| can_view?(x)}.map {|x|
|
|
75
75
|
[ name(:with => x, :no_wrapper => true), x.id ]
|
|
76
76
|
}
|
|
77
77
|
select_options.insert(0, ["(No #{this_type.name.to_s.titleize})", ""]) if this.nil?
|
|
78
|
-
link_id = "#{
|
|
78
|
+
link_id = "#{dom_id}_editor"
|
|
79
79
|
f = ajax_updater(object_url(this_parent),
|
|
80
|
-
|
|
80
|
+
[link_id],
|
|
81
81
|
:method => "put",
|
|
82
82
|
:params => { this_parent.class.name.underscore => {
|
|
83
|
-
|
|
83
|
+
this_field_reflection.primary_key_name => Hobo.raw_js('this.value')
|
|
84
84
|
} })
|
|
85
85
|
%>
|
|
86
86
|
<select onchange="#{f}">
|
|
@@ -94,9 +94,9 @@
|
|
|
94
94
|
<if-can-edit><%
|
|
95
95
|
return object_link unless can_edit?
|
|
96
96
|
|
|
97
|
-
id ||=
|
|
97
|
+
id ||= dom_id + "_completer"
|
|
98
98
|
f = ajax_updater(object_url(this_parent),
|
|
99
|
-
|
|
99
|
+
update,
|
|
100
100
|
:method => "put",
|
|
101
101
|
:params => { this_parent.class.name.underscore => {
|
|
102
102
|
this_field => Hobo.raw_js("$('#{id}').value")
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
|
|
126
126
|
values = comma_split(values)
|
|
127
127
|
f = ajax_updater(object_url(this_parent),
|
|
128
|
-
|
|
128
|
+
update,
|
|
129
129
|
:method => "put",
|
|
130
130
|
:params => { this_parent.class.name.underscore => {
|
|
131
131
|
this_field => Hobo.raw_js('this.value')
|
|
@@ -141,9 +141,9 @@
|
|
|
141
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
|
-
message || "Change #{this_field.to_s.titleize}",
|
|
145
144
|
update,
|
|
146
145
|
:method => "put",
|
|
146
|
+
:message => message,
|
|
147
147
|
:spinner_next_to => Hobo.raw_js("this"),
|
|
148
148
|
:params => { this_parent.class.name.underscore => {
|
|
149
149
|
this_field => Hobo.raw_js('this.checked')
|
|
@@ -159,11 +159,11 @@
|
|
|
159
159
|
<% base_class = this.class
|
|
160
160
|
base_class = base_class.superclass while base_class.superclass != ActiveRecord::Base
|
|
161
161
|
f = ajax_updater("#{base_url}/#{controller_for base_class}/#{this.id}",
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
162
|
+
update,
|
|
163
|
+
:method => "put",
|
|
164
|
+
:params => { base_class.name.underscore => {
|
|
165
|
+
"type" => Hobo.raw_js('this.value')
|
|
166
|
+
} })
|
|
167
167
|
%>
|
|
168
168
|
|
|
169
169
|
<select onchange="#{f}">
|
|
@@ -175,7 +175,7 @@
|
|
|
175
175
|
|
|
176
176
|
<def tag="integer-select-editor" attrs="min, max, update, nil-option, message">
|
|
177
177
|
<select class="number-editor-bhv" hobo-update="#{update}"
|
|
178
|
-
hobo-model-id="#{
|
|
178
|
+
hobo-model-id="#{dom_id}"
|
|
179
179
|
merge-attrs="&message ? attributes.merge(:hobo_message => message) : attributes">
|
|
180
180
|
<if test="&this.nil?"><option value=""><%= nil_option || "Choose a value" %></option></if>
|
|
181
181
|
<%= options_for_select((min.to_i..max.to_i).to_a, this) %>
|
|
@@ -197,17 +197,17 @@
|
|
|
197
197
|
if obj == nil
|
|
198
198
|
new = klass.new(fields)
|
|
199
199
|
permission = if can_create?(new)
|
|
200
|
-
message ||= "Setting #{new.class.name.titleize}"
|
|
201
200
|
class_name = new.class.name.underscore
|
|
202
|
-
|
|
203
|
-
|
|
201
|
+
ajax_options = { :message => message }
|
|
202
|
+
ajax_options[:params] = { class_name => fields } unless fields.empty?
|
|
203
|
+
checkbox_attrs[:onclick] = ajax_updater(object_url(new.class), update, ajax_options)
|
|
204
204
|
end
|
|
205
205
|
else
|
|
206
206
|
permission = if can_delete?(obj)
|
|
207
207
|
checkbox_attrs[:checked] = 'checked'
|
|
208
208
|
message ||= "Unsetting #{obj.class.name.titleize}"
|
|
209
209
|
class_name = obj.class.name.underscore
|
|
210
|
-
checkbox_attrs[:onclick] = ajax_updater(object_url(obj, "destroy"),
|
|
210
|
+
checkbox_attrs[:onclick] = ajax_updater(object_url(obj, "destroy"), update, {:message => message, :method => 'delete'})
|
|
211
211
|
end
|
|
212
212
|
end
|
|
213
213
|
element(:input, add_classes(attributes.merge(checkbox_attrs),
|
|
@@ -20,58 +20,73 @@
|
|
|
20
20
|
%></def>
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
<def tag="form" attrs="
|
|
23
|
+
<def tag="form" attrs="update, hidden-fields, action, method, web-method"><%=
|
|
24
24
|
ajax_attrs, html_attrs = attributes.partition_hash(Hobo::RapidHelper::AJAX_ATTRS)
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
new_record = this.try.new_record?
|
|
27
27
|
|
|
28
|
-
new_record = this.respond_to?(:new_record?) && this.new_record?
|
|
29
|
-
|
|
30
28
|
method = if method.nil?
|
|
31
29
|
(action || web_method || new_record) ? "post" : "put"
|
|
32
30
|
else
|
|
33
31
|
method.downcase
|
|
34
32
|
end
|
|
35
|
-
if method == "put"
|
|
36
|
-
http_method_hidden = hidden_field_tag("_method", "PUT")
|
|
37
|
-
html_attrs[:method] = "post"
|
|
38
|
-
else
|
|
39
|
-
html_attrs[:method] = method
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
if update || !ajax_attrs.empty?
|
|
43
|
-
message ||= "Creating #{this.class.name.titleize}" if new_record
|
|
44
|
-
# add an onsubmit to convert to an ajax form if `update` is given
|
|
45
|
-
function = ajax_updater(:post_form, message, update, ajax_attrs)
|
|
46
|
-
html_attrs[:onsubmit] = [html_attrs[:onsubmit], "#{function}; return false;"].compact.join("; ")
|
|
47
|
-
end
|
|
48
33
|
|
|
49
|
-
|
|
50
|
-
scope[:in_form] = true
|
|
51
|
-
with_form_context { parameters.default }
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
hiddens = hidden_fields(:fields => hidden_fields, :skip => field_names) if new_record
|
|
55
|
-
|
|
56
|
-
auth_token = if request_forgery_protection_token.nil?
|
|
57
|
-
''
|
|
58
|
-
else
|
|
59
|
-
element(:input, :type => "hidden",
|
|
60
|
-
:name => request_forgery_protection_token.to_s,
|
|
61
|
-
:value => form_authenticity_token)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
page_path_hidden = hidden_field_tag("page_path", view_name)
|
|
65
|
-
|
|
66
|
-
body = [http_method_hidden, page_path_hidden, auth_token, hiddens, body].join
|
|
34
|
+
html_attrs[:action] = action || object_url(this, web_method, :method => method)
|
|
67
35
|
|
|
68
|
-
if
|
|
69
|
-
|
|
36
|
+
if html_attrs[:action].nil? || (new_record && !this.user_can_create?(current_user))
|
|
37
|
+
Hobo::Dryml.last_if = false
|
|
38
|
+
""
|
|
70
39
|
else
|
|
71
|
-
|
|
40
|
+
if method == "put"
|
|
41
|
+
# browsers don't support put -- use post and add the Rails _method hack
|
|
42
|
+
http_method_hidden = hidden_field_tag("_method", "PUT")
|
|
43
|
+
html_attrs[:method] = "post"
|
|
44
|
+
else
|
|
45
|
+
html_attrs[:method] = method
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
if update || !ajax_attrs.empty?
|
|
49
|
+
# add an onsubmit to convert to an ajax form if `update` is given
|
|
50
|
+
function = ajax_updater(:post_form, update, ajax_attrs)
|
|
51
|
+
html_attrs[:onsubmit] = [html_attrs[:onsubmit], "#{function}; return false;"].compact.join("; ")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
body, field_names = scope.new_scope do
|
|
55
|
+
scope[:in_form] = true
|
|
56
|
+
with_form_context { parameters.default }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
hiddens = hidden_fields(:fields => hidden_fields, :skip => field_names) if new_record
|
|
60
|
+
|
|
61
|
+
auth_token = if request_forgery_protection_token.nil?
|
|
62
|
+
''
|
|
63
|
+
else
|
|
64
|
+
element(:input, :type => "hidden",
|
|
65
|
+
:name => request_forgery_protection_token.to_s,
|
|
66
|
+
:value => form_authenticity_token)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
page_path = if request.post? || request.put? && params[:page_path]
|
|
70
|
+
params[:page_path]
|
|
71
|
+
else
|
|
72
|
+
view_name.sub(Hobo::Dryml::EMPTY_PAGE, params[:action])
|
|
73
|
+
end
|
|
74
|
+
page_path_hidden = hidden_field_tag("page_path", page_path) unless method == "get"
|
|
75
|
+
|
|
76
|
+
body = [http_method_hidden, page_path_hidden, auth_token, hiddens, body].join
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
if action.nil? # don't add automatic css classes if the action was specified
|
|
80
|
+
if web_method
|
|
81
|
+
add_classes!(html_attrs, "#{type_id}_#{web_method}_form")
|
|
82
|
+
else
|
|
83
|
+
add_classes!(html_attrs, "#{'new_' if new_record}#{type_id}")
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
Hobo::Dryml.last_if = true
|
|
88
|
+
element("form", html_attrs, body)
|
|
72
89
|
end
|
|
73
|
-
|
|
74
|
-
element("form", html_attrs, body)
|
|
75
90
|
%></def>
|
|
76
91
|
|
|
77
92
|
|
|
@@ -89,19 +104,18 @@
|
|
|
89
104
|
elsif !can_edit?
|
|
90
105
|
view
|
|
91
106
|
else
|
|
92
|
-
attrs = add_classes(attributes, type_and_field)
|
|
93
|
-
the_input = if
|
|
94
|
-
if
|
|
107
|
+
attrs = add_classes(attributes, type_id, type_and_field)
|
|
108
|
+
the_input = if (refl = this_field_reflection)
|
|
109
|
+
if refl.macro == :belongs_to
|
|
95
110
|
belongs_to_input(attrs)
|
|
96
|
-
elsif
|
|
97
|
-
if
|
|
111
|
+
elsif refl.macro == :has_many
|
|
112
|
+
if refl.options[:through]
|
|
98
113
|
has_many_through_input(attrs)
|
|
99
114
|
else
|
|
100
115
|
has_many_input(attrs)
|
|
101
116
|
end
|
|
102
117
|
end
|
|
103
118
|
else
|
|
104
|
-
add_classes!(attrs, type_id)
|
|
105
119
|
attrs[:name] ||= param_name_for_this
|
|
106
120
|
the_input = call_polymorphic_tag('input', attrs) or
|
|
107
121
|
raise HoboError, ("No input tag for #{this_field}:#{this_type} (this=#{this.inspect})")
|
|
@@ -132,12 +146,12 @@
|
|
|
132
146
|
</def>
|
|
133
147
|
|
|
134
148
|
<def tag="input" for="date" attrs="order">
|
|
135
|
-
<% order = order.nil? ? [:year, :month, :day] : comma_split(order)
|
|
149
|
+
<% order = order.nil? ? [:year, :month, :day] : comma_split(order).*.to_sym -%>
|
|
136
150
|
<%= select_date(this || Time.now, attributes.merge(:prefix => param_name_for_this, :order => order)) %>
|
|
137
151
|
</def>
|
|
138
152
|
|
|
139
153
|
<def tag="input" for="datetime" attrs="order">
|
|
140
|
-
<% order = order.nil? ? [:year, :month, :day, :hour, :minute] : comma_split(order)
|
|
154
|
+
<% order = order.nil? ? [:year, :month, :day, :hour, :minute] : comma_split(order).*.to_sym -%>
|
|
141
155
|
<%= select_datetime(this || Time.now, attributes.merge(:prefix => param_name_for_this, :order => order)) %>
|
|
142
156
|
</def>
|
|
143
157
|
|
|
@@ -157,7 +171,7 @@
|
|
|
157
171
|
<%= text_field_tag(name, this, attributes) %>
|
|
158
172
|
</def>
|
|
159
173
|
|
|
160
|
-
<def tag="input" for="
|
|
174
|
+
<def tag="input" for="HoboFields::EnumString" attrs="labels,titleize">
|
|
161
175
|
<% labels ||= {} %>
|
|
162
176
|
<% titleize = true if titleize.nil? %>
|
|
163
177
|
<select name="#{param_name_for_this}" merge-attrs>
|
|
@@ -176,15 +190,15 @@
|
|
|
176
190
|
|
|
177
191
|
<!--- Buttons --->
|
|
178
192
|
|
|
179
|
-
<def tag="remote-method-button" attrs="method, update,
|
|
193
|
+
<def tag="remote-method-button" attrs="method, update, label"><%=
|
|
180
194
|
ajax_attributes, html_attributes = attributes.partition_hash(Hobo::RapidHelper::AJAX_ATTRS)
|
|
181
195
|
|
|
182
196
|
url = object_url(this, method)
|
|
183
197
|
add_classes!(html_attributes, "button remote-method-button #{method}-button")
|
|
184
|
-
if update || result_update
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
198
|
+
if update || result_update || !ajax_attrs.empty?
|
|
199
|
+
label ||= method.titleize
|
|
200
|
+
ajax_attributes[:message] ||= label
|
|
201
|
+
func = ajax_updater(url, update, ajax_attributes)
|
|
188
202
|
html_attributes.update(:onclick => "var e = this; " + func, :type =>'button', :value => label)
|
|
189
203
|
element(:input, html_attributes)
|
|
190
204
|
else
|
|
@@ -193,10 +207,10 @@
|
|
|
193
207
|
%></def>
|
|
194
208
|
|
|
195
209
|
|
|
196
|
-
<def tag="update-button" attrs="label,
|
|
210
|
+
<def tag="update-button" attrs="label, update, fields, params"><%=
|
|
197
211
|
raise HoboError.new("no update specified") unless update
|
|
198
|
-
message ||= label
|
|
199
|
-
func = ajax_updater(object_url(this),
|
|
212
|
+
ajax_attributes[:message] ||= label
|
|
213
|
+
func = ajax_updater(object_url(this), update,
|
|
200
214
|
:params => { this.class.name.underscore => fields }.merge(params || {}),
|
|
201
215
|
:method => :put)
|
|
202
216
|
element :input, add_classes(attributes.merge(:type =>'button', :onclick => func, :value => label),
|
|
@@ -204,8 +218,10 @@
|
|
|
204
218
|
</def>
|
|
205
219
|
|
|
206
220
|
|
|
207
|
-
<def tag="delete-button" attrs="label,
|
|
208
|
-
if
|
|
221
|
+
<def tag="delete-button" attrs="label, update, in-place, image, confirm, fade, subsite"><%=
|
|
222
|
+
in_place = false if in_place.nil? && this == @this
|
|
223
|
+
url = object_url(this, :method => :delete, :subsite => subsite)
|
|
224
|
+
if (Hobo::Dryml.last_if = url && can_delete?)
|
|
209
225
|
attributes = attributes.merge(if image
|
|
210
226
|
{ :type => "image", :src => "#{base_url}/images/#{image}" }
|
|
211
227
|
else
|
|
@@ -217,15 +233,17 @@
|
|
|
217
233
|
add_classes!(attributes,
|
|
218
234
|
image ? "image-button" : "button",
|
|
219
235
|
"delete-button delete-#{this.class.name.underscore.dasherize}-button")
|
|
220
|
-
url
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
236
|
+
if url
|
|
237
|
+
if in_place == false
|
|
238
|
+
attributes[:confirm] = confirm if confirm
|
|
239
|
+
attributes[:method] = :delete
|
|
240
|
+
button_to(label, url, attributes)
|
|
241
|
+
else
|
|
242
|
+
fade = true if fade.nil?
|
|
243
|
+
attributes[:value] = label
|
|
244
|
+
attributes[:onclick] = "Hobo.removeButton(this, '#{url}', #{js_updates(update)}, {fade:#{fade}, confirm: #{confirm.inspect}})"
|
|
245
|
+
element(:input, attributes)
|
|
246
|
+
end
|
|
229
247
|
end
|
|
230
248
|
else
|
|
231
249
|
""
|
|
@@ -233,14 +251,14 @@
|
|
|
233
251
|
%></def>
|
|
234
252
|
|
|
235
253
|
|
|
236
|
-
<def tag="create-button" attrs="model, update, label,
|
|
254
|
+
<def tag="create-button" attrs="model, update, label, fields, message"><%=
|
|
237
255
|
raise HoboError.new("no update specified") unless update
|
|
238
256
|
|
|
239
257
|
fields ||= {}
|
|
240
258
|
class_or_assoc = if model
|
|
241
259
|
model.is_a?(String) ? model.constantize : model
|
|
242
260
|
elsif Hobo.simple_has_many_association?(this)
|
|
243
|
-
fields[
|
|
261
|
+
fields[this_field_reflection.primary_key_name] = this.proxy_owner.id
|
|
244
262
|
this
|
|
245
263
|
else
|
|
246
264
|
raise HoboError.new("invalid context for <create-button>")
|
|
@@ -249,12 +267,12 @@
|
|
|
249
267
|
new.set_creator(current_user)
|
|
250
268
|
if can_create?(new)
|
|
251
269
|
label ||= "New #{new.class.name.titleize}"
|
|
252
|
-
message
|
|
270
|
+
ajax_attributes = { :message => message }
|
|
271
|
+
ajax_attributes[:params] = { class_name => fields } unless fields.empty?
|
|
253
272
|
class_name = new.class.name.underscore
|
|
254
|
-
func = ajax_updater(object_url(new.class), message, update,
|
|
255
|
-
({:params => { class_name => fields }} unless fields.empty?))
|
|
273
|
+
func = ajax_updater(object_url(new.class), message, update, ajax_attributes)
|
|
256
274
|
element :input, add_classes(attributes.merge(:type =>'button', :onclick => func, :value => label),
|
|
257
|
-
|
|
275
|
+
"button create-button create-#{class_name}-button")
|
|
258
276
|
end
|
|
259
277
|
%></def>
|
|
260
278
|
|
|
@@ -263,8 +281,9 @@
|
|
|
263
281
|
raise HoboError.new("Not allowed to edit") unless can_edit?
|
|
264
282
|
|
|
265
283
|
blank_message ||= "(No #{this_type.name.to_s.titleize})"
|
|
266
|
-
|
|
267
|
-
|
|
284
|
+
conditions = ActiveRecord::Associations::BelongsToAssociation.new(this, this_field_reflection).conditions
|
|
285
|
+
options ||= this_field_reflection.klass.find(:all, :conditions => conditions).select {|x| can_view?(x)}
|
|
286
|
+
#Todo: switch to autocompleter for id_name when too many records, and id_name supported
|
|
268
287
|
select_options = options.map { |x|
|
|
269
288
|
[ name(:with => x, :no_wrapper => true), x.id ]
|
|
270
289
|
}.sort
|
|
@@ -281,7 +300,7 @@
|
|
|
281
300
|
<% refl = this_type
|
|
282
301
|
completer_model ||= refl.klass
|
|
283
302
|
completer_attr ||= refl.klass.id_name_column
|
|
284
|
-
id ||=
|
|
303
|
+
id ||= dom_id + "_completer"
|
|
285
304
|
where_attributes = attributes.select_hash {|k,v| k.to_s.starts_with? "where_"}
|
|
286
305
|
url = object_url(completer_model, :completions, { :for => completer_attr }.update(where_attributes))
|
|
287
306
|
%>
|
|
@@ -345,6 +364,19 @@
|
|
|
345
364
|
</def>
|
|
346
365
|
|
|
347
366
|
|
|
348
|
-
<def tag="after-submit" attrs="uri">
|
|
349
|
-
|
|
367
|
+
<def tag="after-submit" attrs="uri, stay-here, go-back">
|
|
368
|
+
<% uri = request.request_uri if stay_here %>
|
|
369
|
+
<% uri = session[:previous_uri] if go_back %>
|
|
370
|
+
<input type="hidden" value="¶ms[:after_submit] || uri" name="after_submit" if="&uri"/>
|
|
371
|
+
</def>
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
<def tag="hidden-field" attrs="name, value"><input type="hidden" name="&name" value="&value" merge-attrs/></def>
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
<def tag="select-menu" attrs="options, selected, first-option, first-value">
|
|
378
|
+
<select merge-attrs param="default">
|
|
379
|
+
<option value="#{first_value}" unless="&first_option.nil?"><first-option/></option>
|
|
380
|
+
<do param="options"><%= options_for_select(options, selected) %></do>
|
|
381
|
+
</select>
|
|
350
382
|
</def>
|