phlexible 2.1.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 +2 -1
- data/Gemfile.lock +134 -42
- data/README.md +46 -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/callbacks.rb +44 -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 +23 -18
- 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 -4
- data/phlexible.gemspec +4 -2
- metadata +57 -11
- data/config/view_helper.rb +0 -16
- data/lib/phlexible/rails.rb +0 -20
@@ -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,9 +23,13 @@
|
|
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
|
31
|
+
klass.include Callbacks
|
32
|
+
klass.before_template :define_controller_variables
|
29
33
|
end
|
30
34
|
|
31
35
|
class UndefinedVariable < NameError
|
@@ -36,31 +40,32 @@ module Phlexible
|
|
36
40
|
end
|
37
41
|
end
|
38
42
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
vars = (view&.__controller_variables__ || Set.new) + __controller_variables__
|
45
|
-
vars.each do |k, v|
|
46
|
-
allow_undefined = true
|
47
|
-
if k.ends_with?('!')
|
48
|
-
allow_undefined = false
|
49
|
-
k = k.chop
|
50
|
-
end
|
43
|
+
private
|
44
|
+
|
45
|
+
def define_controller_variables
|
46
|
+
return unless respond_to?(:__controller_variables__)
|
51
47
|
|
52
|
-
|
48
|
+
view_assigns = view_assigns()
|
49
|
+
view = @view
|
53
50
|
|
54
|
-
|
55
|
-
|
51
|
+
vars = (view&.__controller_variables__ || Set.new) + __controller_variables__
|
52
|
+
vars.each do |k, v|
|
53
|
+
allow_undefined = true
|
54
|
+
if k.ends_with?('!')
|
55
|
+
allow_undefined = false
|
56
|
+
k = k.chop
|
56
57
|
end
|
57
|
-
end
|
58
58
|
|
59
|
-
|
59
|
+
raise ControllerVariables::UndefinedVariable, k if !allow_undefined && !view_assigns.key?(k)
|
60
|
+
|
61
|
+
instance_variable_set(:"@#{v}", view_assigns[k])
|
62
|
+
view&.instance_variable_set(:"@#{v}", view_assigns[k])
|
63
|
+
end
|
60
64
|
end
|
61
65
|
|
62
66
|
module ClassMethods
|
63
|
-
|
67
|
+
# /*
|
68
|
+
def controller_variable(*names, **kwargs)
|
64
69
|
if names.empty? && kwargs.empty?
|
65
70
|
raise ArgumentError, 'You must provide at least one variable name and/or a hash of ' \
|
66
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,10 +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 :Rails, 'phlexible/rails'
|
10
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
|
metadata
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: phlexible
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Moss
|
8
|
+
autorequire:
|
8
9
|
bindir: exe
|
9
10
|
cert_chain: []
|
10
|
-
date: 2025-
|
11
|
+
date: 2025-04-22 00:00:00.000000000 Z
|
11
12
|
dependencies:
|
12
13
|
- !ruby/object:Gem::Dependency
|
13
14
|
name: phlex
|
@@ -18,7 +19,7 @@ dependencies:
|
|
18
19
|
version: 1.10.0
|
19
20
|
- - "<"
|
20
21
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
22
|
+
version: 3.0.0
|
22
23
|
type: :runtime
|
23
24
|
prerelease: false
|
24
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -28,27 +29,61 @@ dependencies:
|
|
28
29
|
version: 1.10.0
|
29
30
|
- - "<"
|
30
31
|
- !ruby/object:Gem::Version
|
31
|
-
version:
|
32
|
+
version: 3.0.0
|
32
33
|
- !ruby/object:Gem::Dependency
|
33
34
|
name: phlex-rails
|
34
35
|
requirement: !ruby/object:Gem::Requirement
|
35
36
|
requirements:
|
36
37
|
- - ">="
|
37
38
|
- !ruby/object:Gem::Version
|
38
|
-
version: 1.2.
|
39
|
+
version: 1.2.0
|
39
40
|
- - "<"
|
40
41
|
- !ruby/object:Gem::Version
|
41
|
-
version:
|
42
|
+
version: 3.0.0
|
42
43
|
type: :runtime
|
43
44
|
prerelease: false
|
44
45
|
version_requirements: !ruby/object:Gem::Requirement
|
45
46
|
requirements:
|
46
47
|
- - ">="
|
47
48
|
- !ruby/object:Gem::Version
|
48
|
-
version: 1.2.
|
49
|
+
version: 1.2.0
|
49
50
|
- - "<"
|
50
51
|
- !ruby/object:Gem::Version
|
51
|
-
version:
|
52
|
+
version: 3.0.0
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: rails
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: 7.2.0
|
60
|
+
- - "<"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 9.0.0
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 7.2.0
|
70
|
+
- - "<"
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 9.0.0
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: zeitwerk
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 2.7.2
|
80
|
+
type: :runtime
|
81
|
+
prerelease: false
|
82
|
+
version_requirements: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - "~>"
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: 2.7.2
|
52
87
|
description: A bunch of helpers and goodies intended to make life with Phlex even
|
53
88
|
easier!
|
54
89
|
email:
|
@@ -58,14 +93,16 @@ extensions: []
|
|
58
93
|
extra_rdoc_files: []
|
59
94
|
files:
|
60
95
|
- ".rubocop.yml"
|
96
|
+
- ".ruby-version"
|
97
|
+
- Appraisals
|
61
98
|
- CODE_OF_CONDUCT.md
|
62
99
|
- Gemfile
|
63
100
|
- Gemfile.lock
|
64
101
|
- LICENSE.txt
|
65
102
|
- README.md
|
66
103
|
- Rakefile
|
104
|
+
- config/render_helper.rb
|
67
105
|
- config/sus.rb
|
68
|
-
- config/view_helper.rb
|
69
106
|
- fixtures/dummy/app/controllers/articles_controller.rb
|
70
107
|
- fixtures/dummy/app/views/articles/index.html.erb
|
71
108
|
- fixtures/dummy/app/views/articles/link.rb
|
@@ -77,17 +114,24 @@ files:
|
|
77
114
|
- fixtures/dummy/log/.gitignore
|
78
115
|
- fixtures/dummy/public/favicon.ico
|
79
116
|
- fixtures/rails_helper.rb
|
117
|
+
- gemfiles/.bundle/config
|
118
|
+
- gemfiles/phlex_1.gemfile
|
119
|
+
- gemfiles/phlex_1.gemfile.lock
|
120
|
+
- gemfiles/phlex_2.gemfile
|
121
|
+
- gemfiles/phlex_2.gemfile.lock
|
80
122
|
- lib/phlexible.rb
|
81
123
|
- lib/phlexible/alias_view.rb
|
124
|
+
- lib/phlexible/callbacks.rb
|
82
125
|
- lib/phlexible/page_title.rb
|
83
|
-
- lib/phlexible/rails.rb
|
84
126
|
- lib/phlexible/rails/a_element.rb
|
85
127
|
- lib/phlexible/rails/action_controller/implicit_render.rb
|
86
128
|
- lib/phlexible/rails/action_controller/meta_tags.rb
|
87
129
|
- lib/phlexible/rails/button_to.rb
|
130
|
+
- lib/phlexible/rails/button_to_concerns.rb
|
88
131
|
- lib/phlexible/rails/controller_variables.rb
|
89
132
|
- lib/phlexible/rails/meta_tags_component.rb
|
90
133
|
- lib/phlexible/rails/responder.rb
|
134
|
+
- lib/phlexible/rails/view_assigns.rb
|
91
135
|
- lib/phlexible/version.rb
|
92
136
|
- phlexible.gemspec
|
93
137
|
homepage: https://github.com/joelmoss/phlexible
|
@@ -98,6 +142,7 @@ metadata:
|
|
98
142
|
source_code_uri: https://github.com/joelmoss/phlexible
|
99
143
|
changelog_uri: https://github.com/joelmoss/phlexible/releases
|
100
144
|
rubygems_mfa_required: 'true'
|
145
|
+
post_install_message:
|
101
146
|
rdoc_options: []
|
102
147
|
require_paths:
|
103
148
|
- lib
|
@@ -112,7 +157,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
157
|
- !ruby/object:Gem::Version
|
113
158
|
version: '0'
|
114
159
|
requirements: []
|
115
|
-
rubygems_version: 3.
|
160
|
+
rubygems_version: 3.5.22
|
161
|
+
signing_key:
|
116
162
|
specification_version: 4
|
117
163
|
summary: A bunch of helpers and goodies intended to make life with Phlex even easier!
|
118
164
|
test_files: []
|
data/config/view_helper.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ViewHelper
|
4
|
-
def self.extended(parent)
|
5
|
-
parent.class_exec do
|
6
|
-
let(:output) { example.call }
|
7
|
-
let(:example) { view.new }
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def view(&block)
|
12
|
-
let :view do
|
13
|
-
Class.new(Phlex::HTML, &block)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
data/lib/phlexible/rails.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'phlex-rails'
|
4
|
-
|
5
|
-
module Phlexible
|
6
|
-
module Rails
|
7
|
-
autoload :ControllerVariables, 'phlexible/rails/controller_variables'
|
8
|
-
autoload :Responder, 'phlexible/rails/responder'
|
9
|
-
autoload :AElement, 'phlexible/rails/a_element'
|
10
|
-
|
11
|
-
autoload :MetaTagsComponent, 'phlexible/rails/meta_tags_component'
|
12
|
-
autoload :ButtonTo, 'phlexible/rails/button_to'
|
13
|
-
autoload :ButtonToConcerns, 'phlexible/rails/button_to'
|
14
|
-
|
15
|
-
module ActionController
|
16
|
-
autoload :ImplicitRender, 'phlexible/rails/action_controller/implicit_render'
|
17
|
-
autoload :MetaTags, 'phlexible/rails/action_controller/meta_tags'
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|