hobo 1.3.0.pre31 → 1.3.0
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/CHANGES-1.1.txt +5253 -0
- data/CHANGES.txt +255 -5095
- data/VERSION +1 -1
- data/hobo.gemspec +1 -2
- data/lib/generators/hobo/admin_subsite/USAGE +25 -0
- data/lib/generators/hobo/admin_subsite/admin_subsite_generator.rb +2 -1
- data/lib/generators/hobo/assets/USAGE +5 -0
- data/lib/generators/hobo/assets/templates/application.dryml.erb +1 -1
- data/lib/generators/hobo/controller/USAGE +3 -0
- data/lib/generators/hobo/i18n/USAGE +3 -0
- data/lib/generators/hobo/i18n/templates/app.fr.yml +26 -0
- data/lib/generators/hobo/i18n/templates/app.nb.yml +25 -0
- data/lib/generators/hobo/i18n/templates/hobo.de.yml +1 -0
- data/lib/generators/hobo/i18n/templates/hobo.en.yml +3 -2
- data/lib/generators/hobo/i18n/templates/hobo.es.yml +1 -0
- data/lib/generators/hobo/i18n/templates/hobo.fr.yml +195 -0
- data/lib/generators/hobo/i18n/templates/hobo.it.yml +1 -0
- data/lib/generators/hobo/i18n/templates/hobo.nb.yml +198 -0
- data/lib/generators/hobo/i18n/templates/hobo.pt-PT.yml +1 -0
- data/lib/generators/hobo/i18n/templates/hobo.ru.yml +1 -0
- data/lib/generators/hobo/model/USAGE +2 -2
- data/lib/generators/hobo/rapid/templates/hobo-rapid.js +15 -30
- data/lib/generators/hobo/rapid/templates/themes/clean/public/stylesheets/clean.css +1 -0
- data/lib/generators/hobo/resource/USAGE +39 -0
- data/lib/generators/hobo/routes/router.rb +2 -2
- data/lib/generators/hobo/setup_wizard/setup_wizard_generator.rb +23 -9
- data/lib/generators/hobo/subsite.rb +13 -2
- data/lib/generators/hobo/subsite/USAGE +24 -0
- data/lib/generators/hobo/subsite_taglib/USAGE +4 -0
- data/lib/generators/hobo/subsite_taglib/templates/taglib.dryml.erb +1 -1
- data/lib/generators/hobo/test_framework/USAGE +2 -0
- data/lib/generators/hobo/user_controller/USAGE +3 -0
- data/lib/generators/hobo/user_controller/templates/controller.rb.erb +3 -0
- data/lib/generators/hobo/user_mailer/USAGE +2 -0
- data/lib/generators/hobo/user_model/USAGE +2 -9
- data/lib/generators/hobo/user_resource/USAGE +10 -0
- data/lib/hobo.rb +1 -1
- data/lib/hobo/controller/authentication_support.rb +0 -22
- data/lib/hobo/controller/model.rb +15 -13
- data/lib/hobo/controller/{user.rb → user_base.rb} +43 -32
- data/lib/hobo/extensions/action_controller/hobo_methods.rb +25 -1
- data/lib/hobo/extensions/active_record/associations/collection.rb +12 -3
- data/lib/hobo/extensions/active_record/associations/reflection.rb +1 -1
- data/lib/hobo/extensions/active_record/relation_with_origin.rb +4 -0
- data/lib/hobo/helper.rb +6 -1
- data/lib/hobo/helper/translations.rb +1 -1
- data/lib/hobo/model.rb +55 -19
- data/lib/hobo/model/lifecycles.rb +3 -3
- data/lib/hobo/model/lifecycles/lifecycle.rb +7 -3
- data/lib/hobo/model/permissions.rb +1 -0
- data/lib/hobo/model/scopes/automatic_scopes.rb +0 -2
- data/lib/hobo/model/view_hints.rb +1 -0
- data/lib/hobo/rapid/generators/rapid/forms.dryml.erb +2 -1
- data/lib/hobo/rapid/generators/rapid/pages.dryml.erb +10 -11
- data/lib/hobo/rapid/helper.rb +4 -3
- data/lib/hobo/rapid/taglibs/rapid_core.dryml +92 -67
- data/lib/hobo/rapid/taglibs/rapid_editing.dryml +35 -15
- data/lib/hobo/rapid/taglibs/rapid_forms.dryml +46 -22
- data/lib/hobo/rapid/taglibs/rapid_i18n.dryml +103 -37
- data/lib/hobo/rapid/taglibs/rapid_lifecycles.dryml +3 -1
- data/lib/hobo/rapid/taglibs/rapid_pages.dryml +3 -3
- data/lib/hobo/rapid/taglibs/rapid_plus.dryml +49 -45
- data/test/irt/generators/partials/_subsite_taglib_variables.rb +1 -1
- metadata +38 -33
@@ -12,7 +12,7 @@
|
|
12
12
|
|
13
13
|
|
14
14
|
<% each_controller do -%>
|
15
|
-
|
15
|
+
<% next unless @controller < Hobo::Controller::Model %>
|
16
16
|
<!-- ====== <%= model.name %> Pages ====== -->
|
17
17
|
<%
|
18
18
|
new_link = linkable?(:new)
|
@@ -124,11 +124,10 @@ end
|
|
124
124
|
|
125
125
|
unless model.view_hints.secondary_children.empty?
|
126
126
|
aside_collections = model.view_hints.secondary_children.map { |c| [model.reflections[c], model.reverse_reflection(c)] }
|
127
|
-
aside_collections.reject! { |refl, reverse| reverse.nil? }
|
128
127
|
end
|
129
128
|
-%>
|
130
129
|
<def tag="show-page" for="<%= model.name %>">
|
131
|
-
<page merge title="#{ht '<%=model_key %>.show.title', :default=>['<%=sq_escape model_name %>'] }">
|
130
|
+
<page merge title="#{ht '<%=model_key %>.show.title', :default=>['<%=sq_escape model_name %>'], :name => name(:no_wrapper => true) }">
|
132
131
|
|
133
132
|
<body: class="show-page <%= model_class %>" param/>
|
134
133
|
|
@@ -142,8 +141,8 @@ end
|
|
142
141
|
<a:<%= back_link %> param="parent-link">« <ht key="<%= model_key %>.actions.back_to_parent" parent="<%= back_link_human_name %>" name="&this">Back to <name/></ht></a:<%= back_link %>>
|
143
142
|
<% end -%>
|
144
143
|
<h2 param="heading">
|
145
|
-
<ht key="<%= model_key %>.show.heading" name="
|
146
|
-
<name/>
|
144
|
+
<ht key="<%= model_key %>.show.heading" name="#{name(:no_wrapper => true)}">
|
145
|
+
<%= model_name %> <name/>
|
147
146
|
</ht>
|
148
147
|
</h2>
|
149
148
|
<% if boolean_fields -%>
|
@@ -160,7 +159,7 @@ end
|
|
160
159
|
<% if edit_link -%>
|
161
160
|
|
162
161
|
<a action="edit" if="&can_edit?" param="edit-link">
|
163
|
-
<ht key="<%= model_key %>.actions.edit" name="
|
162
|
+
<ht key="<%= model_key %>.actions.edit" name="#{name(:no_wrapper => true)}">
|
164
163
|
Edit <%= model_name %>
|
165
164
|
</ht>
|
166
165
|
</a>
|
@@ -169,7 +168,7 @@ end
|
|
169
168
|
|
170
169
|
<section param="content-body">
|
171
170
|
<% if main_content -%>
|
172
|
-
<view:<%= main_content %> param="description"/>
|
171
|
+
<view:<%= main_content %> param="description" />
|
173
172
|
<% end -%>
|
174
173
|
<% if show_fields.any? -%>
|
175
174
|
<field-list fields="<%= show_fields * ', ' %>" param/>
|
@@ -216,7 +215,7 @@ end
|
|
216
215
|
|
217
216
|
<aside param>
|
218
217
|
<% for refl, reverse_refl in aside_collections -%>
|
219
|
-
<% if linkable?(refl.klass, :"index_for_#{reverse_refl.name}") -%>
|
218
|
+
<% if reverse_refl && linkable?(refl.klass, :"index_for_#{reverse_refl.name}") -%>
|
220
219
|
<collection-preview:<%= refl.name %>.recent param="<%= refl.name %>-preview">
|
221
220
|
<heading-content:><human-collection-name with="&this.origin" collection="<%= refl.name %>" your/></heading-content:>
|
222
221
|
</collection-preview:<%= refl.name %>.recent>
|
@@ -244,14 +243,14 @@ end
|
|
244
243
|
name_attribute = model.name_attribute
|
245
244
|
-%>
|
246
245
|
<def tag="edit-page" for="<%= model.name %>">
|
247
|
-
<page merge title="#{ht '<%= model_key %>.edit.title', :default=>['Edit <%= sq_escape model_name %>'] }">
|
246
|
+
<page merge title="#{ht '<%= model_key %>.edit.title', :default=>['Edit <%= sq_escape model_name %>'], :name => name(:no_wrapper => true) }">
|
248
247
|
|
249
248
|
<body: class="edit-page <%= model_class %>" param/>
|
250
249
|
|
251
250
|
<content:>
|
252
251
|
<section param="content-header">
|
253
252
|
<h2 param="heading">
|
254
|
-
<ht key="<%= model_key %>.edit.heading" name="
|
253
|
+
<ht key="<%= model_key %>.edit.heading" name="#{name(:no_wrapper => true)}">
|
255
254
|
Edit <%= model_name %>
|
256
255
|
</ht>
|
257
256
|
</h2>
|
@@ -314,7 +313,7 @@ new_link = :new.in?(actions)
|
|
314
313
|
|
315
314
|
<section param="content-body">
|
316
315
|
<% if new_link -%>
|
317
|
-
<a action="new" to="
|
316
|
+
<a action="new" to="&@<%= owner %>.<%= collection_name %>" param="new-link">
|
318
317
|
<ht key="<%= model_key %>.actions.new" >New <%=model_name %></ht>
|
319
318
|
</a>
|
320
319
|
|
data/lib/hobo/rapid/helper.rb
CHANGED
@@ -120,15 +120,16 @@ module Hobo
|
|
120
120
|
edit_text = this._?.to_s
|
121
121
|
attributes.update(:hobo_edit_text => edit_text) unless edit_text.nil?
|
122
122
|
|
123
|
-
update = attributes.delete(:update)
|
124
|
-
|
123
|
+
if update = attributes.delete(:update)
|
124
|
+
attributes = add_classes(attributes, update_elements_class(update))
|
125
|
+
end
|
125
126
|
|
126
127
|
view(attributes)
|
127
128
|
end
|
128
129
|
|
129
130
|
|
130
131
|
|
131
|
-
AJAX_CALLBACKS = [ :
|
132
|
+
AJAX_CALLBACKS = [ :success, :failure, :complete ]
|
132
133
|
|
133
134
|
AJAX_ATTRS = AJAX_CALLBACKS + [ :update, :type, :method,
|
134
135
|
:script, :form, :params, :confirm, :message,
|
@@ -93,7 +93,15 @@ This will use `<input/>` as the tag in each table cell instead of `<view/>`
|
|
93
93
|
<table fields="name, created_at, description">
|
94
94
|
<controls:/>
|
95
95
|
</table>
|
96
|
-
|
96
|
+
|
97
|
+
The controls can be further customised using the "edit-link" and "delete-button" parameters:
|
98
|
+
|
99
|
+
<table fields="name, created_at, description">
|
100
|
+
<controls:/>
|
101
|
+
<delete-button: label="Nuke Me"/>
|
102
|
+
</table>
|
103
|
+
|
104
|
+
or by providing completely new content for the control column:
|
97
105
|
|
98
106
|
<table fields="name, created_at, description">
|
99
107
|
<controls:>my controls!</controls:>
|
@@ -124,7 +132,9 @@ This will use `<input/>` as the tag in each table cell instead of `<view/>`
|
|
124
132
|
<td param="#{scope.field_name.to_s.sub('?', '').gsub('.', '-')}-view"><call-tag tag="&field_tag"/></td>
|
125
133
|
</with-fields>
|
126
134
|
<td class="controls" param="controls" if="&all_parameters[:controls]">
|
127
|
-
<a param="edit-link" action="edit" if="&can_edit?"
|
135
|
+
<a param="edit-link" action="edit" if="&can_edit?">
|
136
|
+
<t key="hobo.actions.edit_control">Edit</t>
|
137
|
+
</a>
|
128
138
|
<delete-button param/>
|
129
139
|
</td>
|
130
140
|
</if>
|
@@ -157,24 +167,35 @@ Provides a short hand way of displaying images in public/images
|
|
157
167
|
|
158
168
|
|
159
169
|
<!-- Renders some standard JavaScript code that various features of the Rapid library rely on. This tag would typicallu be called from your `<page>` tag. The default Rapid pages include this already. -->
|
160
|
-
<def tag="hobo-rapid-javascripts"
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
170
|
+
<def tag="hobo-rapid-javascripts">
|
171
|
+
<script type="text/javascript" param="default"><%=
|
172
|
+
res = 'var hoboParts = {};'
|
173
|
+
# FIXME: This should interrogate the model-router - not the models
|
174
|
+
unless Hobo::Model.all_models.empty?
|
175
|
+
# Tell JS code how to pluralize names, unless they follow the simple rule
|
176
|
+
names = Hobo::Model.all_models.map do |m|
|
177
|
+
m = m.name.underscore
|
178
|
+
"#{m}: '#{m.pluralize}'" unless m.pluralize == m + 's'
|
179
|
+
end.compact
|
180
|
+
res << "var pluralisations = {#{names * ', '}}; "
|
181
|
+
end
|
182
|
+
base = [base_url, subsite].compact.join("/")
|
183
|
+
res << "urlBase = '#{base}'; hoboPagePath = '#{request.fullpath}'"
|
184
|
+
if protect_against_forgery?
|
185
|
+
res << "; formAuthToken = { name: '#{request_forgery_protection_token}', value: '#{form_authenticity_token}' }"
|
186
|
+
end
|
187
|
+
res
|
188
|
+
%></script>
|
189
|
+
</def>
|
190
|
+
|
191
|
+
|
192
|
+
<def tag="part-contexts-javascripts">
|
193
|
+
<% unless (storage = part_contexts_storage).blank? %>
|
194
|
+
<script type="text/javascript"><%=
|
195
|
+
storage
|
196
|
+
%></script>
|
197
|
+
<% end %>
|
198
|
+
</def>
|
178
199
|
|
179
200
|
<!-- Renders the name of the current context using a variety of methods.
|
180
201
|
|
@@ -445,7 +466,7 @@ Assuming the context is a blog post...
|
|
445
466
|
|
446
467
|
truncate = 30 if truncate == true
|
447
468
|
the_view = self.truncate(the_view, :length => truncate.to_i) if truncate
|
448
|
-
the_view = the_view.strip
|
469
|
+
the_view = the_view.html_safe? ? the_view.strip.html_safe : the_view.strip
|
449
470
|
|
450
471
|
if no_wrapper
|
451
472
|
the_view
|
@@ -483,12 +504,14 @@ Assuming the context is a blog post...
|
|
483
504
|
<!-- Renders localized `number_with_delimiter this`, or `format % this` if the `format` attribute is given -->
|
484
505
|
<def tag="view" for="Numeric" attrs="format"><%= format ? format % this : number_with_delimiter(this) %></def>
|
485
506
|
|
486
|
-
<!--
|
507
|
+
<!-- If `this.html_safe?`, returns this unchanged. Otherwise renders `this` with HTML escaping and newlines replaced with `<br>` tags -->
|
487
508
|
<def tag="view" for="string"><%=
|
488
|
-
if
|
509
|
+
if this.html_safe?
|
510
|
+
this
|
511
|
+
elsif !(this.class == String) && this.respond_to?(:to_html) # workaround for Maruku which adds String#to_html : (
|
489
512
|
this.to_html(scope.xmldoctype)
|
490
513
|
else
|
491
|
-
h(this).gsub("\n", "<br#{scope.xmldoctype ? ' /' : ''}>")
|
514
|
+
h(this).gsub("\n", "<br#{scope.xmldoctype ? ' /' : ''}>").html_safe
|
492
515
|
end
|
493
516
|
%></def>
|
494
517
|
|
@@ -513,10 +536,9 @@ The label can be customised using the `label` attribute, e.g.
|
|
513
536
|
<count:comments label="blog post comment"/> -> <span class="count">12 blog post comments</span>
|
514
537
|
|
515
538
|
You can pass a summary attribute, which will generate a complete localized sentence. It allows 2 options:
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
If the lookup fails, it will fallback to the english default sentences consistent with the count.
|
539
|
+
|
540
|
+
- boolean (e.g. `<count summary/>`): it will lookup the 'tags.count.default' key in the locale file. If the lookup fails, it will fallback to the english default sentences consistent with the count.
|
541
|
+
- String (e.g. `<count summary="offer"/>`): it will lookup the 'tags.count.offer' key in the locale file. If the lookup fails, it will fallback to the english default sentences consistent with the count.
|
520
542
|
|
521
543
|
### Examples
|
522
544
|
|
@@ -532,18 +554,22 @@ You can pass a summary attribute, which will generate a complete localized sente
|
|
532
554
|
one: "Puoi scegliere solo una {{label}}"
|
533
555
|
other: "Puoi scegliere tra {{count}} {{label}}"
|
534
556
|
|
535
|
-
|
557
|
+
with :en locale and boolean summary (internal defaults)
|
558
|
+
|
536
559
|
<count:comments summary/> -> <span class="count">There is 1 Comment</span>
|
537
560
|
<count:viewings summary/> -> <span class="count">There are 3 Viewings</span>
|
538
|
-
(note: just add the locale english strings to use like the following examples)
|
539
561
|
|
540
|
-
|
562
|
+
(note: just add the locale english strings to use like the following examples)
|
563
|
+
|
564
|
+
with :it locale and boolean summary (key "tags.count.default")
|
565
|
+
|
541
566
|
<count:comments summary/>
|
542
567
|
-> count => 0 -> <span class="count">Non ci sono Commenti</span>
|
543
568
|
-> count => 1 -> <span class="count">C'è solo 1 Commento</span>
|
544
569
|
-> count => 5 -> <span class="count">Ci sono 5 Commenti</span>
|
545
570
|
|
546
|
-
|
571
|
+
with :it locale and summary="choice" (key "tags.count.choice")
|
572
|
+
|
547
573
|
<count:comments summary="choice"/>
|
548
574
|
-> count => 0 -> <span class="count">Non ci sono Commenti da scegliere</span>
|
549
575
|
-> count => 1 -> <span class="count">Puoi scegliere solo 1 Commento</span>
|
@@ -596,6 +622,8 @@ You can pass a summary attribute, which will generate a complete localized sente
|
|
596
622
|
end
|
597
623
|
%></span></def>
|
598
624
|
|
625
|
+
<!-- Equivalent to `<you capitalize/>`-->
|
626
|
+
<def tag="You"><you merge capitalize/></def>
|
599
627
|
|
600
628
|
<!-- Renders a `<link rel="Stylesheet" type="text/css">` to include the default stylesheet for the selected theme (select with `<set-theme>`). Included in the default pages.
|
601
629
|
-->
|
@@ -611,9 +639,9 @@ You can pass a summary attribute, which will generate a complete localized sente
|
|
611
639
|
|
612
640
|
The context should be a user object. If `this == current_user` the "you" form is rendered, otherwise the form with the user's name:
|
613
641
|
|
614
|
-
|
615
|
-
|
616
|
-
|
642
|
+
- `<you have/> new mail` -> "you have new mail" or "Jim has new mail"
|
643
|
+
- `<you are/> now an admin` -> "you are now an admin" or "Jim is now an admin"
|
644
|
+
- `<you do/>n't want to go there` -> "you don't want to go there" or "Jim doesn't want to go there"
|
617
645
|
|
618
646
|
The tag is also localized in the namespaces "tags.you.current_user" and "tags.you.other_user".
|
619
647
|
Each namespace can contain the legacy keys "have", "are", "do" used for the respective attributes,
|
@@ -636,15 +664,15 @@ that you add the keys in the correct namespaces.
|
|
636
664
|
are: "{{name}} è"
|
637
665
|
can: "{{name}} può"
|
638
666
|
|
639
|
-
|
640
|
-
|
641
|
-
|
667
|
+
- `<you have/> un nuovo messaggio.` -> "Hai un nuovo messaggio." or "Jim ha un nuovo messaggio."
|
668
|
+
- `Adesso <you are/> amministratore.` -> "Adesso sei amministratore." or "Adesso Jim è amministratore."
|
669
|
+
- `<you can/> scrivere.` -> "Puoi scrivere." or "Jim può scrivere."
|
642
670
|
|
643
671
|
(note: :name is added by default as an interpolable variable)
|
644
672
|
|
645
673
|
### Attributes
|
646
674
|
|
647
|
-
|
675
|
+
- capitalize: the first letter of the resulting sentence will be capitalized
|
648
676
|
|
649
677
|
|
650
678
|
### Additional Notes
|
@@ -666,36 +694,36 @@ The "titleize" attribute is deprecated: use "capitalize" instead.
|
|
666
694
|
</if>
|
667
695
|
<else>
|
668
696
|
<do param="default">
|
669
|
-
<%= s = t("tags.you.other_user.#{k || attributes.keys.first || 'default'}", :name=>
|
670
|
-
:default=>"#{
|
697
|
+
<%= s = t("tags.you.other_user.#{k || attributes.keys.first || 'default'}", :name=>name(:no_wrapper => true),
|
698
|
+
:default=>"#{name(:no_wrapper => true)} #{'has' if attributes[:have]}#{'is' if attributes[:are]}#{'does' if attributes[:do]}")
|
671
699
|
(titleize||capitalize) ? s.sub(/^./){|c| c.upcase} : s %>
|
672
700
|
</do>
|
673
701
|
</else>
|
674
702
|
</def>
|
675
703
|
|
676
|
-
<!-- Equivalent to `<
|
677
|
-
<def tag="
|
704
|
+
<!-- Equivalent to `<your ... capitalize/>`-->
|
705
|
+
<def tag="Your"><your merge capitalize/></def>
|
678
706
|
|
679
707
|
<!-- Similar to `<you>`, but renders "Your" or "Fred's" or equivalent localized strings
|
680
708
|
|
681
709
|
### Attributes
|
682
710
|
|
683
|
-
|
684
|
-
|
685
|
-
|
711
|
+
- capitalize: the first letter of the resulting sentence will be capitalized
|
712
|
+
- count: used in pluralization. If omitted it will be set to 1.
|
713
|
+
- key: used to lookup the translation in the locale file. It allows 3 different options:
|
686
714
|
- single key like 'message': simple translation in 'tags.your.message.current_user'
|
687
715
|
or 'tags.your.message.other_user'
|
688
716
|
- composite key like 'any.namespace.message': translation as for the previous case, but it will
|
689
|
-
translate also the 'any.namespace.message' and will interpolate the variable
|
717
|
+
translate also the 'any.namespace.message' and will interpolate the variable `<key>` (in this case :message)
|
690
718
|
in the translation
|
691
719
|
- when key is omitted it will be set to "default" and will do the translation with that key.
|
692
720
|
Pass other meaningful attributes to achieve a dynamic usage
|
693
|
-
|
721
|
+
- any other attribute passed to the tag will be used as a variable for interpolation
|
694
722
|
|
695
723
|
Notes
|
696
724
|
|
697
|
-
|
698
|
-
|
725
|
+
- The :name variable is added by default as an interpolable variable
|
726
|
+
- If no translation is found an automatic (only english) default is generated:
|
699
727
|
the Your/Jim's string, joined to the tag content.
|
700
728
|
If you pass an explicit 'default' attribute you will override the automatic default.
|
701
729
|
|
@@ -718,24 +746,25 @@ Notes
|
|
718
746
|
other: "Tue {{entry}}"
|
719
747
|
other_user: "{{entry}} di {{name}}"
|
720
748
|
|
721
|
-
|
722
|
-
-> count => 1 -> "Tuo Messaggio" or "Messaggio di Jim"
|
723
|
-
-> count => 5 -> "Tuoi Messaggi" or "Messaggi di Jim"
|
749
|
+
- `<your key="message" count=>"&messages.count"/>`:
|
724
750
|
|
725
|
-
-
|
726
|
-
|
727
|
-
-> count => 5 -> "Tue Entrate" or "Entrate di Jim"
|
751
|
+
- count => 1: "Tuo Messaggio" or "Messaggio di Jim"
|
752
|
+
- count => 5: "Tuoi Messaggi" or "Messaggi di Jim"
|
728
753
|
|
729
|
-
|
730
|
-
|
754
|
+
- `<your key="activerecord.models.entry" count=>"&this.entries.count"/>`:
|
755
|
+
|
756
|
+
- count => 1: "Tua Entrata" or "Entrata di Jim"
|
757
|
+
- count => 5: "Tue Entrate" or "Entrate di Jim"
|
731
758
|
|
759
|
+
- `<your>Posts</your>`: "your Posts" or "Jim's Posts"
|
760
|
+
-->
|
732
761
|
<def tag="your" attrs="key, capitalize"><%=
|
733
762
|
key ||= 'default'
|
734
763
|
# prepare symbolized attributes for merging
|
735
764
|
attrs = {}
|
736
765
|
attributes.each_pair{|k,v| attrs[k.to_sym] = v}
|
737
766
|
d = "#{your_default} #{all_parameters.default}"
|
738
|
-
options = {:default=>[d], :count=>(attrs[:count]||1), :name=>
|
767
|
+
options = {:default=>[d], :count=>(attrs[:count]||1), :name=>name(:no_wrapper => true)}
|
739
768
|
your_key = key.split('.').last
|
740
769
|
unless key.eql?(your_key) || attrs.has_key?(your_key.to_sym)
|
741
770
|
options[your_key.to_sym] = t(key, :count=>options[:count], :default=>your_key.titleize)
|
@@ -750,8 +779,10 @@ Notes
|
|
750
779
|
capitalize ? s.sub(/^./){|c| c.upcase} : s
|
751
780
|
%></def>
|
752
781
|
|
753
|
-
<!--
|
754
|
-
<def tag="
|
782
|
+
<!-- Capitalised version of `<a-or-an>` -->
|
783
|
+
<def tag="A-or-An" attrs="word"><%=
|
784
|
+
(word =~ /^[aeiou]/i ? "An " : "A ") + word
|
785
|
+
%></def>
|
755
786
|
|
756
787
|
<!-- Deprecated. It's harder than you think to do this (e.g. an umbrealla, an user)
|
757
788
|
-->
|
@@ -760,12 +791,6 @@ Notes
|
|
760
791
|
%></def>
|
761
792
|
|
762
793
|
|
763
|
-
<!-- Capitalised version of `<a-or-an>` -->
|
764
|
-
<def tag="A-or-An" attrs="word"><%=
|
765
|
-
(word =~ /^[aeiou]/i ? "An " : "A ") + word
|
766
|
-
%></def>
|
767
|
-
|
768
|
-
|
769
794
|
<!-- Renders a collection of string joined with ", ", or some other string passed in the `join` attribute -->
|
770
795
|
<def tag="comma-list" attrs="join"><%= this.join(join || ", ") %></def>
|
771
796
|
|
@@ -81,25 +81,45 @@ This tag does not sanitize HTML; this is provided by HtmlString before saving to
|
|
81
81
|
|
82
82
|
### Attributes
|
83
83
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
-
|
89
|
-
|
90
|
-
|
84
|
+
- `include-none` - whether to include a 'none' option (i.e. set the foreign key to null). If this value is not supplied, the default is "true" if the current value is nil; otherwise the default is "false". One implication of this is that the default may change when the form is re-rendered due to a validation failure. Setting this value explicitly is recommended.
|
85
|
+
- `blank-message` - the message for the 'none' option. Defaults to "(No `<model-name>`)", e.g. "(No Product)"
|
86
|
+
- `options` - an array of records to include in the menu. Defaults to the all the records in the target table that match any `:conditions` declared on the `belongs_to` (subject to `limit`)
|
87
|
+
- `sort` - whether to sort the array of options. Defaults to no sorting.
|
88
|
+
- `limit` - if `options` is not specified, this limits the number of records. Default: 100
|
89
|
+
- `text_method` - The method to call on each record to get the text for the option. Multiple methods are supported ie "institution.name"
|
90
|
+
- `update` - one or more DOM ID's (comma separated string or an array) to be updated as part of the ajax call.
|
91
91
|
|
92
92
|
NOTE: yes that's *DOM ID's* not part-names. A common source of confusion because by default the part name and DOM ID are the same.
|
93
93
|
|
94
94
|
-->
|
95
|
-
<def tag="select-one-editor" attrs="include-none, blank-message, sort,
|
95
|
+
<def tag="select-one-editor" attrs="include-none, blank-message, options, sort, limit, text-method, update"><%
|
96
96
|
raise Hobo::Error.new("Not allowed to edit") unless can_edit?
|
97
97
|
blank_message ||= ht("#{this_type.name.to_s.underscore}.select_one_editor.blank_message", :count => 0, :default => "(No #{this_type.name.to_s.titleize})")
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
98
|
+
limit ||= 100
|
99
|
+
|
100
|
+
if options.blank? || !options.first.respond_to?(:first)
|
101
|
+
options ||= begin
|
102
|
+
conditions = ActiveRecord::Associations::BelongsToAssociation.new(this_parent, this_field_reflection).send(:conditions)
|
103
|
+
order = this_field_reflection.klass.default_order
|
104
|
+
this_field_reflection.klass.all(:conditions => conditions, :limit => limit, :order => order).select {|x| can_view?(x)}
|
105
|
+
end
|
106
|
+
|
107
|
+
id_method = this_field_reflection.options[:primary_key] || this_field_reflection.klass.primary_key
|
108
|
+
if text_method.nil?
|
109
|
+
select_options = options.map { |x| [name(:with => x, :no_wrapper => true), x.send(id_method)] }
|
110
|
+
else
|
111
|
+
select_options = options.map do |x|
|
112
|
+
[ text_method.split(".").inject(x) { |v, method| v.send(method) },
|
113
|
+
x.send(id_method) ]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
else
|
117
|
+
# handle the old style, where options could be passed an options_for_select style array
|
118
|
+
select_options = options
|
119
|
+
end
|
120
|
+
select_options = select_options.sort if sort
|
121
|
+
select_options.insert(0, [blank_message, ""]) if include_none || (this.nil? && include_none != false)
|
122
|
+
|
103
123
|
f = ajax_updater(object_url(this_parent, :method => :put),
|
104
124
|
update,
|
105
125
|
:method => "put",
|
@@ -108,7 +128,7 @@ This tag does not sanitize HTML; this is provided by HtmlString before saving to
|
|
108
128
|
} })
|
109
129
|
%>
|
110
130
|
<select onchange="#{f}" merge-attrs>
|
111
|
-
<%= options_for_select(
|
131
|
+
<%= options_for_select(select_options, this ? this.send(id_method) : "") %>
|
112
132
|
</select>
|
113
133
|
</def>
|
114
134
|
|
@@ -216,7 +236,7 @@ This tag does not sanitize HTML; this is provided by HtmlString before saving to
|
|
216
236
|
-->
|
217
237
|
<def tag="integer-select-editor" attrs="options, min, max, update, nil-option, message">
|
218
238
|
<% options ||= (min.to_i..max.to_i).to_a %>
|
219
|
-
<select class="integer editor #{
|
239
|
+
<select class="integer editor #{update_elements_class(update)} #{model_id_class(this_parent, this_field)}"
|
220
240
|
merge-attrs="&message ? attributes.merge(:hobo_message => message) : attributes">
|
221
241
|
<if test="&this.nil?"><option value=""><%= nil_option || "Choose a value" %></option></if>
|
222
242
|
<%= options_for_select(options.*.to_s, this.to_s) %>
|