phlexible 2.2.0 → 3.0.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -7
- data/.ruby-version +1 -0
- data/Appraisals +11 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +130 -42
- data/README.md +20 -1
- data/config/render_helper.rb +27 -0
- data/config/sus.rb +1 -1
- data/fixtures/rails_helper.rb +1 -0
- data/gemfiles/.bundle/config +2 -0
- data/gemfiles/phlex_1.gemfile +14 -0
- data/gemfiles/phlex_1.gemfile.lock +253 -0
- data/gemfiles/phlex_2.gemfile +14 -0
- data/gemfiles/phlex_2.gemfile.lock +254 -0
- data/lib/phlexible/rails/a_element.rb +7 -1
- data/lib/phlexible/rails/button_to.rb +0 -113
- data/lib/phlexible/rails/button_to_concerns.rb +140 -0
- data/lib/phlexible/rails/controller_variables.rb +6 -3
- data/lib/phlexible/rails/meta_tags_component.rb +3 -1
- data/lib/phlexible/rails/view_assigns.rb +17 -0
- data/lib/phlexible/version.rb +1 -1
- data/lib/phlexible.rb +6 -5
- data/phlexible.gemspec +4 -2
- metadata +56 -11
- data/config/view_helper.rb +0 -16
- data/lib/phlexible/rails.rb +0 -20
@@ -0,0 +1,14 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "appraisal"
|
6
|
+
gem "combustion"
|
7
|
+
gem "debug"
|
8
|
+
gem "rake", "~> 13.0"
|
9
|
+
gem "rubocop", "~> 1.55"
|
10
|
+
gem "sus"
|
11
|
+
gem "phlex", ">= 2.1.0", "< 3.0.0"
|
12
|
+
gem "phlex-rails", ">= 2.1.0", "< 3.0.0"
|
13
|
+
|
14
|
+
gemspec path: "../"
|
@@ -0,0 +1,254 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ..
|
3
|
+
specs:
|
4
|
+
phlexible (2.2.0)
|
5
|
+
phlex (>= 1.10.0, < 3.0.0)
|
6
|
+
phlex-rails (>= 1.2.0, < 3.0.0)
|
7
|
+
rails (>= 7.2.0, < 9.0.0)
|
8
|
+
zeitwerk (~> 2.7.2)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
actioncable (8.0.2)
|
14
|
+
actionpack (= 8.0.2)
|
15
|
+
activesupport (= 8.0.2)
|
16
|
+
nio4r (~> 2.0)
|
17
|
+
websocket-driver (>= 0.6.1)
|
18
|
+
zeitwerk (~> 2.6)
|
19
|
+
actionmailbox (8.0.2)
|
20
|
+
actionpack (= 8.0.2)
|
21
|
+
activejob (= 8.0.2)
|
22
|
+
activerecord (= 8.0.2)
|
23
|
+
activestorage (= 8.0.2)
|
24
|
+
activesupport (= 8.0.2)
|
25
|
+
mail (>= 2.8.0)
|
26
|
+
actionmailer (8.0.2)
|
27
|
+
actionpack (= 8.0.2)
|
28
|
+
actionview (= 8.0.2)
|
29
|
+
activejob (= 8.0.2)
|
30
|
+
activesupport (= 8.0.2)
|
31
|
+
mail (>= 2.8.0)
|
32
|
+
rails-dom-testing (~> 2.2)
|
33
|
+
actionpack (8.0.2)
|
34
|
+
actionview (= 8.0.2)
|
35
|
+
activesupport (= 8.0.2)
|
36
|
+
nokogiri (>= 1.8.5)
|
37
|
+
rack (>= 2.2.4)
|
38
|
+
rack-session (>= 1.0.1)
|
39
|
+
rack-test (>= 0.6.3)
|
40
|
+
rails-dom-testing (~> 2.2)
|
41
|
+
rails-html-sanitizer (~> 1.6)
|
42
|
+
useragent (~> 0.16)
|
43
|
+
actiontext (8.0.2)
|
44
|
+
actionpack (= 8.0.2)
|
45
|
+
activerecord (= 8.0.2)
|
46
|
+
activestorage (= 8.0.2)
|
47
|
+
activesupport (= 8.0.2)
|
48
|
+
globalid (>= 0.6.0)
|
49
|
+
nokogiri (>= 1.8.5)
|
50
|
+
actionview (8.0.2)
|
51
|
+
activesupport (= 8.0.2)
|
52
|
+
builder (~> 3.1)
|
53
|
+
erubi (~> 1.11)
|
54
|
+
rails-dom-testing (~> 2.2)
|
55
|
+
rails-html-sanitizer (~> 1.6)
|
56
|
+
activejob (8.0.2)
|
57
|
+
activesupport (= 8.0.2)
|
58
|
+
globalid (>= 0.3.6)
|
59
|
+
activemodel (8.0.2)
|
60
|
+
activesupport (= 8.0.2)
|
61
|
+
activerecord (8.0.2)
|
62
|
+
activemodel (= 8.0.2)
|
63
|
+
activesupport (= 8.0.2)
|
64
|
+
timeout (>= 0.4.0)
|
65
|
+
activestorage (8.0.2)
|
66
|
+
actionpack (= 8.0.2)
|
67
|
+
activejob (= 8.0.2)
|
68
|
+
activerecord (= 8.0.2)
|
69
|
+
activesupport (= 8.0.2)
|
70
|
+
marcel (~> 1.0)
|
71
|
+
activesupport (8.0.2)
|
72
|
+
base64
|
73
|
+
benchmark (>= 0.3)
|
74
|
+
bigdecimal
|
75
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
76
|
+
connection_pool (>= 2.2.5)
|
77
|
+
drb
|
78
|
+
i18n (>= 1.6, < 2)
|
79
|
+
logger (>= 1.4.2)
|
80
|
+
minitest (>= 5.1)
|
81
|
+
securerandom (>= 0.3)
|
82
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
83
|
+
uri (>= 0.13.1)
|
84
|
+
appraisal (2.5.0)
|
85
|
+
bundler
|
86
|
+
rake
|
87
|
+
thor (>= 0.14.0)
|
88
|
+
ast (2.4.3)
|
89
|
+
base64 (0.2.0)
|
90
|
+
benchmark (0.4.0)
|
91
|
+
bigdecimal (3.1.9)
|
92
|
+
builder (3.3.0)
|
93
|
+
combustion (1.5.0)
|
94
|
+
activesupport (>= 3.0.0)
|
95
|
+
railties (>= 3.0.0)
|
96
|
+
thor (>= 0.14.6)
|
97
|
+
concurrent-ruby (1.3.5)
|
98
|
+
connection_pool (2.5.1)
|
99
|
+
crass (1.0.6)
|
100
|
+
date (3.4.1)
|
101
|
+
debug (1.10.0)
|
102
|
+
irb (~> 1.10)
|
103
|
+
reline (>= 0.3.8)
|
104
|
+
drb (2.2.1)
|
105
|
+
erubi (1.13.1)
|
106
|
+
globalid (1.2.1)
|
107
|
+
activesupport (>= 6.1)
|
108
|
+
i18n (1.14.7)
|
109
|
+
concurrent-ruby (~> 1.0)
|
110
|
+
io-console (0.8.0)
|
111
|
+
irb (1.15.2)
|
112
|
+
pp (>= 0.6.0)
|
113
|
+
rdoc (>= 4.0.0)
|
114
|
+
reline (>= 0.4.2)
|
115
|
+
json (2.10.2)
|
116
|
+
language_server-protocol (3.17.0.4)
|
117
|
+
lint_roller (1.1.0)
|
118
|
+
logger (1.7.0)
|
119
|
+
loofah (2.24.0)
|
120
|
+
crass (~> 1.0.2)
|
121
|
+
nokogiri (>= 1.12.0)
|
122
|
+
mail (2.8.1)
|
123
|
+
mini_mime (>= 0.1.1)
|
124
|
+
net-imap
|
125
|
+
net-pop
|
126
|
+
net-smtp
|
127
|
+
marcel (1.0.4)
|
128
|
+
mini_mime (1.1.5)
|
129
|
+
minitest (5.25.5)
|
130
|
+
net-imap (0.5.7)
|
131
|
+
date
|
132
|
+
net-protocol
|
133
|
+
net-pop (0.1.2)
|
134
|
+
net-protocol
|
135
|
+
net-protocol (0.2.2)
|
136
|
+
timeout
|
137
|
+
net-smtp (0.5.1)
|
138
|
+
net-protocol
|
139
|
+
nio4r (2.7.4)
|
140
|
+
nokogiri (1.18.8-arm64-darwin)
|
141
|
+
racc (~> 1.4)
|
142
|
+
nokogiri (1.18.8-x86_64-linux-gnu)
|
143
|
+
racc (~> 1.4)
|
144
|
+
parallel (1.27.0)
|
145
|
+
parser (3.3.8.0)
|
146
|
+
ast (~> 2.4.1)
|
147
|
+
racc
|
148
|
+
phlex (2.2.1)
|
149
|
+
zeitwerk (~> 2.7)
|
150
|
+
phlex-rails (2.2.0)
|
151
|
+
phlex (~> 2.2.1)
|
152
|
+
railties (>= 7.1, < 9)
|
153
|
+
pp (0.6.2)
|
154
|
+
prettyprint
|
155
|
+
prettyprint (0.2.0)
|
156
|
+
prism (1.4.0)
|
157
|
+
psych (5.2.3)
|
158
|
+
date
|
159
|
+
stringio
|
160
|
+
racc (1.8.1)
|
161
|
+
rack (3.1.13)
|
162
|
+
rack-session (2.1.0)
|
163
|
+
base64 (>= 0.1.0)
|
164
|
+
rack (>= 3.0.0)
|
165
|
+
rack-test (2.2.0)
|
166
|
+
rack (>= 1.3)
|
167
|
+
rackup (2.2.1)
|
168
|
+
rack (>= 3)
|
169
|
+
rails (8.0.2)
|
170
|
+
actioncable (= 8.0.2)
|
171
|
+
actionmailbox (= 8.0.2)
|
172
|
+
actionmailer (= 8.0.2)
|
173
|
+
actionpack (= 8.0.2)
|
174
|
+
actiontext (= 8.0.2)
|
175
|
+
actionview (= 8.0.2)
|
176
|
+
activejob (= 8.0.2)
|
177
|
+
activemodel (= 8.0.2)
|
178
|
+
activerecord (= 8.0.2)
|
179
|
+
activestorage (= 8.0.2)
|
180
|
+
activesupport (= 8.0.2)
|
181
|
+
bundler (>= 1.15.0)
|
182
|
+
railties (= 8.0.2)
|
183
|
+
rails-dom-testing (2.2.0)
|
184
|
+
activesupport (>= 5.0.0)
|
185
|
+
minitest
|
186
|
+
nokogiri (>= 1.6)
|
187
|
+
rails-html-sanitizer (1.6.2)
|
188
|
+
loofah (~> 2.21)
|
189
|
+
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
190
|
+
railties (8.0.2)
|
191
|
+
actionpack (= 8.0.2)
|
192
|
+
activesupport (= 8.0.2)
|
193
|
+
irb (~> 1.13)
|
194
|
+
rackup (>= 1.0.0)
|
195
|
+
rake (>= 12.2)
|
196
|
+
thor (~> 1.0, >= 1.2.2)
|
197
|
+
zeitwerk (~> 2.6)
|
198
|
+
rainbow (3.1.1)
|
199
|
+
rake (13.2.1)
|
200
|
+
rdoc (6.13.1)
|
201
|
+
psych (>= 4.0.0)
|
202
|
+
regexp_parser (2.10.0)
|
203
|
+
reline (0.6.1)
|
204
|
+
io-console (~> 0.5)
|
205
|
+
rubocop (1.75.3)
|
206
|
+
json (~> 2.3)
|
207
|
+
language_server-protocol (~> 3.17.0.2)
|
208
|
+
lint_roller (~> 1.1.0)
|
209
|
+
parallel (~> 1.10)
|
210
|
+
parser (>= 3.3.0.2)
|
211
|
+
rainbow (>= 2.2.2, < 4.0)
|
212
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
213
|
+
rubocop-ast (>= 1.44.0, < 2.0)
|
214
|
+
ruby-progressbar (~> 1.7)
|
215
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
216
|
+
rubocop-ast (1.44.1)
|
217
|
+
parser (>= 3.3.7.2)
|
218
|
+
prism (~> 1.4)
|
219
|
+
ruby-progressbar (1.13.0)
|
220
|
+
securerandom (0.4.1)
|
221
|
+
stringio (3.1.7)
|
222
|
+
sus (0.32.0)
|
223
|
+
thor (1.3.2)
|
224
|
+
timeout (0.4.3)
|
225
|
+
tzinfo (2.0.6)
|
226
|
+
concurrent-ruby (~> 1.0)
|
227
|
+
unicode-display_width (3.1.4)
|
228
|
+
unicode-emoji (~> 4.0, >= 4.0.4)
|
229
|
+
unicode-emoji (4.0.4)
|
230
|
+
uri (1.0.3)
|
231
|
+
useragent (0.16.11)
|
232
|
+
websocket-driver (0.7.7)
|
233
|
+
base64
|
234
|
+
websocket-extensions (>= 0.1.0)
|
235
|
+
websocket-extensions (0.1.5)
|
236
|
+
zeitwerk (2.7.2)
|
237
|
+
|
238
|
+
PLATFORMS
|
239
|
+
arm64-darwin-24
|
240
|
+
x86_64-linux
|
241
|
+
|
242
|
+
DEPENDENCIES
|
243
|
+
appraisal
|
244
|
+
combustion
|
245
|
+
debug
|
246
|
+
phlex (>= 2.1.0, < 3.0.0)
|
247
|
+
phlex-rails (>= 2.1.0, < 3.0.0)
|
248
|
+
phlexible!
|
249
|
+
rake (~> 13.0)
|
250
|
+
rubocop (~> 1.55)
|
251
|
+
sus
|
252
|
+
|
253
|
+
BUNDLED WITH
|
254
|
+
2.4.1
|
@@ -4,8 +4,14 @@ module Phlexible
|
|
4
4
|
module Rails
|
5
5
|
# Calls `url_for` for the `href` attribute.
|
6
6
|
module AElement
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
include Phlex::Rails::Helpers::URLFor
|
11
|
+
end
|
12
|
+
|
7
13
|
def a(href:, **, &)
|
8
|
-
super(href:
|
14
|
+
super(href: url_for(href), **, &)
|
9
15
|
end
|
10
16
|
end
|
11
17
|
end
|
@@ -15,119 +15,6 @@
|
|
15
15
|
# - :params - Hash of parameters to be rendered as hidden fields within the form.
|
16
16
|
module Phlexible
|
17
17
|
module Rails
|
18
|
-
module ButtonToConcerns
|
19
|
-
BUTTON_TAG_METHOD_VERBS = %w[patch put delete].freeze
|
20
|
-
DEFAULT_OPTIONS = { method: 'post', form_class: 'button_to', params: {} }.freeze
|
21
|
-
|
22
|
-
def initialize(url, options = nil)
|
23
|
-
@url = url
|
24
|
-
@options = options
|
25
|
-
end
|
26
|
-
|
27
|
-
def view_template(&block) # rubocop:disable Metrics/AbcSize
|
28
|
-
action = helpers.url_for(@url)
|
29
|
-
@options = DEFAULT_OPTIONS.merge((@options || {}).symbolize_keys)
|
30
|
-
|
31
|
-
method = (@options.delete(:method).presence || method_for_options(@options)).to_s
|
32
|
-
form_method = method == 'get' ? 'get' : 'post'
|
33
|
-
|
34
|
-
form action: action, method: form_method, **form_attributes do
|
35
|
-
method_tag method
|
36
|
-
form_method == 'post' && token_input(action, method.empty? ? 'post' : method)
|
37
|
-
param_inputs
|
38
|
-
|
39
|
-
block_given? ? button(**button_attrs, &block) : button(**button_attrs) { @name }
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def form_attributes
|
46
|
-
{
|
47
|
-
class: @options.delete(:form_class), # @deprecated
|
48
|
-
**(@options.delete(:form_attributes) || {})
|
49
|
-
}
|
50
|
-
end
|
51
|
-
|
52
|
-
def button_attrs
|
53
|
-
{
|
54
|
-
type: 'submit',
|
55
|
-
**@options
|
56
|
-
}
|
57
|
-
end
|
58
|
-
|
59
|
-
def method_for_options(options)
|
60
|
-
if options.is_a?(Array)
|
61
|
-
method_for_options(options.last)
|
62
|
-
elsif options.respond_to?(:persisted?)
|
63
|
-
options.persisted? ? :patch : :post
|
64
|
-
elsif options.respond_to?(:to_model)
|
65
|
-
method_for_options(options.to_model)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def token_input(action, method)
|
70
|
-
return unless helpers.protect_against_forgery?
|
71
|
-
|
72
|
-
name = helpers.request_forgery_protection_token.to_s
|
73
|
-
value = helpers.form_authenticity_token(form_options: { action: action, method: method })
|
74
|
-
|
75
|
-
input type: 'hidden', name: name, value: value, autocomplete: 'off'
|
76
|
-
end
|
77
|
-
|
78
|
-
def method_tag(method)
|
79
|
-
return unless BUTTON_TAG_METHOD_VERBS.include?(method)
|
80
|
-
|
81
|
-
input type: 'hidden', name: '_method', value: method.to_s, autocomplete: 'off'
|
82
|
-
end
|
83
|
-
|
84
|
-
def param_inputs
|
85
|
-
return unless (params = @options.delete(:params))
|
86
|
-
|
87
|
-
to_form_params(params).each do |param|
|
88
|
-
input type: 'hidden', name: param[:name], value: param[:value], autocomplete: 'off'
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
# Returns an array of hashes each containing :name and :value keys suitable for use as the
|
93
|
-
# names and values of form input fields:
|
94
|
-
#
|
95
|
-
# to_form_params(name: 'David', nationality: 'Danish')
|
96
|
-
# # => [{name: 'name', value: 'David'}, {name: 'nationality', value: 'Danish'}]
|
97
|
-
#
|
98
|
-
# to_form_params(country: { name: 'Denmark' })
|
99
|
-
# # => [{name: 'country[name]', value: 'Denmark'}]
|
100
|
-
#
|
101
|
-
# to_form_params(countries: ['Denmark', 'Sweden']})
|
102
|
-
# # => [{name: 'countries[]', value: 'Denmark'}, {name: 'countries[]', value: 'Sweden'}]
|
103
|
-
#
|
104
|
-
# An optional namespace can be passed to enclose key names:
|
105
|
-
#
|
106
|
-
# to_form_params({ name: 'Denmark' }, 'country')
|
107
|
-
# # => [{name: 'country[name]', value: 'Denmark'}]
|
108
|
-
def to_form_params(attribute, namespace = nil)
|
109
|
-
attribute = attribute.to_h if attribute.respond_to?(:permitted?)
|
110
|
-
|
111
|
-
params = []
|
112
|
-
case attribute
|
113
|
-
when Hash
|
114
|
-
attribute.each do |key, value|
|
115
|
-
prefix = namespace ? "#{namespace}[#{key}]" : key
|
116
|
-
params.push(*to_form_params(value, prefix))
|
117
|
-
end
|
118
|
-
when Array
|
119
|
-
array_prefix = "#{namespace}[]"
|
120
|
-
attribute.each do |value|
|
121
|
-
params.push(*to_form_params(value, array_prefix))
|
122
|
-
end
|
123
|
-
else
|
124
|
-
params << { name: namespace.to_s, value: attribute.to_param }
|
125
|
-
end
|
126
|
-
|
127
|
-
params.sort_by { |pair| pair[:name] }
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
18
|
class ButtonTo < Phlex::HTML
|
132
19
|
include ButtonToConcerns
|
133
20
|
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Generates a form containing a single button that submits to the URL created by the set of options.
|
4
|
+
# Similar to Rails `button_to` helper.
|
5
|
+
#
|
6
|
+
# The form submits a POST request by default. You can specify a different HTTP verb via the :method
|
7
|
+
# option.
|
8
|
+
#
|
9
|
+
# Additional arguments are passed through to the button element, with a few exceptions:
|
10
|
+
# - :method - Symbol of HTTP verb. Supported verbs are :post, :get, :delete, :patch, and :put.
|
11
|
+
# Default is :post.
|
12
|
+
# - :form_attributes - Hash of HTML attributes to be rendered on the form tag.
|
13
|
+
# - :form_class - This controls the class of the form within which the submit button will be placed.
|
14
|
+
# Default is 'button_to'. @deprecated: use :form_attributes instead if you want to override this.
|
15
|
+
# - :params - Hash of parameters to be rendered as hidden fields within the form.
|
16
|
+
module Phlexible
|
17
|
+
module Rails
|
18
|
+
module ButtonToConcerns
|
19
|
+
extend ActiveSupport::Concern
|
20
|
+
|
21
|
+
included do
|
22
|
+
include Phlex::Rails::Helpers::URLFor
|
23
|
+
register_value_helper :protect_against_forgery?
|
24
|
+
register_value_helper :request_forgery_protection_token
|
25
|
+
register_value_helper :form_authenticity_token
|
26
|
+
end
|
27
|
+
|
28
|
+
BUTTON_TAG_METHOD_VERBS = %w[patch put delete].freeze
|
29
|
+
DEFAULT_OPTIONS = { method: 'post', form_class: 'button_to', params: {} }.freeze
|
30
|
+
|
31
|
+
def initialize(url, options = nil)
|
32
|
+
@url = url
|
33
|
+
@options = options
|
34
|
+
end
|
35
|
+
|
36
|
+
def view_template(&block)
|
37
|
+
action = url_for(@url)
|
38
|
+
@options = DEFAULT_OPTIONS.merge((@options || {}).symbolize_keys)
|
39
|
+
|
40
|
+
method = (@options.delete(:method).presence || method_for_options(@options)).to_s
|
41
|
+
form_method = method == 'get' ? 'get' : 'post'
|
42
|
+
|
43
|
+
form action: action, method: form_method, **form_attributes do
|
44
|
+
method_tag method
|
45
|
+
form_method == 'post' && token_input(action, method.empty? ? 'post' : method)
|
46
|
+
param_inputs
|
47
|
+
|
48
|
+
block_given? ? button(**button_attrs, &block) : button(**button_attrs) { @name }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def form_attributes
|
55
|
+
{
|
56
|
+
class: @options.delete(:form_class), # @deprecated
|
57
|
+
**(@options.delete(:form_attributes) || {})
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
def button_attrs
|
62
|
+
{
|
63
|
+
type: 'submit',
|
64
|
+
**@options
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def method_for_options(options)
|
69
|
+
if options.is_a?(Array)
|
70
|
+
method_for_options(options.last)
|
71
|
+
elsif options.respond_to?(:persisted?)
|
72
|
+
options.persisted? ? :patch : :post
|
73
|
+
elsif options.respond_to?(:to_model)
|
74
|
+
method_for_options(options.to_model)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def token_input(action, method)
|
79
|
+
return unless protect_against_forgery?
|
80
|
+
|
81
|
+
name = request_forgery_protection_token.to_s
|
82
|
+
value = form_authenticity_token(form_options: { action: action, method: method })
|
83
|
+
|
84
|
+
input type: 'hidden', name: name, value: value, autocomplete: 'off'
|
85
|
+
end
|
86
|
+
|
87
|
+
def method_tag(method)
|
88
|
+
return unless BUTTON_TAG_METHOD_VERBS.include?(method)
|
89
|
+
|
90
|
+
input type: 'hidden', name: '_method', value: method.to_s, autocomplete: 'off'
|
91
|
+
end
|
92
|
+
|
93
|
+
def param_inputs
|
94
|
+
return unless (params = @options.delete(:params))
|
95
|
+
|
96
|
+
to_form_params(params).each do |param|
|
97
|
+
input type: 'hidden', name: param[:name], value: param[:value], autocomplete: 'off'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Returns an array of hashes each containing :name and :value keys suitable for use as the
|
102
|
+
# names and values of form input fields:
|
103
|
+
#
|
104
|
+
# to_form_params(name: 'David', nationality: 'Danish')
|
105
|
+
# # => [{name: 'name', value: 'David'}, {name: 'nationality', value: 'Danish'}]
|
106
|
+
#
|
107
|
+
# to_form_params(country: { name: 'Denmark' })
|
108
|
+
# # => [{name: 'country[name]', value: 'Denmark'}]
|
109
|
+
#
|
110
|
+
# to_form_params(countries: ['Denmark', 'Sweden']})
|
111
|
+
# # => [{name: 'countries[]', value: 'Denmark'}, {name: 'countries[]', value: 'Sweden'}]
|
112
|
+
#
|
113
|
+
# An optional namespace can be passed to enclose key names:
|
114
|
+
#
|
115
|
+
# to_form_params({ name: 'Denmark' }, 'country')
|
116
|
+
# # => [{name: 'country[name]', value: 'Denmark'}]
|
117
|
+
def to_form_params(attribute, namespace = nil)
|
118
|
+
attribute = attribute.to_h if attribute.respond_to?(:permitted?)
|
119
|
+
|
120
|
+
params = []
|
121
|
+
case attribute
|
122
|
+
when Hash
|
123
|
+
attribute.each do |key, value|
|
124
|
+
prefix = namespace ? "#{namespace}[#{key}]" : key
|
125
|
+
params.push(*to_form_params(value, prefix))
|
126
|
+
end
|
127
|
+
when Array
|
128
|
+
array_prefix = "#{namespace}[]"
|
129
|
+
attribute.each do |value|
|
130
|
+
params.push(*to_form_params(value, array_prefix))
|
131
|
+
end
|
132
|
+
else
|
133
|
+
params << { name: namespace.to_s, value: attribute.to_param }
|
134
|
+
end
|
135
|
+
|
136
|
+
params.sort_by { |pair| pair[:name] }
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -23,6 +23,8 @@
|
|
23
23
|
module Phlexible
|
24
24
|
module Rails
|
25
25
|
module ControllerVariables
|
26
|
+
include ViewAssigns
|
27
|
+
|
26
28
|
def self.included(klass)
|
27
29
|
klass.class_attribute :__controller_variables__, instance_predicate: false, default: Set.new
|
28
30
|
klass.extend ClassMethods
|
@@ -40,10 +42,10 @@ module Phlexible
|
|
40
42
|
|
41
43
|
private
|
42
44
|
|
43
|
-
def define_controller_variables
|
45
|
+
def define_controller_variables
|
44
46
|
return unless respond_to?(:__controller_variables__)
|
45
47
|
|
46
|
-
view_assigns =
|
48
|
+
view_assigns = view_assigns()
|
47
49
|
view = @view
|
48
50
|
|
49
51
|
vars = (view&.__controller_variables__ || Set.new) + __controller_variables__
|
@@ -62,7 +64,8 @@ module Phlexible
|
|
62
64
|
end
|
63
65
|
|
64
66
|
module ClassMethods
|
65
|
-
|
67
|
+
# /*
|
68
|
+
def controller_variable(*names, **kwargs)
|
66
69
|
if names.empty? && kwargs.empty?
|
67
70
|
raise ArgumentError, 'You must provide at least one variable name and/or a hash of ' \
|
68
71
|
'variable names and options.'
|
@@ -3,8 +3,10 @@
|
|
3
3
|
module Phlexible
|
4
4
|
module Rails
|
5
5
|
class MetaTagsComponent < Phlex::HTML
|
6
|
+
include ViewAssigns
|
7
|
+
|
6
8
|
def view_template
|
7
|
-
|
9
|
+
view_assigns['meta_tags']&.each do |name, content|
|
8
10
|
meta name: name, content: content.is_a?(String) ? content : content.to_json
|
9
11
|
end
|
10
12
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Phlexible
|
4
|
+
module Rails
|
5
|
+
module ViewAssigns
|
6
|
+
def view_assigns
|
7
|
+
if respond_to?(:view_context)
|
8
|
+
# Phlex 2
|
9
|
+
view_context.controller.view_assigns
|
10
|
+
else
|
11
|
+
# Phlex 1
|
12
|
+
helpers.controller.view_assigns
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/phlexible/version.rb
CHANGED
data/lib/phlexible.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'phlexible/version'
|
4
|
-
require '
|
4
|
+
require 'zeitwerk'
|
5
|
+
require 'rails'
|
6
|
+
require 'phlex-rails'
|
7
|
+
|
8
|
+
loader = Zeitwerk::Loader.for_gem
|
9
|
+
loader.setup
|
5
10
|
|
6
11
|
module Phlexible
|
7
|
-
autoload :AliasView, 'phlexible/alias_view'
|
8
|
-
autoload :PageTitle, 'phlexible/page_title'
|
9
|
-
autoload :Callbacks, 'phlexible/callbacks'
|
10
|
-
autoload :Rails, 'phlexible/rails'
|
11
12
|
end
|
data/phlexible.gemspec
CHANGED
@@ -30,6 +30,8 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
31
31
|
spec.require_paths = ['lib']
|
32
32
|
|
33
|
-
spec.add_dependency 'phlex', '>= 1.10.0', '<
|
34
|
-
spec.add_dependency 'phlex-rails', '>= 1.2.
|
33
|
+
spec.add_dependency 'phlex', '>= 1.10.0', '< 3.0.0'
|
34
|
+
spec.add_dependency 'phlex-rails', '>= 1.2.0', '< 3.0.0'
|
35
|
+
spec.add_dependency 'rails', '>= 7.2.0', '< 9.0.0'
|
36
|
+
spec.add_dependency 'zeitwerk', '~> 2.7.2'
|
35
37
|
end
|