phlexible 0.1.0 → 0.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -1
- data/Gemfile +2 -1
- data/Gemfile.lock +92 -81
- data/README.md +132 -17
- data/fixtures/dummy/app/views/articles/link.rb +2 -2
- data/lib/phlexible/alias_view.rb +3 -2
- data/lib/phlexible/page_title.rb +42 -0
- data/lib/phlexible/rails/a_element.rb +12 -0
- data/lib/phlexible/rails/action_controller/implicit_render.rb +64 -0
- data/lib/phlexible/rails/button_to.rb +82 -0
- data/lib/phlexible/rails/responder.rb +28 -0
- data/lib/phlexible/rails.rb +9 -1
- data/lib/phlexible/version.rb +1 -1
- data/lib/phlexible.rb +1 -0
- metadata +16 -13
- data/lib/phlexible/rails/anchor_element.rb +0 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1d6d20a51dd488d65ba2a2ca84ffd702e5cff5505dce12595cdd1d2ca3f0c8b6
|
|
4
|
+
data.tar.gz: 12bdc3b31f359f5e974ba21d7cb154145c3e0444604c6a20cf706d94eb6a07f8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '09db42fc189ffefa64ca54bdedf9e171d0bf9d3084b4bc89a1c18953141f4fbad978e1a10b0d9d81a522df5ddf633ddca6f34aff214f2e69542f5ca197f232fa'
|
|
7
|
+
data.tar.gz: 0bb3d5026764d1366fe31f1b57f05e8c0ec8eeb24947c73c85448ecb4e9f7f9fcf6a0fd425e3150548e34525405c483a86c0725df8f03690d5df0fff225f1768
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,89 +1,92 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
phlexible (0.
|
|
5
|
-
phlex (~> 1.
|
|
6
|
-
phlex-rails (~> 0.
|
|
4
|
+
phlexible (0.2.0)
|
|
5
|
+
phlex (~> 1.5.1)
|
|
6
|
+
phlex-rails (~> 0.8.0)
|
|
7
7
|
|
|
8
8
|
GEM
|
|
9
9
|
remote: https://rubygems.org/
|
|
10
10
|
specs:
|
|
11
|
-
actioncable (7.0.4)
|
|
12
|
-
actionpack (= 7.0.4)
|
|
13
|
-
activesupport (= 7.0.4)
|
|
11
|
+
actioncable (7.0.4.2)
|
|
12
|
+
actionpack (= 7.0.4.2)
|
|
13
|
+
activesupport (= 7.0.4.2)
|
|
14
14
|
nio4r (~> 2.0)
|
|
15
15
|
websocket-driver (>= 0.6.1)
|
|
16
|
-
actionmailbox (7.0.4)
|
|
17
|
-
actionpack (= 7.0.4)
|
|
18
|
-
activejob (= 7.0.4)
|
|
19
|
-
activerecord (= 7.0.4)
|
|
20
|
-
activestorage (= 7.0.4)
|
|
21
|
-
activesupport (= 7.0.4)
|
|
16
|
+
actionmailbox (7.0.4.2)
|
|
17
|
+
actionpack (= 7.0.4.2)
|
|
18
|
+
activejob (= 7.0.4.2)
|
|
19
|
+
activerecord (= 7.0.4.2)
|
|
20
|
+
activestorage (= 7.0.4.2)
|
|
21
|
+
activesupport (= 7.0.4.2)
|
|
22
22
|
mail (>= 2.7.1)
|
|
23
23
|
net-imap
|
|
24
24
|
net-pop
|
|
25
25
|
net-smtp
|
|
26
|
-
actionmailer (7.0.4)
|
|
27
|
-
actionpack (= 7.0.4)
|
|
28
|
-
actionview (= 7.0.4)
|
|
29
|
-
activejob (= 7.0.4)
|
|
30
|
-
activesupport (= 7.0.4)
|
|
26
|
+
actionmailer (7.0.4.2)
|
|
27
|
+
actionpack (= 7.0.4.2)
|
|
28
|
+
actionview (= 7.0.4.2)
|
|
29
|
+
activejob (= 7.0.4.2)
|
|
30
|
+
activesupport (= 7.0.4.2)
|
|
31
31
|
mail (~> 2.5, >= 2.5.4)
|
|
32
32
|
net-imap
|
|
33
33
|
net-pop
|
|
34
34
|
net-smtp
|
|
35
35
|
rails-dom-testing (~> 2.0)
|
|
36
|
-
actionpack (7.0.4)
|
|
37
|
-
actionview (= 7.0.4)
|
|
38
|
-
activesupport (= 7.0.4)
|
|
36
|
+
actionpack (7.0.4.2)
|
|
37
|
+
actionview (= 7.0.4.2)
|
|
38
|
+
activesupport (= 7.0.4.2)
|
|
39
39
|
rack (~> 2.0, >= 2.2.0)
|
|
40
40
|
rack-test (>= 0.6.3)
|
|
41
41
|
rails-dom-testing (~> 2.0)
|
|
42
42
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
|
43
|
-
actiontext (7.0.4)
|
|
44
|
-
actionpack (= 7.0.4)
|
|
45
|
-
activerecord (= 7.0.4)
|
|
46
|
-
activestorage (= 7.0.4)
|
|
47
|
-
activesupport (= 7.0.4)
|
|
43
|
+
actiontext (7.0.4.2)
|
|
44
|
+
actionpack (= 7.0.4.2)
|
|
45
|
+
activerecord (= 7.0.4.2)
|
|
46
|
+
activestorage (= 7.0.4.2)
|
|
47
|
+
activesupport (= 7.0.4.2)
|
|
48
48
|
globalid (>= 0.6.0)
|
|
49
49
|
nokogiri (>= 1.8.5)
|
|
50
|
-
actionview (7.0.4)
|
|
51
|
-
activesupport (= 7.0.4)
|
|
50
|
+
actionview (7.0.4.2)
|
|
51
|
+
activesupport (= 7.0.4.2)
|
|
52
52
|
builder (~> 3.1)
|
|
53
53
|
erubi (~> 1.4)
|
|
54
54
|
rails-dom-testing (~> 2.0)
|
|
55
55
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
|
56
|
-
activejob (7.0.4)
|
|
57
|
-
activesupport (= 7.0.4)
|
|
56
|
+
activejob (7.0.4.2)
|
|
57
|
+
activesupport (= 7.0.4.2)
|
|
58
58
|
globalid (>= 0.3.6)
|
|
59
|
-
activemodel (7.0.4)
|
|
60
|
-
activesupport (= 7.0.4)
|
|
61
|
-
activerecord (7.0.4)
|
|
62
|
-
activemodel (= 7.0.4)
|
|
63
|
-
activesupport (= 7.0.4)
|
|
64
|
-
activestorage (7.0.4)
|
|
65
|
-
actionpack (= 7.0.4)
|
|
66
|
-
activejob (= 7.0.4)
|
|
67
|
-
activerecord (= 7.0.4)
|
|
68
|
-
activesupport (= 7.0.4)
|
|
59
|
+
activemodel (7.0.4.2)
|
|
60
|
+
activesupport (= 7.0.4.2)
|
|
61
|
+
activerecord (7.0.4.2)
|
|
62
|
+
activemodel (= 7.0.4.2)
|
|
63
|
+
activesupport (= 7.0.4.2)
|
|
64
|
+
activestorage (7.0.4.2)
|
|
65
|
+
actionpack (= 7.0.4.2)
|
|
66
|
+
activejob (= 7.0.4.2)
|
|
67
|
+
activerecord (= 7.0.4.2)
|
|
68
|
+
activesupport (= 7.0.4.2)
|
|
69
69
|
marcel (~> 1.0)
|
|
70
70
|
mini_mime (>= 1.1.0)
|
|
71
|
-
activesupport (7.0.4)
|
|
71
|
+
activesupport (7.0.4.2)
|
|
72
72
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
73
73
|
i18n (>= 1.6, < 2)
|
|
74
74
|
minitest (>= 5.1)
|
|
75
75
|
tzinfo (~> 2.0)
|
|
76
76
|
ast (2.4.2)
|
|
77
77
|
builder (3.2.4)
|
|
78
|
+
cgi (0.3.6)
|
|
78
79
|
combustion (1.3.7)
|
|
79
80
|
activesupport (>= 3.0.0)
|
|
80
81
|
railties (>= 3.0.0)
|
|
81
82
|
thor (>= 0.14.6)
|
|
82
|
-
concurrent-ruby (1.
|
|
83
|
+
concurrent-ruby (1.2.2)
|
|
83
84
|
crass (1.0.6)
|
|
84
85
|
date (3.3.3)
|
|
86
|
+
erb (4.0.2)
|
|
87
|
+
cgi (>= 0.3.3)
|
|
85
88
|
erubi (1.12.0)
|
|
86
|
-
globalid (1.
|
|
89
|
+
globalid (1.1.0)
|
|
87
90
|
activesupport (>= 5.0)
|
|
88
91
|
i18n (1.12.0)
|
|
89
92
|
concurrent-ruby (~> 1.0)
|
|
@@ -91,7 +94,7 @@ GEM
|
|
|
91
94
|
loofah (2.19.1)
|
|
92
95
|
crass (~> 1.0.2)
|
|
93
96
|
nokogiri (>= 1.5.9)
|
|
94
|
-
mail (2.8.
|
|
97
|
+
mail (2.8.1)
|
|
95
98
|
mini_mime (>= 0.1.1)
|
|
96
99
|
net-imap
|
|
97
100
|
net-pop
|
|
@@ -99,8 +102,7 @@ GEM
|
|
|
99
102
|
marcel (1.0.2)
|
|
100
103
|
method_source (1.0.0)
|
|
101
104
|
mini_mime (1.1.2)
|
|
102
|
-
|
|
103
|
-
minitest (5.17.0)
|
|
105
|
+
minitest (5.18.0)
|
|
104
106
|
net-imap (0.3.4)
|
|
105
107
|
date
|
|
106
108
|
net-protocol
|
|
@@ -111,75 +113,83 @@ GEM
|
|
|
111
113
|
net-smtp (0.3.3)
|
|
112
114
|
net-protocol
|
|
113
115
|
nio4r (2.5.8)
|
|
114
|
-
nokogiri (1.
|
|
115
|
-
|
|
116
|
+
nokogiri (1.14.2-arm64-darwin)
|
|
117
|
+
racc (~> 1.4)
|
|
118
|
+
nokogiri (1.14.2-x86_64-darwin)
|
|
119
|
+
racc (~> 1.4)
|
|
120
|
+
nokogiri (1.14.2-x86_64-linux)
|
|
116
121
|
racc (~> 1.4)
|
|
117
122
|
parallel (1.22.1)
|
|
118
|
-
parser (3.2.
|
|
123
|
+
parser (3.2.1.0)
|
|
119
124
|
ast (~> 2.4.1)
|
|
120
|
-
phlex (1.1
|
|
125
|
+
phlex (1.5.1)
|
|
126
|
+
concurrent-ruby (~> 1.2)
|
|
127
|
+
erb (>= 4)
|
|
121
128
|
zeitwerk (~> 2.6)
|
|
122
|
-
phlex-rails (0.
|
|
123
|
-
phlex (
|
|
129
|
+
phlex-rails (0.8.0)
|
|
130
|
+
phlex (~> 1.5)
|
|
124
131
|
rails (>= 6.1, < 8)
|
|
125
|
-
zeitwerk (~> 2)
|
|
132
|
+
zeitwerk (~> 2.6)
|
|
133
|
+
phlex-testing-nokogiri (0.1.0)
|
|
134
|
+
nokogiri (~> 1.13)
|
|
135
|
+
phlex (>= 0.5)
|
|
126
136
|
racc (1.6.2)
|
|
127
|
-
rack (2.2.
|
|
137
|
+
rack (2.2.6.3)
|
|
128
138
|
rack-test (2.0.2)
|
|
129
139
|
rack (>= 1.3)
|
|
130
|
-
rails (7.0.4)
|
|
131
|
-
actioncable (= 7.0.4)
|
|
132
|
-
actionmailbox (= 7.0.4)
|
|
133
|
-
actionmailer (= 7.0.4)
|
|
134
|
-
actionpack (= 7.0.4)
|
|
135
|
-
actiontext (= 7.0.4)
|
|
136
|
-
actionview (= 7.0.4)
|
|
137
|
-
activejob (= 7.0.4)
|
|
138
|
-
activemodel (= 7.0.4)
|
|
139
|
-
activerecord (= 7.0.4)
|
|
140
|
-
activestorage (= 7.0.4)
|
|
141
|
-
activesupport (= 7.0.4)
|
|
140
|
+
rails (7.0.4.2)
|
|
141
|
+
actioncable (= 7.0.4.2)
|
|
142
|
+
actionmailbox (= 7.0.4.2)
|
|
143
|
+
actionmailer (= 7.0.4.2)
|
|
144
|
+
actionpack (= 7.0.4.2)
|
|
145
|
+
actiontext (= 7.0.4.2)
|
|
146
|
+
actionview (= 7.0.4.2)
|
|
147
|
+
activejob (= 7.0.4.2)
|
|
148
|
+
activemodel (= 7.0.4.2)
|
|
149
|
+
activerecord (= 7.0.4.2)
|
|
150
|
+
activestorage (= 7.0.4.2)
|
|
151
|
+
activesupport (= 7.0.4.2)
|
|
142
152
|
bundler (>= 1.15.0)
|
|
143
|
-
railties (= 7.0.4)
|
|
153
|
+
railties (= 7.0.4.2)
|
|
144
154
|
rails-dom-testing (2.0.3)
|
|
145
155
|
activesupport (>= 4.2.0)
|
|
146
156
|
nokogiri (>= 1.6)
|
|
147
|
-
rails-html-sanitizer (1.
|
|
157
|
+
rails-html-sanitizer (1.5.0)
|
|
148
158
|
loofah (~> 2.19, >= 2.19.1)
|
|
149
|
-
railties (7.0.4)
|
|
150
|
-
actionpack (= 7.0.4)
|
|
151
|
-
activesupport (= 7.0.4)
|
|
159
|
+
railties (7.0.4.2)
|
|
160
|
+
actionpack (= 7.0.4.2)
|
|
161
|
+
activesupport (= 7.0.4.2)
|
|
152
162
|
method_source
|
|
153
163
|
rake (>= 12.2)
|
|
154
164
|
thor (~> 1.0)
|
|
155
165
|
zeitwerk (~> 2.5)
|
|
156
166
|
rainbow (3.1.1)
|
|
157
167
|
rake (13.0.6)
|
|
158
|
-
regexp_parser (2.
|
|
168
|
+
regexp_parser (2.7.0)
|
|
159
169
|
rexml (3.2.5)
|
|
160
|
-
rubocop (1.
|
|
170
|
+
rubocop (1.48.0)
|
|
161
171
|
json (~> 2.3)
|
|
162
172
|
parallel (~> 1.10)
|
|
163
173
|
parser (>= 3.2.0.0)
|
|
164
174
|
rainbow (>= 2.2.2, < 4.0)
|
|
165
175
|
regexp_parser (>= 1.8, < 3.0)
|
|
166
176
|
rexml (>= 3.2.5, < 4.0)
|
|
167
|
-
rubocop-ast (>= 1.
|
|
177
|
+
rubocop-ast (>= 1.26.0, < 2.0)
|
|
168
178
|
ruby-progressbar (~> 1.7)
|
|
169
179
|
unicode-display_width (>= 2.4.0, < 3.0)
|
|
170
|
-
rubocop-ast (1.
|
|
171
|
-
parser (>= 3.
|
|
172
|
-
ruby-progressbar (1.
|
|
173
|
-
sus (0.
|
|
180
|
+
rubocop-ast (1.27.0)
|
|
181
|
+
parser (>= 3.2.1.0)
|
|
182
|
+
ruby-progressbar (1.13.0)
|
|
183
|
+
sus (0.20.3)
|
|
174
184
|
thor (1.2.1)
|
|
175
|
-
timeout (0.3.
|
|
176
|
-
tzinfo (2.0.
|
|
185
|
+
timeout (0.3.2)
|
|
186
|
+
tzinfo (2.0.6)
|
|
177
187
|
concurrent-ruby (~> 1.0)
|
|
178
188
|
unicode-display_width (2.4.2)
|
|
179
189
|
websocket-driver (0.7.5)
|
|
180
190
|
websocket-extensions (>= 0.1.0)
|
|
181
191
|
websocket-extensions (0.1.5)
|
|
182
|
-
zeitwerk (2.6.
|
|
192
|
+
zeitwerk (2.6.7)
|
|
183
193
|
|
|
184
194
|
PLATFORMS
|
|
185
195
|
arm64-darwin-22
|
|
@@ -188,10 +198,11 @@ PLATFORMS
|
|
|
188
198
|
|
|
189
199
|
DEPENDENCIES
|
|
190
200
|
combustion
|
|
201
|
+
phlex-testing-nokogiri
|
|
191
202
|
phlexible!
|
|
192
203
|
rake (~> 13.0)
|
|
193
204
|
rubocop (~> 1.21)
|
|
194
|
-
sus (~> 0.
|
|
205
|
+
sus (~> 0.20.0)
|
|
195
206
|
|
|
196
207
|
BUNDLED WITH
|
|
197
208
|
2.4.1
|
data/README.md
CHANGED
|
@@ -16,14 +16,81 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
|
16
16
|
|
|
17
17
|
### Rails
|
|
18
18
|
|
|
19
|
-
#### `
|
|
19
|
+
#### `ActionController::ImplicitRender`
|
|
20
|
+
|
|
21
|
+
Adds support for default and `action_missing` rendering of Phlex views. So instead of this:
|
|
22
|
+
|
|
23
|
+
```ruby
|
|
24
|
+
class UsersController
|
|
25
|
+
def index
|
|
26
|
+
render Views::Users::Index.new
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
You can do this:
|
|
32
|
+
|
|
33
|
+
```ruby
|
|
34
|
+
class UsersController
|
|
35
|
+
include Phlexible::Rails::ActionController::ImplicitRender
|
|
36
|
+
end
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
#### `Responder`
|
|
40
|
+
|
|
41
|
+
If you use [Responders](https://github.com/heartcombo/responders), Phlexible provides a responder to
|
|
42
|
+
support implicit rendering similar to `ActionController::ImplicitRender` above. It will render the
|
|
43
|
+
Phlex view using `respond_with` if one exists, and fall back to default rendering.
|
|
44
|
+
|
|
45
|
+
Just include it in your ApplicationResponder:
|
|
46
|
+
|
|
47
|
+
```ruby
|
|
48
|
+
class ApplicationResponder < ActionController::Responder
|
|
49
|
+
include Phlexible::Rails::ActionController::ImplicitRender
|
|
50
|
+
include Phlexible::Rails::Responder
|
|
51
|
+
end
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Then simply `respond_with` in your action method as normal:
|
|
55
|
+
|
|
56
|
+
```ruby
|
|
57
|
+
class UsersController < ApplicationController
|
|
58
|
+
def new
|
|
59
|
+
respond_with User.new
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def index
|
|
63
|
+
respond_with User.all
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
As Phlex views expect explicit arguments, you can pass these in the `:view_options` keyword
|
|
69
|
+
argument:
|
|
70
|
+
|
|
71
|
+
```ruby
|
|
72
|
+
class UsersController < ApplicationController
|
|
73
|
+
def index
|
|
74
|
+
respond_with User.all, view_options: { page: 1 }
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
class Views::Users::Index < Phlex::HTML
|
|
79
|
+
def initialize(users, page:); end
|
|
80
|
+
end
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
This responder requires the use of `ActionController::ImplicitRender`, so dont't forget to include
|
|
84
|
+
that in your `ApplicationController`.
|
|
85
|
+
|
|
86
|
+
#### `AElement`
|
|
20
87
|
|
|
21
88
|
No need to call Rails `link_to` helper, when you can simply render an anchor tag directly with
|
|
22
89
|
Phlex. But unfortunately that means you lose some of the magic that `link_to` provides. Especially
|
|
23
90
|
the automatic resolution of URL's and Rails routes.
|
|
24
91
|
|
|
25
|
-
The `Phlexible::Rails::
|
|
26
|
-
|
|
92
|
+
The `Phlexible::Rails::AElement` module passes through the `href` attribute to Rails `url_for`
|
|
93
|
+
helper. So you can do this:
|
|
27
94
|
|
|
28
95
|
```ruby
|
|
29
96
|
Rails.application.routes.draw do
|
|
@@ -33,14 +100,48 @@ end
|
|
|
33
100
|
|
|
34
101
|
```ruby
|
|
35
102
|
class MyView < Phlex::HTML
|
|
36
|
-
|
|
103
|
+
include Phlexible::Rails::AElement
|
|
37
104
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
105
|
+
def template
|
|
106
|
+
a(href: :articles) { 'View articles' }
|
|
107
|
+
end
|
|
41
108
|
end
|
|
42
109
|
```
|
|
43
110
|
|
|
111
|
+
#### 'ButtonTo`
|
|
112
|
+
|
|
113
|
+
Generates a form containing a single button that submits to the URL created by the set of options.
|
|
114
|
+
|
|
115
|
+
It is similar to Rails `button_to` helper, which accepts the value/content of the button as the
|
|
116
|
+
first argument, and a URL or route helper as the second argument.
|
|
117
|
+
|
|
118
|
+
```ruby
|
|
119
|
+
Phlexible::Rails::ButtonTo.new 'My Button', :root
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Alternatively you can pass a block; the result of which will be used as the value of the button.
|
|
123
|
+
|
|
124
|
+
```ruby
|
|
125
|
+
Phlexible::Rails::ButtonTo.new(:root) { 'Go Home 👉' }
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The url argument accepts the same options as Rails `url_for`.
|
|
129
|
+
|
|
130
|
+
The form submits a POST request by default. You can specify a different HTTP verb via the :method
|
|
131
|
+
option.
|
|
132
|
+
|
|
133
|
+
```ruby
|
|
134
|
+
Phlexible::Rails::ButtonTo.new 'My Button', :root, method: :patch
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
##### Options
|
|
138
|
+
|
|
139
|
+
- `:class` - Specify the HTML class name of the button (not the form).
|
|
140
|
+
- `:form_class` - Specify the HTML class name of the form (default: 'button_to').
|
|
141
|
+
- `:data` - This option can be used to add custom data attributes.
|
|
142
|
+
- `:method` - Symbol of the HTTP verb. Supported verbs are :post (default), :get, :delete, :patch,
|
|
143
|
+
and :put.
|
|
144
|
+
|
|
44
145
|
### `AliasView`
|
|
45
146
|
|
|
46
147
|
Create an alias at a given `element`, to the given view class.
|
|
@@ -49,11 +150,11 @@ So instead of:
|
|
|
49
150
|
|
|
50
151
|
```ruby
|
|
51
152
|
class MyView < Phlex::HTML
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
end
|
|
153
|
+
def template
|
|
154
|
+
div do
|
|
155
|
+
render My::Awesome::Component.new
|
|
56
156
|
end
|
|
157
|
+
end
|
|
57
158
|
end
|
|
58
159
|
```
|
|
59
160
|
|
|
@@ -61,18 +162,32 @@ You can instead do:
|
|
|
61
162
|
|
|
62
163
|
```ruby
|
|
63
164
|
class MyView < Phlex::HTML
|
|
64
|
-
|
|
165
|
+
extend Phlexible::AliasView
|
|
65
166
|
|
|
66
|
-
|
|
167
|
+
alias_view :awesome, -> { My::Awesome::Component }
|
|
67
168
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
end
|
|
169
|
+
def template
|
|
170
|
+
div do
|
|
171
|
+
awesome
|
|
72
172
|
end
|
|
173
|
+
end
|
|
73
174
|
end
|
|
74
175
|
```
|
|
75
176
|
|
|
177
|
+
### PageTitle
|
|
178
|
+
|
|
179
|
+
Helper to assist in defining page titles within Phlex views. Also includes support for nested views,
|
|
180
|
+
where each desendent view class will have its title prepended to the page title. Simply assign the
|
|
181
|
+
title to the `page_title` class variable:
|
|
182
|
+
|
|
183
|
+
```ruby
|
|
184
|
+
class MyView
|
|
185
|
+
self.page_title = 'My Title'
|
|
186
|
+
end
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Then call the `page_title` method in the `<head>` of your page.
|
|
190
|
+
|
|
76
191
|
## Development
|
|
77
192
|
|
|
78
193
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Views::Articles::Link < Phlex::HTML
|
|
4
|
-
include Phlexible::Rails::
|
|
4
|
+
include Phlexible::Rails::AElement
|
|
5
5
|
|
|
6
6
|
def template
|
|
7
|
-
a(href: :root) { 'A link to root' }
|
|
7
|
+
a(href: :root, class: :foo) { 'A link to root' }
|
|
8
8
|
end
|
|
9
9
|
end
|
data/lib/phlexible/alias_view.rb
CHANGED
|
@@ -30,8 +30,9 @@ module Phlexible
|
|
|
30
30
|
#
|
|
31
31
|
module AliasView
|
|
32
32
|
def alias_view(element, view_class)
|
|
33
|
-
define_method element do |*args, **kwargs, &
|
|
34
|
-
render view_class.call.new(*args, **kwargs, &
|
|
33
|
+
define_method element do |*args, **kwargs, &blk|
|
|
34
|
+
render view_class.call.new(*args, **kwargs), &blk
|
|
35
|
+
# view_class.call.new(*args, **kwargs).call(@_target, view_context: @_view_context, parent: self, &blk)
|
|
35
36
|
end
|
|
36
37
|
end
|
|
37
38
|
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Phlexible
|
|
4
|
+
#
|
|
5
|
+
# Helper to assist in defining page titles within Phlex views. Also includes support for nested
|
|
6
|
+
# views, where each desendent view class will have its title prepended to the page title. Simply
|
|
7
|
+
# include the module and assign the title to the `page_title` class variable:
|
|
8
|
+
#
|
|
9
|
+
# class MyView
|
|
10
|
+
# include Phlexible::PageTitle
|
|
11
|
+
# self.page_title = 'My Title'
|
|
12
|
+
# end
|
|
13
|
+
#
|
|
14
|
+
# Then call the `page_title` method in the <head> of your page.
|
|
15
|
+
#
|
|
16
|
+
module PageTitle
|
|
17
|
+
def self.included(base)
|
|
18
|
+
base.class_eval do
|
|
19
|
+
self.class.attr_accessor :page_title
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def page_title
|
|
26
|
+
title = []
|
|
27
|
+
|
|
28
|
+
klass = self.class
|
|
29
|
+
while klass.respond_to?(:page_title)
|
|
30
|
+
title << if klass.page_title.is_a?(Proc)
|
|
31
|
+
instance_exec(&klass.page_title)
|
|
32
|
+
else
|
|
33
|
+
klass.page_title
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
klass = klass.superclass
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
title.compact.join(' - ')
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Adds support for default and action_missing rendering of Phlex views. So instead of this:
|
|
4
|
+
#
|
|
5
|
+
# class UsersController
|
|
6
|
+
# def index
|
|
7
|
+
# render Views::Users::Index.new
|
|
8
|
+
# end
|
|
9
|
+
# end
|
|
10
|
+
#
|
|
11
|
+
# You can do this:
|
|
12
|
+
#
|
|
13
|
+
# class UsersController
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
module Phlexible
|
|
17
|
+
module Rails
|
|
18
|
+
module ActionController
|
|
19
|
+
module ImplicitRender
|
|
20
|
+
NUFFIN = 'NUFFIN'
|
|
21
|
+
|
|
22
|
+
def default_render
|
|
23
|
+
render_view_class || super
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Renders the Phlex view.
|
|
27
|
+
def render_view_class(view_options = NUFFIN, render_options = {})
|
|
28
|
+
klass = render_options&.key?(:action) ? phlex_view(render_options[:action]) : phlex_view
|
|
29
|
+
return unless klass
|
|
30
|
+
|
|
31
|
+
if view_options == NUFFIN
|
|
32
|
+
view_options = render_options.delete(:view_options) { {} }
|
|
33
|
+
render klass.new(**view_options), render_options
|
|
34
|
+
else
|
|
35
|
+
kwargs = {}
|
|
36
|
+
kwargs = render_options.delete(:view_options) if render_options.key?(:view_options)
|
|
37
|
+
|
|
38
|
+
render klass.new(view_options, **kwargs), render_options
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def method_for_action(action_name)
|
|
45
|
+
if action_method?(action_name)
|
|
46
|
+
action_name
|
|
47
|
+
elsif phlex_view
|
|
48
|
+
'_handle_view_class'
|
|
49
|
+
elsif respond_to?(:action_missing, true)
|
|
50
|
+
'_handle_action_missing'
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def _handle_view_class(*_args)
|
|
55
|
+
render_view_class
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def phlex_view(action_name = @_action_name)
|
|
59
|
+
"views/#{controller_path}/#{action_name}".classify.safe_constantize
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
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
|
+
module Phlexible
|
|
9
|
+
module Rails
|
|
10
|
+
module ButtonToConcerns
|
|
11
|
+
BUTTON_TAG_METHOD_VERBS = %w[patch put delete].freeze
|
|
12
|
+
DEFAULT_OPTIONS = { method: 'post', form_class: 'button_to' }.freeze
|
|
13
|
+
|
|
14
|
+
def initialize(name = nil, url = nil, options = nil)
|
|
15
|
+
@name = name
|
|
16
|
+
@url = url
|
|
17
|
+
@options = options
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
21
|
+
def template(&block)
|
|
22
|
+
if block_given?
|
|
23
|
+
@options = @url
|
|
24
|
+
@url = @name
|
|
25
|
+
@name = nil
|
|
26
|
+
end
|
|
27
|
+
|
|
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, class: @options.delete(:form_class), method: form_method do
|
|
35
|
+
method_tag method
|
|
36
|
+
form_method == 'post' && token_input(action, method.empty? ? 'post' : method)
|
|
37
|
+
|
|
38
|
+
block_given? ? button(**button_attrs, &block) : button(**button_attrs) { @name }
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def button_attrs
|
|
46
|
+
{
|
|
47
|
+
type: 'submit',
|
|
48
|
+
**@options
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def method_for_options(options)
|
|
53
|
+
if options.is_a?(Array)
|
|
54
|
+
method_for_options(options.last)
|
|
55
|
+
elsif options.respond_to?(:persisted?)
|
|
56
|
+
options.persisted? ? :patch : :post
|
|
57
|
+
elsif options.respond_to?(:to_model)
|
|
58
|
+
method_for_options(options.to_model)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def token_input(action, method)
|
|
63
|
+
return unless helpers.protect_against_forgery?
|
|
64
|
+
|
|
65
|
+
name = helpers.request_forgery_protection_token.to_s
|
|
66
|
+
value = helpers.form_authenticity_token(form_options: { action: action, method: method })
|
|
67
|
+
|
|
68
|
+
input type: 'hidden', name: name, value: value, autocomplete: 'off'
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def method_tag(method)
|
|
72
|
+
return unless BUTTON_TAG_METHOD_VERBS.include?(method)
|
|
73
|
+
|
|
74
|
+
input type: 'hidden', name: '_method', value: method.to_s, autocomplete: 'off'
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
class ButtonTo < Phlex::HTML
|
|
79
|
+
include ButtonToConcerns
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Phlexible
|
|
4
|
+
module Rails
|
|
5
|
+
module Responder
|
|
6
|
+
# Overridden to support implicit rendering of phlex views.
|
|
7
|
+
def default_render
|
|
8
|
+
if @default_response
|
|
9
|
+
@default_response.call(options)
|
|
10
|
+
elsif !get? && has_errors?
|
|
11
|
+
render_phlex_view options.merge(status: :unprocessable_entity)
|
|
12
|
+
else
|
|
13
|
+
render_phlex_view options
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Render the Phlex view with the current resource. Falls back to default controller rendering
|
|
18
|
+
# if no Phlex view exists. If a `view_options` keyword argument is given, this will be passed
|
|
19
|
+
# as the keyword arguments of the view initializer.
|
|
20
|
+
#
|
|
21
|
+
# @see Phlexible::Rails::ActionController::ImplicitRender#render_view_class
|
|
22
|
+
def render_phlex_view(options)
|
|
23
|
+
controller.render_view_class(@resource, options) || controller.render(options)
|
|
24
|
+
end
|
|
25
|
+
alias render render_phlex_view
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
data/lib/phlexible/rails.rb
CHANGED
|
@@ -4,6 +4,14 @@ require 'phlex-rails'
|
|
|
4
4
|
|
|
5
5
|
module Phlexible
|
|
6
6
|
module Rails
|
|
7
|
-
autoload :
|
|
7
|
+
autoload :Responder, 'phlexible/rails/responder'
|
|
8
|
+
autoload :AElement, 'phlexible/rails/a_element'
|
|
9
|
+
|
|
10
|
+
autoload :ButtonTo, 'phlexible/rails/button_to'
|
|
11
|
+
autoload :ButtonToConcerns, 'phlexible/rails/button_to'
|
|
12
|
+
|
|
13
|
+
module ActionController
|
|
14
|
+
autoload :ImplicitRender, 'phlexible/rails/action_controller/implicit_render'
|
|
15
|
+
end
|
|
8
16
|
end
|
|
9
17
|
end
|
data/lib/phlexible/version.rb
CHANGED
data/lib/phlexible.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: phlexible
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joel Moss
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-
|
|
11
|
+
date: 2023-03-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: phlex
|
|
@@ -16,30 +16,30 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
19
|
+
version: 1.5.1
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
26
|
+
version: 1.5.1
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: phlex-rails
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
33
|
+
version: 0.8.0
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
41
|
-
description: A bunch of helpers and goodies intended to make life with
|
|
42
|
-
|
|
40
|
+
version: 0.8.0
|
|
41
|
+
description: A bunch of helpers and goodies intended to make life with Phlex even
|
|
42
|
+
easier!
|
|
43
43
|
email:
|
|
44
44
|
- joel@developwithstyle.com
|
|
45
45
|
executables: []
|
|
@@ -67,8 +67,12 @@ files:
|
|
|
67
67
|
- fixtures/rails_helper.rb
|
|
68
68
|
- lib/phlexible.rb
|
|
69
69
|
- lib/phlexible/alias_view.rb
|
|
70
|
+
- lib/phlexible/page_title.rb
|
|
70
71
|
- lib/phlexible/rails.rb
|
|
71
|
-
- lib/phlexible/rails/
|
|
72
|
+
- lib/phlexible/rails/a_element.rb
|
|
73
|
+
- lib/phlexible/rails/action_controller/implicit_render.rb
|
|
74
|
+
- lib/phlexible/rails/button_to.rb
|
|
75
|
+
- lib/phlexible/rails/responder.rb
|
|
72
76
|
- lib/phlexible/version.rb
|
|
73
77
|
homepage: https://github.com/joelmoss/phlexible
|
|
74
78
|
licenses:
|
|
@@ -86,16 +90,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
86
90
|
requirements:
|
|
87
91
|
- - ">="
|
|
88
92
|
- !ruby/object:Gem::Version
|
|
89
|
-
version:
|
|
93
|
+
version: 3.0.0
|
|
90
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
95
|
requirements:
|
|
92
96
|
- - ">="
|
|
93
97
|
- !ruby/object:Gem::Version
|
|
94
98
|
version: '0'
|
|
95
99
|
requirements: []
|
|
96
|
-
rubygems_version: 3.4.
|
|
100
|
+
rubygems_version: 3.4.6
|
|
97
101
|
signing_key:
|
|
98
102
|
specification_version: 4
|
|
99
|
-
summary: A bunch of helpers and goodies intended to make life with
|
|
100
|
-
even easier!
|
|
103
|
+
summary: A bunch of helpers and goodies intended to make life with Phlex even easier!
|
|
101
104
|
test_files: []
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Phlexible
|
|
4
|
-
module Rails
|
|
5
|
-
module AnchorElement
|
|
6
|
-
# @override Calls `url_for` for the :href attribute.
|
|
7
|
-
def a(**attributes, &block)
|
|
8
|
-
attributes[:href] = helpers.url_for(attributes[:href]) if attributes.key?(:href)
|
|
9
|
-
|
|
10
|
-
super(**attributes, &block)
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|