compony 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/CHANGELOG.md +7 -0
  4. data/Gemfile.lock +6 -6
  5. data/README.md +36 -0
  6. data/VERSION +1 -1
  7. data/app/controllers/compony_controller.rb +4 -0
  8. data/compony.gemspec +4 -4
  9. data/doc/ComponentGenerator.html +1 -1
  10. data/doc/Components.html +1 -1
  11. data/doc/ComponentsGenerator.html +1 -1
  12. data/doc/Compony/Component.html +1 -1
  13. data/doc/Compony/ComponentMixins/Default/Labelling.html +1 -1
  14. data/doc/Compony/ComponentMixins/Default/Standalone/ResourcefulVerbDsl.html +1 -1
  15. data/doc/Compony/ComponentMixins/Default/Standalone/StandaloneDsl.html +96 -27
  16. data/doc/Compony/ComponentMixins/Default/Standalone/VerbDsl.html +1 -1
  17. data/doc/Compony/ComponentMixins/Default/Standalone.html +1 -1
  18. data/doc/Compony/ComponentMixins/Default.html +1 -1
  19. data/doc/Compony/ComponentMixins/Resourceful.html +1 -1
  20. data/doc/Compony/ComponentMixins.html +1 -1
  21. data/doc/Compony/Components/Button.html +1 -1
  22. data/doc/Compony/Components/Destroy.html +1 -1
  23. data/doc/Compony/Components/Edit.html +1 -1
  24. data/doc/Compony/Components/Form.html +210 -127
  25. data/doc/Compony/Components/New.html +1 -1
  26. data/doc/Compony/Components/WithForm.html +1 -1
  27. data/doc/Compony/Components.html +1 -1
  28. data/doc/Compony/ControllerMixin.html +1 -1
  29. data/doc/Compony/Engine.html +1 -1
  30. data/doc/Compony/MethodAccessibleHash.html +1 -1
  31. data/doc/Compony/ModelFields/Anchormodel.html +1 -1
  32. data/doc/Compony/ModelFields/Association.html +1 -1
  33. data/doc/Compony/ModelFields/Attachment.html +1 -1
  34. data/doc/Compony/ModelFields/Base.html +1 -1
  35. data/doc/Compony/ModelFields/Boolean.html +1 -1
  36. data/doc/Compony/ModelFields/Color.html +1 -1
  37. data/doc/Compony/ModelFields/Currency.html +1 -1
  38. data/doc/Compony/ModelFields/Date.html +1 -1
  39. data/doc/Compony/ModelFields/Datetime.html +1 -1
  40. data/doc/Compony/ModelFields/Decimal.html +1 -1
  41. data/doc/Compony/ModelFields/Email.html +1 -1
  42. data/doc/Compony/ModelFields/Float.html +1 -1
  43. data/doc/Compony/ModelFields/Integer.html +1 -1
  44. data/doc/Compony/ModelFields/Percentage.html +1 -1
  45. data/doc/Compony/ModelFields/Phone.html +1 -1
  46. data/doc/Compony/ModelFields/RichText.html +1 -1
  47. data/doc/Compony/ModelFields/String.html +1 -1
  48. data/doc/Compony/ModelFields/Text.html +1 -1
  49. data/doc/Compony/ModelFields/Time.html +1 -1
  50. data/doc/Compony/ModelFields/Url.html +1 -1
  51. data/doc/Compony/ModelFields.html +1 -1
  52. data/doc/Compony/ModelMixin.html +25 -25
  53. data/doc/Compony/NaturalOrdering.html +1 -1
  54. data/doc/Compony/RequestContext.html +1 -1
  55. data/doc/Compony/Version.html +1 -1
  56. data/doc/Compony/ViewHelpers.html +1 -1
  57. data/doc/Compony.html +3 -3
  58. data/doc/ComponyController.html +1 -1
  59. data/doc/_index.html +1 -1
  60. data/doc/file.README.html +36 -1
  61. data/doc/index.html +36 -1
  62. data/doc/method_list.html +112 -96
  63. data/doc/top-level-namespace.html +1 -1
  64. data/lib/compony/component_mixins/default/standalone/standalone_dsl.rb +18 -10
  65. data/lib/compony/components/form.rb +49 -32
  66. data/lib/compony/model_mixin.rb +19 -13
  67. data/lib/compony.rb +2 -2
  68. metadata +3 -9
