hobo 1.3.0.pre31 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/CHANGES-1.1.txt +5253 -0
  2. data/CHANGES.txt +255 -5095
  3. data/VERSION +1 -1
  4. data/hobo.gemspec +1 -2
  5. data/lib/generators/hobo/admin_subsite/USAGE +25 -0
  6. data/lib/generators/hobo/admin_subsite/admin_subsite_generator.rb +2 -1
  7. data/lib/generators/hobo/assets/USAGE +5 -0
  8. data/lib/generators/hobo/assets/templates/application.dryml.erb +1 -1
  9. data/lib/generators/hobo/controller/USAGE +3 -0
  10. data/lib/generators/hobo/i18n/USAGE +3 -0
  11. data/lib/generators/hobo/i18n/templates/app.fr.yml +26 -0
  12. data/lib/generators/hobo/i18n/templates/app.nb.yml +25 -0
  13. data/lib/generators/hobo/i18n/templates/hobo.de.yml +1 -0
  14. data/lib/generators/hobo/i18n/templates/hobo.en.yml +3 -2
  15. data/lib/generators/hobo/i18n/templates/hobo.es.yml +1 -0
  16. data/lib/generators/hobo/i18n/templates/hobo.fr.yml +195 -0
  17. data/lib/generators/hobo/i18n/templates/hobo.it.yml +1 -0
  18. data/lib/generators/hobo/i18n/templates/hobo.nb.yml +198 -0
  19. data/lib/generators/hobo/i18n/templates/hobo.pt-PT.yml +1 -0
  20. data/lib/generators/hobo/i18n/templates/hobo.ru.yml +1 -0
  21. data/lib/generators/hobo/model/USAGE +2 -2
  22. data/lib/generators/hobo/rapid/templates/hobo-rapid.js +15 -30
  23. data/lib/generators/hobo/rapid/templates/themes/clean/public/stylesheets/clean.css +1 -0
  24. data/lib/generators/hobo/resource/USAGE +39 -0
  25. data/lib/generators/hobo/routes/router.rb +2 -2
  26. data/lib/generators/hobo/setup_wizard/setup_wizard_generator.rb +23 -9
  27. data/lib/generators/hobo/subsite.rb +13 -2
  28. data/lib/generators/hobo/subsite/USAGE +24 -0
  29. data/lib/generators/hobo/subsite_taglib/USAGE +4 -0
  30. data/lib/generators/hobo/subsite_taglib/templates/taglib.dryml.erb +1 -1
  31. data/lib/generators/hobo/test_framework/USAGE +2 -0
  32. data/lib/generators/hobo/user_controller/USAGE +3 -0
  33. data/lib/generators/hobo/user_controller/templates/controller.rb.erb +3 -0
  34. data/lib/generators/hobo/user_mailer/USAGE +2 -0
  35. data/lib/generators/hobo/user_model/USAGE +2 -9
  36. data/lib/generators/hobo/user_resource/USAGE +10 -0
  37. data/lib/hobo.rb +1 -1
  38. data/lib/hobo/controller/authentication_support.rb +0 -22
  39. data/lib/hobo/controller/model.rb +15 -13
  40. data/lib/hobo/controller/{user.rb → user_base.rb} +43 -32
  41. data/lib/hobo/extensions/action_controller/hobo_methods.rb +25 -1
  42. data/lib/hobo/extensions/active_record/associations/collection.rb +12 -3
  43. data/lib/hobo/extensions/active_record/associations/reflection.rb +1 -1
  44. data/lib/hobo/extensions/active_record/relation_with_origin.rb +4 -0
  45. data/lib/hobo/helper.rb +6 -1
  46. data/lib/hobo/helper/translations.rb +1 -1
  47. data/lib/hobo/model.rb +55 -19
  48. data/lib/hobo/model/lifecycles.rb +3 -3
  49. data/lib/hobo/model/lifecycles/lifecycle.rb +7 -3
  50. data/lib/hobo/model/permissions.rb +1 -0
  51. data/lib/hobo/model/scopes/automatic_scopes.rb +0 -2
  52. data/lib/hobo/model/view_hints.rb +1 -0
  53. data/lib/hobo/rapid/generators/rapid/forms.dryml.erb +2 -1
  54. data/lib/hobo/rapid/generators/rapid/pages.dryml.erb +10 -11
  55. data/lib/hobo/rapid/helper.rb +4 -3
  56. data/lib/hobo/rapid/taglibs/rapid_core.dryml +92 -67
  57. data/lib/hobo/rapid/taglibs/rapid_editing.dryml +35 -15
  58. data/lib/hobo/rapid/taglibs/rapid_forms.dryml +46 -22
  59. data/lib/hobo/rapid/taglibs/rapid_i18n.dryml +103 -37
  60. data/lib/hobo/rapid/taglibs/rapid_lifecycles.dryml +3 -1
  61. data/lib/hobo/rapid/taglibs/rapid_pages.dryml +3 -3
  62. data/lib/hobo/rapid/taglibs/rapid_plus.dryml +49 -45
  63. data/test/irt/generators/partials/_subsite_taglib_variables.rb +1 -1
  64. metadata +38 -33