@@ -102,7 +102,7 @@
102
102
  </div>
103
103
 
104
104
  <div id="footer">
105
- Generated on Fri Dec 20 13:46:32 2024 by
105
+ Generated on Fri Feb 14 13:24:11 2025 by
106
106
  <a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
107
107
  0.9.37 (ruby-3.3.5).
108
108
  </div>
@@ -17,6 +17,7 @@ module Compony
17
17
  @scope_args = scope_args
18
18
  @verbs = {}
19
19
  @skip_authentication = false
20
+ @skip_forgery_protection = false
20
21
  @layout = true # can be overriden by false or a string
21
22
  end
22
23
 
@@ -25,16 +26,17 @@ module Compony
25
26
  evaluate(&block)
26
27
  @component = block.binding.eval('self') # Fetches the component holding this DSL call (via the block)
27
28
  return {
28
- name: @name,
29
- path: @path,
30
- constraints: @constraints,
31
- scope: @scope,
32
- scope_args: @scope_args,
33
- verbs: @verbs,
34
- rails_action_name: Compony.rails_action_name(comp_name, family_name, @name),
35
- path_helper_name: Compony.path_helper_name(comp_name, family_name, @name),
36
- skip_authentication: @skip_authentication,
37
- layout: @layout
29
+ name: @name,
30
+ path: @path,
31
+ constraints: @constraints,
32
+ scope: @scope,
33
+ scope_args: @scope_args,
34
+ verbs: @verbs,
35
+ rails_action_name: Compony.rails_action_name(comp_name, family_name, @name),
36
+ path_helper_name: Compony.path_helper_name(comp_name, family_name, @name),
37
+ skip_authentication: @skip_authentication,
38
+ skip_forgery_protection: @skip_forgery_protection,
39
+ layout: @layout
38
40
  }.compact
39
41
  end
40
42
 
@@ -65,6 +67,12 @@ module Compony
65
67
  @skip_authentication = true
66
68
  end
67
69
 
70
+ # DSL
71
+ # Defines that for this component, no forgery protection (CSRF) should be performed.
72
+ def skip_forgery_protection!
73
+ @skip_forgery_protection = true
74
+ end
75
+
68
76
  # DSL
69
77
  # Speficies the Rails layout (under `app/views/layouts`) that should be used to render this component.
70
78
  # Defaults to Rails' default (`layouts/application`) if the method is never called.
@@ -36,7 +36,8 @@ module Compony
36
36
  end
37
37
 
38
38
  content do
39
- form_html = simple_form_for(data, method: @comp_opts[:submit_verb], url: @submit_path) do |f|
39
+ form_params = { method: @comp_opts[:submit_verb], url: @submit_path }.merge(@form_params || {})
40
+ form_html = simple_form_for(data, **form_params) do |f|
40
41
  component.with_simpleform(f, controller) do
41
42
  instance_exec(&form_fields)
42
43
  div class: 'compony-form-buttons' do
@@ -95,32 +96,38 @@ module Compony
95
96
 
96
97
  # Called inside the form_fields block. This makes the method `field` available in the block.
97
98
  # See also notes for `with_simpleform`.
98
- def field(name, **input_opts)
99
+ # If multilang is true, a suffixed field is generated for every available locale (useful with gem "mobility"). Render the array as you wish.
100
+ def field(name, multilang: false, **input_opts)
99
101
  fail("The `field` method may only be called inside `form_fields` for #{inspect}.") unless @simpleform
100
- name = name.to_sym
101
102
 
102
- input_opts.merge!(disabled: true) if @form_disabled
103
+ if multilang
104
+ I18n.available_locales.map { |locale| field("#{name}_#{locale}", **input_opts) }
105
+ else
106
+ name = name.to_sym
103
107
 
104
- # Check per-field authorization
105
- if @cancancan_action.present? && @controller.current_ability.permitted_attributes(@cancancan_action, @simpleform.object).exclude?(name)
106
- Rails.logger.debug do
107
- "Skipping form field #{name.inspect} because the current user is not allowed to perform #{@cancancan_action.inspect} on #{@simpleform.object}."
108
+ input_opts.merge!(disabled: true) if @form_disabled
109
+
110
+ # Check per-field authorization
111
+ if @cancancan_action.present? && @controller.current_ability.permitted_attributes(@cancancan_action, @simpleform.object).exclude?(name)
112
+ Rails.logger.debug do
113
+ "Skipping form field #{name.inspect} because the current user is not allowed to perform #{@cancancan_action.inspect} on #{@simpleform.object}."
114
+ end
115
+ return
108
116
  end
109
- return
110
- end
111
117
 
112
- hidden = input_opts.delete(:hidden)
113
- model_field = @simpleform.object.fields[name]
114
- fail("Field #{name.inspect} is not defined on #{@simpleform.object.inspect} but was requested in #{inspect}.") unless model_field
118
+ hidden = input_opts.delete(:hidden)
119
+ model_field = @simpleform.object.fields[name]
120
+ fail("Field #{name.inspect} is not defined on #{@simpleform.object.inspect} but was requested in #{inspect}.") unless model_field
115
121
 
116
- if hidden
117
- return model_field.simpleform_input_hidden(@simpleform, self, **input_opts)
118
- else
119
- unless @focus_given || @skip_autofocus
120
- input_opts[:autofocus] = true unless input_opts.key? :autofocus
121
- @focus_given = true
122
+ if hidden
123
+ return model_field.simpleform_input_hidden(@simpleform, self, **input_opts)
124
+ else
125
+ unless @focus_given || @skip_autofocus
126
+ input_opts[:autofocus] = true unless input_opts.key? :autofocus
127
+ @focus_given = true
128
+ end
129
+ return model_field.simpleform_input(@simpleform, self, **input_opts)
122
130
  end
123
- return model_field.simpleform_input(@simpleform, self, **input_opts)
124
131
  end
125
132
  end
126
133
 
@@ -163,6 +170,11 @@ module Compony
163
170
  @form_disabled = true
164
171
  end
165
172
 
173
+ # DSL method, allows to customize parameters given to simple_form_for
174
+ def form_params(**new_form_params)
175
+ @form_params = new_form_params
176
+ end
177
+
166
178
  protected
167
179
 
168
180
  # DSL method, adds a new line to the schema whitelisting a single param inside the schema's wrapper
@@ -173,19 +185,24 @@ module Compony
173
185
 
174
186
  # DSL method, adds a new field to the schema whitelisting a single field of data_class
175
187
  # This auto-generates the correct schema line for the field.
176
- def schema_field(field_name)
177
- # This runs upon component setup.
178
- @schema_lines_for_data << proc do |data, controller|
179
- # This runs within a request context.
180
- field = data.class.fields[field_name.to_sym] || fail("No field #{field_name.to_sym.inspect} found for #{data.inspect} in #{inspect}.")
181
- # Check per-field authorization
182
- if @cancancan_action.present? && controller.current_ability.permitted_attributes(@cancancan_action.to_sym, data).exclude?(field.name.to_sym)
183
- Rails.logger.debug do
184
- "Skipping form schema_field #{field_name.inspect} because the current user is not allowed to perform #{@cancancan_action.inspect} on #{data}."
188
+ # If multilang is true, a suffixed field is generated for every available locale (useful with gem "mobility")
189
+ def schema_field(field_name, multilang: false)
190
+ if multilang
191
+ I18n.available_locales.each { |locale| schema_field("#{field_name}_#{locale}") }
192
+ else
193
+ # This runs upon component setup.
194
+ @schema_lines_for_data << proc do |data, controller|
195
+ # This runs within a request context.
196
+ field = data.class.fields[field_name.to_sym] || fail("No field #{field_name.to_sym.inspect} found for #{data.inspect} in #{inspect}.")
197
+ # Check per-field authorization
198
+ if @cancancan_action.present? && controller.current_ability.permitted_attributes(@cancancan_action.to_sym, data).exclude?(field.name.to_sym)
199
+ Rails.logger.debug do
200
+ "Skipping form schema_field #{field_name.inspect} because the current user is not allowed to perform #{@cancancan_action.inspect} on #{data}."
201
+ end
202
+ next nil
185
203
  end
186
- next nil
204
+ next field.schema_line
187
205
  end
188
- next field.schema_line
189
206
  end
190
207
  end
191
208
 
@@ -198,7 +215,7 @@ module Compony
198
215
  # Check per-field authorization
199
216
  unless @cancancan_action.nil? || controller.current_ability.can?(:set_password, data)
200
217
  Rails.logger.debug do