@@ -32,8 +32,6 @@ Several of the tags in this taglib support the following set of ajax attributes:
32
32
  The following attributes are also supported by all the ajax tags. Set them to fragments of javascript to have that script
33
33
  executed at various points in the ajax request cycle:
34
34
 
35
- - before: script to run before the request
36
-
37
35
  - success: script to run on successful completion of the request
38
36
 
39
37
  - failure: script to run on a request failure
@@ -373,15 +371,29 @@ edit collections a `Category` model in your application:
373
371
 
374
372
  ### Attributes
375
373
 
376
- - order: The order of the year, month and day menus. A comma separated string or an array. Default: "year, month, day"
377
- - date-separator, discard-type, prompt and prefix are passed to the select_date helper as options
374
+ - all the options of select_date and date_select are passed to the select_date Rails
375
+ helper
378
376
 
379
377
  All the other attributes are passed to the `select_date` helper as the html-options hash.
380
378
 
381
379
  The menus default to the current date if the current value is nil.
382
380
 
381
+ Examples:
382
+
383
+ - override the input for date tag in a form
384
+
385
+ <my-special-date-view:>
386
+ <input start-year="&1940" order="day,month,year" />
387
+ </my-special-date-view:>
388
+
389
+ - override the tag application-wide
390
+
391
+ <extend tag='input' for='date'>
392
+ <old-input merge order="day,month,year" start-year="&1940" />
393
+ </extend>
394
+
383
395
  -->
384
- <def tag="input" for="date" attrs="order, date-separator, discard-type, prompt, prefix">
396
+ <def tag="input" for="date" attrs="use-month-numbers, use-short-month, add-month-numbers, use-month-names, date-separator, start-year, end-year, discard-day, discard-month, discard-year, order, include-blank, default, disabled, prompt, prefix">
385
397
  <% order = order.nil? ? [:year, :month, :day] : comma_split(order).*.to_sym -%>