201
- "Skipping form schema_pw_field #{name.inspect} because the current user is not allowed to perform :set_password on #{data}."
218
+ "Skipping form schema_pw_field #{field_name.inspect} because the current user is not allowed to perform :set_password on #{data}."
202
219
  end
203
220
  next nil
204
221
  end
@@ -19,21 +19,27 @@ module Compony
19
19
  end
20
20
 
21
21
  # DSL method, defines a new field which will be translated and can be added to field groups
22
- def field(name, type, **extra_attrs)
23
- name = name.to_sym
24
- self.fields = fields.dup
25
- field = Compony.model_field_class_for(type.to_s.camelize).new(name, self, **extra_attrs)
26
- # Handle the case where ActiveType would interfere with attribute registration
27
- if defined?(ActiveType) && self <= ActiveType::Object && !include?(ActiveModel::Attributes)
28
- fail "Please add `include ActiveModel::Attributes` at the top of the class #{self}, as attributes cannot be registered otherwise with ActiveType."
29
- end
30
- # Register the field as an attribute
31
- if defined?(ActiveType) && self <= ActiveType::Object
32
- ar_attribute(name)
22
+ # If multilang is true, a suffixed field is generated for every available locale, along with a non-suffixed virtual field (useful with gem "mobility")
23
+ def field(name, type, multilang: false, **extra_attrs)
24
+ if multilang
25
+ field(name, type, virtual: true, **extra_attrs)
26
+ I18n.available_locales.each { |locale| field("#{name}_#{locale}", type, **extra_attrs) }
33
27
  else
34
- attribute(name)
28
+ name = name.to_sym
29
+ self.fields = fields.dup
30
+ field = Compony.model_field_class_for(type.to_s.camelize).new(name, self, **extra_attrs)
31
+ # Handle the case where ActiveType would interfere with attribute registration
32
+ if defined?(ActiveType) && self <= ActiveType::Object && !include?(ActiveModel::Attributes)
33
+ fail "Please add `include ActiveModel::Attributes` at the top of the class #{self}, as attributes cannot be registered otherwise with ActiveType."
34
+ end
35
+ # Register the field as an attribute
36
+ if defined?(ActiveType) && self <= ActiveType::Object
37
+ ar_attribute(name)
38
+ else
39
+ attribute(name)
40
+ end
41
+ fields[name] = field
35
42
  end
36
- fields[name] = field
37
43
  end
38
44
 
39
45
  # DSL method, sets the containing model.
data/lib/compony.rb CHANGED
@@ -79,13 +79,13 @@ module Compony
79
79
  end
80
80
 
81
81
  # Getter for content_before_root_comp_block
82
- # @see Compony#content_before_root_comp
82
+ # @see Compony#content_before_root_comp=
83
83
  def self.content_before_root_comp_block
84
84
  @content_before_root_comp_block
85
85
  end
86
86
 
87
87
  # Getter for content_after_root_comp_block
88
- # @see Compony#content_after_root_comp
88
+ # @see Compony#content_after_root_comp=
89
89
  def self.content_after_root_comp_block
90
90
  @content_after_root_comp_block
91
91
  end
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: compony
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sandro Kalbermatter
8
8
  - contributors
9
- autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2024-12-20 00:00:00.000000000 Z
11
+ date: 2025-02-14 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: yard
@@ -165,8 +164,6 @@ dependencies:
165
164
  - - "~>"
166
165
  - !ruby/object:Gem::Version
167
166
  version: 3.6.1
168
- description:
169
- email:
170
167
  executables: []
171
168
  extensions: []
172
169
  extra_rdoc_files: []
@@ -312,10 +309,8 @@ files:
312
309
  - lib/generators/components/USAGE
313
310
  - lib/generators/components/components_generator.rb
314
311
  - logo.svg
315
- homepage:
316
312
  licenses: []
317
313
  metadata: {}
318
- post_install_message:
319
314
  rdoc_options: []
320
315
  require_paths:
321
316
  - lib
@@ -330,8 +325,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
330
325
  - !ruby/object:Gem::Version
331
326
  version: '0'
332
327
  requirements: []
333
- rubygems_version: 3.5.22
334
- signing_key:
328
+ rubygems_version: 3.6.3
335
329
  specification_version: 4
336
330
  summary: Compony is a Gem that allows you to write your Rails application in component-style
337
331
  fashion. It combines a controller action and route along \ with its view into a