386
398
  <%= select_date(this || current_time,
387
399
  (all_attributes - attributes.keys).reverse_merge(:prefix => param_name_for_this).merge(:order => order),
@@ -621,7 +633,8 @@ All of the standard ajax attributes are supported (see the main taglib documenti
621
633
  class_or_assoc = if model
622
634
  model.is_a?(String) ? model.constantize : model
623
635
  elsif Hobo.simple_has_many_association?(this)
624
- fields[this_field_reflection.primary_key_name] = this.proxy_owner.id
636
+ id_method = this_field_reflection.options[:primary_key] || this_field_reflection.klass.primary_key
637
+ fields[this_field_reflection.primary_key_name] = this.proxy_owner.send(id_method)
625
638
  this
626
639
  else
627
640
  raise Hobo::Error.new("invalid context for <create-button>")
@@ -630,11 +643,17 @@ All of the standard ajax attributes are supported (see the main taglib documenti
630
643
  new.set_creator(current_user)
631
644
  if can_create?(new)
632
645
  label ||= ht("#{new.class.to_s.underscore}.actions.new", :default=>"New #{new.class.model_name.human}")
633
- ajax_attributes = { :message => message }
634
646
  class_name = new.class.name.underscore
635
- ajax_attributes[:params] = { class_name => fields } unless fields.empty?
647
+ params ||= params || {}
648
+ params = params.merge(class_name => fields) unless fields.blank?
649
+
650
+ ajax_attributes, html_attributes = attributes.partition_hash(Hobo::Rapid::Helper::AJAX_ATTRS)
651
+
652
+ ajax_attributes.reverse_merge!(:message => message, :params => params)
636
653
  func = ajax_updater(object_url(new.class, :method => :post), update, ajax_attributes)
637
- element :input, add_classes(attributes.merge(:type =>'button', :onclick => func, :value => label),
654
+ html_attributes.reverse_merge!(:type =>'button', :onclick => func, :value => label)
655
+
656
+ element :input, add_classes(html_attributes,
638
657
  "button create-button create-#{class_name}-button"), nil, true, true
639
658
  end
640
659
  %></def>
@@ -649,6 +668,7 @@ This is the default input that Rapid uses for `belongs_to` associations. The men
649
668
  - `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.
650
669
  - `blank-message` - the message for the 'none' option. Defaults to "(No `<model-name>`)", e.g. "(No Product)"
651
670
  - `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`)
671
+ - `sort` - whether to sort the array of options. Defaults to no sorting.
652
672
  - `limit` - if `options` is not specified, this limits the number of records. Default: 100
653
673
  - `text_method` - The method to call on each record to get the text for the option. Multiple methods are supported ie "institution.name"
654
674
 
@@ -664,15 +684,17 @@ For situations where there are too many target records to practically include in
664
684
 
665
685
  options ||= begin
666
686
  conditions = ActiveRecord::Associations::BelongsToAssociation.new(this_parent, this_field_reflection).send(:conditions)
667
- this_field_reflection.klass.all(:conditions => conditions, :limit => limit).select {|x| can_view?(x)}
687
+ order = this_field_reflection.klass.default_order
688
+ this_field_reflection.klass.all(:conditions => conditions, :limit => limit, :order => order).select {|x| can_view?(x)}
668
689
  end
669
690
 
691
+ id_method = this_field_reflection.options[:primary_key] || this_field_reflection.klass.primary_key
670
692
  if text_method.nil?
671
- select_options = options.map { |x| [x.to_s, x.id] }
693
+ select_options = options.map { |x| [name(:with => x, :no_wrapper => true), x.send(id_method)] }
672
694
  else
673
695
  select_options = options.map do |x|
674
696
  [ text_method.split(".").inject(x) { |v, method| v.send(method) },
675
- x.id ]
697
+ x.send(id_method) ]
676
698
  end
677
699
  end
678
700
  select_options = select_options.sort if sort
@@ -680,7 +702,7 @@ For situations where there are too many target records to practically include in
680
702
  attributes = add_classes(attributes, "input", "belongs_to", type_and_field)
681
703
  -%>
682
704
  <select name="#{param_name_for_this(true)}" merge-attrs="&attributes.except :name">
683
- <%= options_for_select(select_options, this ? this.id : "") %>
705
+ <%= options_for_select(select_options, this ? this.send(id_method) : "") %>
684
706
  </select>
685
707
  </def>
686
708
 
@@ -751,11 +773,13 @@ If you wish to set `min-chars` to 0, you will require this [patch to controls.js
751
773
  min_chars ||= 1
752
774
  value = name(:no_wrapper => true, :if_present => true)
753
775
  -%>
754
- <input type="text" name="#{param_name_for_this}"
755
- class="autocompleter #{type_and_field._?.dasherize} #{css_data :complete_on, typed_id(complete_target), completer} #{css_data :min_chars, min_chars} #{'nil-value' if value==''}"
756
- value="#{value=='' ? nil_value : value}"
757
- merge-attrs/>
758
- <div class="completions-popup" style="display:none"></div>
776
+ <wrap tag="span" class="field-with-errors" when="&!this_parent.errors[this_field].empty?">
777
+ <input type="text" name="#{param_name_for_this}"
778
+ class="autocompleter #{type_and_field._?.dasherize} #{css_data :complete_on, typed_id(complete_target), completer} #{css_data :min_chars, min_chars} #{'nil-value' if value==''}"
779
+ value="#{value=='' ? nil_value : value}"
780
+ merge-attrs/>
781
+ <div class="completions-popup" style="display:none"></div>
782
+ </wrap>
759
783
  </def>
760
784
 
761
785
 
@@ -862,7 +886,7 @@ Use the `stay-here` attribute to remain on the current page:
862
886
  ...
863
887
  </form>
864
888
 
865
- Use the `go-back` option to return to the previous page:
889
+ Use the `go-back` option to return to the page in `session[:previous_uri]`:
866
890
 
867
891
  <form>
868
892
  <after-submit go-back/>
@@ -904,7 +928,7 @@ Use the `uri` option to specify a redirect location:
904
928
  <select merge-attrs param="default">
905
929
  <% selected=this if selected.nil? %>
906
930
  <option value="#{first_value}" unless="&first_option.nil?"><first-option/></option>
907
- <do param="options"><% options_for_select(options, selected) %></do>
931
+ <do param="options"><%= options_for_select(options, selected) %></do>
908
932
  </select>
909
933
  </def>
910
934
 
@@ -929,8 +953,8 @@ Use the `uri` option to specify a redirect location:
929
953
  <input type="hidden" name="#{param_name}[]" value=""/><% # ensure all items are removed when nothing checked
930
954
  %>
931
955
  <li repeat="&options" param>
932
- <input type="checkbox" name="#{param_name}[]" value="@#{this.id}" checked="&this.in?(collection)" disabled="&disabled"/>
933
- <name param/>
956
+ <input id="#{dom_id(this, :check_many)}" type="checkbox" name="#{param_name}[]" value="@#{this.id}" checked="&this.in?(collection)" disabled="&disabled"/>
957
+ <label for="#{dom_id(this, :check_many)}"><name param/></label>
934
958
  </li>
935
959
  </ul>
936
960
  </def>
@@ -7,7 +7,6 @@
7
7
  - model - (optional) should be a model class or a record object (default to this)
8
8
  - count - (optional) used to pick the inflected string for the model. It should be an integer.
9
9
  -->
10
-
11
10
  <def tag="model-name-human" attrs="model, count"><%=
12
11
  model ||= this
13
12
  model = model.class unless model.kind_of? Class
@@ -28,7 +27,6 @@
28
27
  - count - (optional) should be an integer
29
28
 
30
29
  -->
31
-
32
30
  <def tag="human-attribute-name" attrs="attribute, model"><%=
33
31
  model ||= this
34
32
  model = model.class unless model.kind_of? Class
@@ -53,41 +51,44 @@ With the `your` attribute and in the special case the context is a Hobo::Model::
53
51
  ### Example
54
52
 
55
53
 
56
- it:
57
- activerecord:
58
- attributes:
59
- post:
60
- comments:
61
- one: "Commento"
62
- other: "Commenti"
63
- user:
54
+ it:
55
+ activerecord:
56
+ attributes:
57
+ post:
58
+ comments:
59
+ one: "Commento"
60
+ other: "Commenti"
61
+ user:
62
+ roles:
63
+ one: "Ruolo"
64
+ other: "Ruoli"
65
+ tags:
66
+ your:
64
67
  roles:
65
- one: "Ruolo"
66
- other: "Ruoli"
67
- tags:
68
- your:
69
- roles:
70
- current_user:
71
- one: "Il tuo Ruolo"
72
- other: "I tuoi Ruoli"
73
- other_user:
74
- one: "Ruolo di {{name}}"
75
- other: Ruoli di {{name}}"
76
-
77
- # context is a Post instance ('your' is ignored)
78
- <human-collection-name collection="comments" count="&user.comments.count" your/>
79
- I18n.locale = :en => "Comment" or "Comments"
80
- I18n.locale = :it => "Commento" or "Commenti"
81
-
82
- # context is an User instance
83
- <human-collection-name collection="roles' count="&user.roles.count" your/>
84
- I18n.locale = :en => "Your Role" or "Jim's Role" or "Your Roles" or "Jim's Roles"
85
- I18n.locale = :it => "Il tuo Ruolo" or "Il Ruolo di Jim" or "I tuoi Ruoli" or "I Ruoli di Jim"
86
- (output is the same as <Your key="roles" count=>"&user.roles.count"/> )
87
-
88
- <human-collection-name collection="roles" count="&user.roles.count"/>
89
- I18n.locale = :en => "Role" or "Roles"
90
- I18n.locale = :it => "Ruolo" or "Ruoli"
68
+ current_user:
69
+ one: "Il tuo Ruolo"
70
+ other: "I tuoi Ruoli"
71
+ other_user:
72
+ one: "Ruolo di {{name}}"
73
+ other: Ruoli di {{name}}"
74
+
75
+ context is a Post instance ('your' is ignored)
76
+
77
+ <human-collection-name collection="comments" count="&user.comments.count" your/>
78
+ I18n.locale = :en => "Comment" or "Comments"
79
+ I18n.locale = :it => "Commento" or "Commenti"
80
+
81
+ context is a User instance
82
+
83
+ <human-collection-name collection="roles' count="&user.roles.count" your/>
84
+ I18n.locale = :en => "Your Role" or "Jim's Role" or "Your Roles" or "Jim's Roles"
85
+ I18n.locale = :it => "Il tuo Ruolo" or "Il Ruolo di Jim" or "I tuoi Ruoli" or "I Ruoli di Jim"
86
+
87
+ (output is the same as `<Your key="roles" count=>"&user.roles.count"/>`)
88
+
89
+ <human-collection-name collection="roles" count="&user.roles.count"/>
90
+ I18n.locale = :en => "Role" or "Roles"
91
+ I18n.locale = :it => "Ruolo" or "Ruoli"
91
92
  -->
92
93
  <def tag="human-collection-name" attrs="collection, count, your"><%
93
94
  raise Hobo::Error, "The 'collection' attribute must be defined" if collection.blank?
@@ -97,7 +98,7 @@ With the `your` attribute and in the special case the context is a Hobo::Model::
97
98
  attrs = {}
98
99
  all_attributes.each_pair{|k,v| attrs[k.to_sym] = v} -%>
99
100
  <% if your && belong_class < Hobo::Model::UserBase && this.kind_of?(Hobo::Model::UserBase) && I18n.locale == :en -%>
100
- <your key="&collection" merge-attrs="&{:name=>this.name}.merge(attrs)" capitalize>
101
+ <your key="&collection" merge-attrs="&{:name=>name(:no_wrapper => true)}.merge(attrs)" capitalize>
101
102
  <%= belong_class.human_attribute_name(collection.to_sym, attrs) %>
102
103
  </your>
103
104
  <% else -%>
@@ -105,3 +106,68 @@ With the `your` attribute and in the special case the context is a Hobo::Model::
105
106
  <% end %>
106
107
  </def>
107
108
 
109
+ <!-- nodoc -->
110
+ <def tag="fakedef">
111
+ </def>
112
+
113
+ <!-- Simple wrapper around I18n.t.
114
+
115
+ The tag content is used as the :default option. It is overridden by an explicit 'default' attribute.
116
+ There is a default :count => 1.
117
+
118
+ ### Attributes
119
+
120
+ - key: the key to lookup
121
+ - all the attributes accepted by the wrapped method -->
122
+ <fakedef tag="t" attrs="key">
123
+ <!-- actually defined in i18n.rb -->
124
+ </fakedef>
125
+
126
+ <!--
127
+ Wrapper around the Rails :translate helper with hobo added features.
128
+
129
+ It can be used as a regular helper or as a dryml tag.
130
+
131
+ ### Hobo Added Features
132
+
133
+ `ht` adds some conventions for easier hobo translation.
134
+
135
+ 1. Assumes the first part of the key to be a model name (e.g.: users.index.title -> user)
136
+ 2. Tries to translate the model by lookup for: (e.g.: user-> activerecord.models.user)
137
+ 3. Adds a default fallback to the beginning of the fallback chain by replacing the first part of the key with "hobo" and using the translated model name as additional attribute. This allows us to have default translations (e.g.: hobo.index.title: "{{model}} Index")
138
+
139
+ You can also pass any other :translate option like for example :count.
140
+
141
+ Is also used as a tag in the dryml-view files. The syntax is:
142
+
143
+ <ht key="my.app">My Application</ht>
144
+
145
+ Will lookup the "my.app"-key for your locale and replaces the "My Application" content if found.
146
+
147
+ <ht key="my" app="Program">My Application</ht>
148
+
149
+ Will look up both the "my"- and "app"-key for your locale, and replaces the "My Application" with the "my"-key contents (interpolated using the "app"-key.
150
+
151
+ sample.no.yml-file:
152
+
153
+ "no":
154
+ my: "Mitt {{app}}"
155
+
156
+ The output should be: Mitt Program
157
+
158
+ Another example:
159
+
160
+ <%= ht :key=>'user.index.title', :default=>'Index' %>
161
+ <ht key="user.index.title">Index</ht>
162
+ #=> "Index" # if "user.index.title" or "hobo.index.title" is not found
163
+ #=> "User Index" # with the below en.yml file
164
+
165
+ === en.yml ===
166
+ en:
167
+ hobo:
168
+ index:
169
+ title: %{model} Index
170
+ -->
171
+ <fakedef tag="ht">
172
+ <!-- actually defined in translations.rb -->
173
+ </fakedef>
@@ -25,7 +25,9 @@ Transitions with parameters are implemented using a form. HTML does not allow f
25
25
 
26
26
  html_attributes[:method] ||= has_params ? :get : :put
27
27
  add_classes!(html_attributes, "transition-button #{transition_name}-button")
28
- label = ht("#{this.class.to_s.underscore}.actions.#{transition_name}", :default => (label || transition_name.to_s.titleize))
28
+ label = t("activerecord.attributes.#{this.class.to_s.underscore}.lifecycle.transitions.#{transition_name}", :default => (label || transition_name.to_s.titleize))
29
+ title = t("activerecord.attribute_help.#{this.class.to_s.underscore}.lifecycle.transitions.#{transition_name}")
30
+ html_attributes.update(:title => title) unless title.empty?
29
31
  url = object_url(this, transition_name, :method => html_attributes[:method])
30
32
 
31
33
  if (update || !ajax_attributes.empty?) && !has_params
@@ -55,10 +55,10 @@ The easiest way to see what this tag does is to look at the source.
55
55
 
56
56
  <!-- Renderes dynamically generated JavaScript required by `hobo-rapid.js`, including the information required to perform automatic part updates -->
57
57
  <def tag="page-scripts">
58
- <script type="text/javascript" param="default">
58
+ <do param="default">
59
59
  <hobo-rapid-javascripts/>
60
- <part-contexts-storage/>
61
- </script>
60
+ <part-contexts-javascripts/>
61
+ </do>
62
62
  </def>
63
63
 
64
64
 
@@ -13,7 +13,7 @@ An [worked example](/tutorials/agility#improve_the_project_page_with_a_searchabl
13
13
  <div class="table-plus" merge-attrs="&attributes - attrs_for(:with_fields) - attrs_for(:table)">
14
14
  <div class="header" param="header">
15
15
  <div class="search">
16
- <form param="search-form" method="get" action="">
16
+ <form param="search-form" method="get" action="" with="&nil">
17
17
  <hidden-fields for-query-string skip="page, search"/>
18
18
  <span><t key="hobo.table_plus.search">Search</t></span>
19
19
  <input class="search" type="search" name="search" value="&params[:search]"/>
@@ -31,9 +31,9 @@ An [worked example](/tutorials/agility#improve_the_project_page_with_a_searchabl
31
31
  sort_url = url_for_page_path(params.merge(:sort => sort) - [:page])
32
32
  col_heading_name = this.member_class.try.human_attribute_name(scope.field_name, :default=> scope.field_name.titleize) %>
33
33
 
34
- <th param="#{scope.field-name}-heading">
34
+ <th param="#{scope.field_name}-heading">
35
35
  <a href="&sort_url" class="column-sort"
36
- param="#{scope.field-name}-heading-link"><%= col_heading_name %></a>
36
+ param="#{scope.field_name}-heading-link"><%= col_heading_name %></a>
37
37
  <if test="&col == sort_field">
38
38
  <do param="up-arrow" if="&sort_direction == 'desc'">&uarr;</do>
39
39
  <do param="down-arrow" if="&sort_direction == 'asc'">&darr;</do>
@@ -177,60 +177,64 @@ See [Filtering stories by status](/tutorials/agility#filtering_stories_by_status
177
177
 
178
178
  ### I18n
179
179
 
180
- It lookups the options attributes in "activerecord.attributes.#{model}.filter_menu.#{param\_name}.options"
181
- with fallback to "filter_menu.#{param_name}.options".
180
+ It lookups the options attributes in `activerecord.attributes.#{model}.filter_menu.#{param\_name}.options`
181
+ with fallback to `filter_menu.#{param_name}.options`.
182
182
  The passed options are used as a default in case the lookup fails.
183
- Besides the "activerecord.attributes.#{model}.filter_menu.#{param_name}.no_filter" or
184
- "tags.filter_menu.default.no_filter" key is used as default of the attribute "no-filter"
183
+ Besides the `activerecord.attributes.#{model}.filter_menu.#{param_name}.no_filter` or
184
+ `tags.filter_menu.default.no_filter` key is used as default of the attribute "no-filter"
185
185
  (or "All" if no default is found)
186
186
 
187
187
  ### I18n Example
188
188
 
189
189
 
190
- es:
191
- activerecord:
192
- attributes:
193
- <model_name>:
194
- filter_menu:
195
- period:
196
- no_filter: Todos Períodos
197
- options:
198
- - [ "Hoy", "today" ]
199
- - [ "Ayer", "yesterday" ]
190
+ es:
191
+ activerecord:
192
+ attributes:
193
+ <model_name>:
194
+ filter_menu:
195
+ period:
196
+ no_filter: Todos Períodos
197
+ options:
198
+ - [ "Hoy", "today" ]
199
+ - [ "Ayer", "yesterday" ]
200
200
 
201
201
  or
202
202
 
203
- es:
204
- tags:
205
- filter_menu:
206
- period:
207
- no_filter: Todos Períodos
208
- options:
209
- - [ "Hoy", "today" ]
210
- - [ "Ayer", "yesterday" ]
211
-
212
- TIME_PERIODS = %w[today yesterday]
213
-
214
- <t-filter-menu param-name="period" options="&TIME_PERIODS" no-filter="All Periods"/>
215
-
216
- with I18n.locale == :es
217
- <select name="period">
218
- <option value="">Todos Períodos</option>
219
- <option value="today">Hoy</option>
220
- <option value="yesterday">Ayer</option>
221
- </select>
222
-
223
- with I18n.locale == :en (i.e no locale file)
224
- <select name="period">
225
- <option value="">All Periods</option>
226
- <option value="today">today</option>
227
- <option value="yesterday">yesterday</option>
228
- </select>
203
+ es:
204
+ tags:
205
+ filter_menu:
206
+ period:
207
+ no_filter: Todos Períodos
208
+ options:
209
+ - [ "Hoy", "today" ]
210
+ - [ "Ayer", "yesterday" ]
211
+
212
+
213
+ TIME_PERIODS = %w[today yesterday]
214
+
215
+ <t-filter-menu param-name="period" options="&TIME_PERIODS" no-filter="All Periods"/>
216
+
217
+ with I18n.locale == :es
218
+
219
+ <select name="period">
220
+ <option value="">Todos Períodos</option>
221
+ <option value="today">Hoy</option>
222
+ <option value="yesterday">Ayer</option>
223
+ </select>
224
+
225
+ with I18n.locale == :en (i.e no locale file)
226
+
227
+ <select name="period">
228
+ <option value="">All Periods</option>
229
+ <option value="today">today</option>
230
+ <option value="yesterday">yesterday</option>
231
+ </select>
229
232
 
230
233
  -->
231
234
  <def tag="filter-menu" attrs="model, param-name, options, no-filter, id, first-value">
232
- <% opt = t("activerecord.attributes.#{model}.filter_menu.#{param_name}.options", :default=>[:"tags.filter_menu.#{param_name}.options"])
233
- options = opt unless opt.blank?
235
+ <% options = t("activerecord.attributes.#{model}.filter_menu.#{param_name}.options", :default=>[:"tags.filter_menu.#{param_name}.options", options])
236
+ raise ArgumentError, %(You must provide an "options" attribute, or set "activerecord.attributes.#{model}.filter_menu.#{param_name}.options" or "tags.filter_menu.#{param_name}.options" to an Array or to an Array of Arrays
237
+ in your locale file(s)) unless options.is_a?(Array)
234
238
  no_filter = t("activerecord.attributes.#{model}.filter_menu.#{param_name}.no_filter", :default=>[:"tags.filter_menu.#{param_name}.no_filter", :"tags.filter_menu.default.no_filter", no_filter, "All"]) %>
235
239
  <form action="&request.fullpath" method="get" class="filter-menu" merge-attrs="id">
236
240
  <div>