render_turbo_stream 4.2.0 → 4.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +20 -16
- data/app/models/render_turbo_stream/option.rb +4 -0
- data/app/views/render_turbo_stream.turbo_stream.erb +8 -1
- data/app/views/render_turbo_stream_request_test.html.erb +6 -1
- data/db/migrate/20230616070450_create_render_turbo_stream_options.rb +9 -0
- data/lib/render_turbo_stream/controller_channel_helpers.rb +2 -2
- data/lib/render_turbo_stream/controller_helpers.rb +13 -32
- data/lib/render_turbo_stream/controller_libs.rb +7 -2
- data/lib/render_turbo_stream/libs.rb +15 -5
- data/lib/render_turbo_stream/version.rb +1 -1
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 414f885f38878ae67239db4d797a57f1a0826daf8fdea5f94d6ce7a1b2a0a54a
|
4
|
+
data.tar.gz: eb8b5012eec604e899f088337697491c41522337bf4cec7fc66067462089cc2a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 454f651f6801fdb48a2bd2a76167a8d8d0fafd2712242aa9ce5db5f4d72d30bc95a7e4406e7d9da0f67b1542262b2d46a0c60b47cf52ce4773544fc94cdb636b
|
7
|
+
data.tar.gz: 386d2f4bf0d2a940969fe14fd280cb9afe9d09fac6568b9fc5ea98ddcd054a48de547d1a677275e6c418389efe309b10f621258e617c515329105db72b5960eb
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# RenderTurboStream
|
2
2
|
|
3
|
-
2021 DHH annouced a great milestone in web development with [Rails 7, "Fulfilling a Vision"](https://rubyonrails.org/2021/12/15/Rails-7-fulfilling-a-vision).
|
4
|
-
|
5
3
|
This gem has a second [README Turbo::StreamsChannel](https://gitlab.com/sedl/renderturbostream/-/blob/main/README-channels.md). Starting point is here. And I recommend that you download my [Quick-and-dirty test project](https://gitlab.com/sedl/renderturbostream_railsapp), set it up, see all the tests succeed, and then read through this README.
|
6
4
|
|
5
|
+
As of v4.3, locals inside partials should work as expected. If you are working with turbo but without this gem, please read [readme-locals](https://gitlab.com/sedl/renderturbostream/-/blob/main/readme-locals.md) to avoid tedious details.
|
6
|
+
|
7
7
|
Defining templates like `(create|update).turbo_stream.haml` is a heavy mix of logic and view. This gem separates logic and view so that `*.turbo_stream.*` templates are no longer necessary and the logic can stay on the ruby side.
|
8
8
|
|
9
9
|
For `:replace` actions, responses must be wrapped inside a `turbo_frame_tag` with a matching `target_id`. The gem will regex the content and wrap it by a `turbo_frame_tag` if necessary but not present. This way the matching `target_id` is only defined in one place. This check only happens on the first call after restarting the application in production and on every call if precompile assets is set to true in configs.
|
@@ -17,7 +17,7 @@ Has a testing strategy.
|
|
17
17
|
An overview of how we design a rails-7 application with turbo
|
18
18
|
is [published on dev.to](https://dev.to/chmich/rails-7-vite-wrapping-up-1pia).
|
19
19
|
|
20
|
-
|
20
|
+
Hope it helps :)
|
21
21
|
|
22
22
|
**Chris**
|
23
23
|
|
@@ -103,12 +103,15 @@ def update
|
|
103
103
|
turbo_stream_save(
|
104
104
|
@article.update(article_params),
|
105
105
|
if_success_turbo_redirect_to: articles_path,
|
106
|
-
target_id: 'customer-form'
|
106
|
+
target_id: 'customer-form',
|
107
|
+
partial: 'form'
|
107
108
|
)
|
108
109
|
end
|
109
110
|
```
|
110
111
|
This will set a status, generate a flash message, and run `render_turbo_stream`. If it fails, it would result in something like this:
|
111
112
|
|
113
|
+
If no partial is given, it renders the default template as turbo_stream.
|
114
|
+
|
112
115
|
```ruby
|
113
116
|
render_turbo_stream(
|
114
117
|
[
|
@@ -127,16 +130,6 @@ render_turbo_stream(
|
|
127
130
|
|
128
131
|
If the update succeeds, it will do a `redirect_to` action from turbo_power
|
129
132
|
|
130
|
-
The `stream_partial` method is for rendering a partial alone.
|
131
|
-
|
132
|
-
```ruby
|
133
|
-
stream_partial(
|
134
|
-
'flash-box',
|
135
|
-
partial: nil, #=> default: id.gsub('-','_')
|
136
|
-
locals: { title: 'my title' },
|
137
|
-
action: nil #=> default: :replace
|
138
|
-
)
|
139
|
-
```
|
140
133
|
|
141
134
|
**locals**: The hash for locals goes through a `symbolize_keys`, so you need to use locals in used partials like this: `locals[:message]`.
|
142
135
|
|
@@ -194,7 +187,7 @@ This means that the target id must be defined in several places: inside a partia
|
|
194
187
|
In order to avoid this kind of tedious coding, the gem has a kind of fallback built in: If the argument `partial` is given, but the attribute `target_id` is not, the gem will get the target_id from the partial. The process is:
|
195
188
|
|
196
189
|
1. Render the partial with the provided locals
|
197
|
-
2. Grabs into the partial by Nokogiri and looks for
|
190
|
+
2. Grabs into the partial by Nokogiri and looks for the first `turbo_frame_tag` **OR** a element with the attribute `data_turbo_target`, get the id and uses this as target_id.
|
198
191
|
3. If all that not is found it raises a exception
|
199
192
|
4. wraps the partial within the `turbo_stream.*` and sends this to the front.
|
200
193
|
|
@@ -250,10 +243,21 @@ config.x.render_turbo_stream.first_argument_is_html_id = %[replace append prepen
|
|
250
243
|
|
251
244
|
This setting is relevant for testing helpers.
|
252
245
|
|
246
|
+
# Personal note
|
247
|
+
|
248
|
+
The World Wide Web, founded around 1990 by [Tim Berners-Lee](https://en.wikipedia.org/wiki/Tim_Berners-Lee), was an html response from the server.
|
249
|
+
|
250
|
+
Frameworks like Angular, Ember, React, Vue brought a much better user experience, so called "single page applications". But they changed a paradigma: Now Javascript was the processor of HTML, which is far from the [Progressive Enhancement](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement).
|
251
|
+
|
252
|
+
2021 DHH annouced a great milestone in web development with [Rails 7, "Fulfilling a Vision"](https://rubyonrails.org/2021/12/15/Rails-7-fulfilling-a-vision). The Rails core now has done a big step, for bringing a user experience like a single page app, but by reducing javascript. This is a modern back to the roots. Thank you Rails Team!
|
253
|
+
|
254
|
+
But as of 2023, I searched for months and found nothing to solve all these details to make this Vision really work for rails. Now i am really happy and i cannot imagine working without Turbo!
|
255
|
+
|
256
|
+
Let us build on this vision and make rails what it has always been: A framework ahead of its time!
|
253
257
|
|
254
258
|
# Contributing
|
255
259
|
|
256
|
-
|
260
|
+
Contributors welcome.
|
257
261
|
|
258
262
|
# License
|
259
263
|
|
@@ -15,8 +15,15 @@
|
|
15
15
|
<% ctl = { partial: args[:partial], target_id: args[:target_id], action: args[:action] } %>
|
16
16
|
|
17
17
|
|
18
|
+
<% locals = args[:locals]&.symbolize_keys %>
|
19
|
+
|
20
|
+
<% if args[:partial].present? %>
|
21
|
+
<% rendered_html = render(partial: args[:partial], locals: locals, formats: [:html]) %>
|
22
|
+
<% else %>
|
23
|
+
<% rendered_html = render(template: args[:template], locals: locals, formats: [:html]) %>
|
24
|
+
<% end %>
|
25
|
+
|
18
26
|
|
19
|
-
<% rendered_html = render(partial: args[:partial], locals: args[:locals]&.symbolize_keys, formats: [:html]) %>
|
20
27
|
<% unless args[:target].present? %>
|
21
28
|
<% args[:target] = RenderTurboStream::Libs.fetch_arguments_from_rendered_string(rendered_html)[:target] %>
|
22
29
|
<% unless args[:target].present? %>
|
@@ -11,7 +11,12 @@
|
|
11
11
|
<% else %>
|
12
12
|
|
13
13
|
|
14
|
-
|
14
|
+
<% locals = s[:locals]&.symbolize_keys %>
|
15
|
+
<% if s[:partial].present? %>
|
16
|
+
<% html = (render partial: s[:partial], locals: locals, formats: [:html]) %>
|
17
|
+
<% else %>
|
18
|
+
<% html = (render template: s[:template], locals: locals, formats: [:html]) %>
|
19
|
+
<% end %>
|
15
20
|
|
16
21
|
|
17
22
|
|
@@ -61,9 +61,9 @@ module RenderTurboStream
|
|
61
61
|
|
62
62
|
disable_default = false
|
63
63
|
if partial.present?
|
64
|
-
_partial = RenderTurboStream::Libs.partial_path(
|
64
|
+
_partial = RenderTurboStream::Libs.partial_path(controller_path, partial)
|
65
65
|
elsif template.present?
|
66
|
-
_template = RenderTurboStream::Libs.partial_path(
|
66
|
+
_template = RenderTurboStream::Libs.partial_path(controller_path, template)
|
67
67
|
disable_default = true
|
68
68
|
else
|
69
69
|
_template = [controller_path, action_name].join('/')
|
@@ -12,10 +12,10 @@ module RenderTurboStream
|
|
12
12
|
if_success_redirect_to: nil, # does a regular redirect. Works if you are inside a turbo_frame and just want to redirect inside that frame BUT CANNOT STREAM OTHERS ACTIONS ON THE SAME RESPONSE https://github.com/rails/rails/issues/48056
|
13
13
|
if_success_turbo_redirect_to: nil, # does a full page redirect (break out of all frames by turbo_power redirect)
|
14
14
|
|
15
|
-
target_id: nil, # IF NIL:
|
16
|
-
partial: nil,
|
15
|
+
target_id: nil, # IF NIL: the gem grabs inside the rendered content for turbo_frame_tag or element with attribute data_turbo_target and takes the id from there.
|
16
|
+
partial: nil, # if nil: the gem renders the default template by turbo-stream
|
17
17
|
action: 'replace', # options: append, prepend
|
18
|
-
locals: {},
|
18
|
+
locals: {},
|
19
19
|
|
20
20
|
if_success_add: nil, # hash for a partial to render or array with actions (as array) or hashes for partials within
|
21
21
|
if_error_add: nil, # additional partials that should be rendered if save_action failed
|
@@ -29,12 +29,6 @@ module RenderTurboStream
|
|
29
29
|
flash_controller_action_name: action_name # options: 'update', 'create', otherwise you have to declare a translation in config/locales like "activerecord.success.#{flash_controller_action_name}" and "activerecord.errors.#{flash_controller_action_name}"
|
30
30
|
)
|
31
31
|
|
32
|
-
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
33
|
-
# EXCEPTIONS
|
34
|
-
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
35
|
-
|
36
|
-
raise 'render_turbo_stream: arguments target_id and if_success_redirect_to cannot be provided both' if target_id && if_success_redirect_to
|
37
|
-
|
38
32
|
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
39
33
|
# LOGIC
|
40
34
|
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
@@ -49,7 +43,7 @@ module RenderTurboStream
|
|
49
43
|
libs = RenderTurboStream::ControllerLibs.new(save_action)
|
50
44
|
model_name = object.model_name.human
|
51
45
|
|
52
|
-
streams =
|
46
|
+
streams = []
|
53
47
|
|
54
48
|
flashes = libs.generate_flash(
|
55
49
|
model_name,
|
@@ -93,8 +87,9 @@ module RenderTurboStream
|
|
93
87
|
if_success_turbo_redirect_to
|
94
88
|
]
|
95
89
|
])
|
90
|
+
|
96
91
|
elsif save_action && if_success_redirect_to.present?
|
97
|
-
response.status =
|
92
|
+
response.status = 303
|
98
93
|
if allow_channel
|
99
94
|
Rails.logger.debug(" • Sent #{streams.length} actions through Turbo::StreamsChannel to enable defined redirection because allowed in configs.")
|
100
95
|
c_libs = RenderTurboStream::ChannelLibs.new(response)
|
@@ -107,13 +102,10 @@ module RenderTurboStream
|
|
107
102
|
end
|
108
103
|
redirect_to if_success_redirect_to
|
109
104
|
|
110
|
-
elsif !target_id.present? && allow_channel
|
111
|
-
Rails.logger.debug(" • Sent #{streams.length} actions through Turbo::StreamsChannel because no target_id defined and allowed in configs.")
|
112
|
-
c_libs = RenderTurboStream::ChannelLibs.new(response)
|
113
|
-
c_libs.send_actions_to_channel("authenticated-user-#{helpers.current_user.id}", streams, @render_turbo_stream_evaluate_instance_variables)
|
114
|
-
|
115
105
|
else
|
106
|
+
streams += libs.generate_action(controller_path, target_id, action, partial, (partial ? nil : action_name), locals)
|
116
107
|
render_turbo_stream(streams)
|
108
|
+
|
117
109
|
end
|
118
110
|
end
|
119
111
|
|
@@ -134,7 +126,11 @@ module RenderTurboStream
|
|
134
126
|
end
|
135
127
|
r.delete(:target_id)
|
136
128
|
r[:action] = (props[:action].present? ? props[:action] : :replace)
|
137
|
-
|
129
|
+
if props[:partial].present?
|
130
|
+
r[:partial] = RenderTurboStream::Libs.partial_path(controller_path, props[:partial])
|
131
|
+
else
|
132
|
+
r[:template] = RenderTurboStream::Libs.partial_path(controller_path, props[:template])
|
133
|
+
end
|
138
134
|
r[:type] = 'stream-partial'
|
139
135
|
|
140
136
|
ary.push(r)
|
@@ -155,20 +151,5 @@ module RenderTurboStream
|
|
155
151
|
|
156
152
|
end
|
157
153
|
|
158
|
-
# renders a partial to turbo_stream
|
159
|
-
|
160
|
-
def stream_partial(target_id = nil, partial: nil, action: :replace, locals: {})
|
161
|
-
render_turbo_stream(
|
162
|
-
[
|
163
|
-
{
|
164
|
-
target: RenderTurboStream::Libs.target_id_to_target(target_id),
|
165
|
-
partial: partial,
|
166
|
-
action: action,
|
167
|
-
locals: locals
|
168
|
-
}
|
169
|
-
]
|
170
|
-
)
|
171
|
-
end
|
172
|
-
|
173
154
|
end
|
174
155
|
end
|
@@ -76,11 +76,16 @@ module RenderTurboStream
|
|
76
76
|
|
77
77
|
end
|
78
78
|
|
79
|
-
def generate_action(controller_path, target_id, action, partial, locals)
|
79
|
+
def generate_action(controller_path, target_id, action, partial, template, locals)
|
80
80
|
libs = RenderTurboStream::Libs
|
81
81
|
target = libs.target_id_to_target(target_id)
|
82
|
-
|
82
|
+
if partial
|
83
|
+
_partial = libs.partial_path(controller_path, partial)
|
83
84
|
[target: target, partial: _partial, locals: locals, action: action]
|
85
|
+
else
|
86
|
+
_template = libs.template_path(controller_path, template)
|
87
|
+
[target: target, template: _template, locals: locals, action: action]
|
88
|
+
end
|
84
89
|
end
|
85
90
|
|
86
91
|
def action_errors(actions)
|
@@ -17,26 +17,36 @@ module RenderTurboStream
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
def self.partial_path(
|
20
|
+
def self.partial_path(controller_path, partial)
|
21
21
|
if partial && partial.to_s.include?('/')
|
22
22
|
partial
|
23
23
|
elsif partial.present?
|
24
24
|
[controller_path, partial].join('/')
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.template_path(controller_path, template)
|
29
|
+
if template && template.to_s.include?('/')
|
30
|
+
template
|
31
|
+
elsif template.present?
|
32
|
+
[controller_path, template].join('/')
|
29
33
|
end
|
30
34
|
end
|
31
35
|
|
32
36
|
def self.fetch_arguments_from_rendered_string(rendered_string)
|
33
37
|
noko = Nokogiri::HTML(rendered_string)
|
34
38
|
frame = noko.at_css('turbo-frame')
|
39
|
+
ele = noko.at_css('[data_turbo_target]')
|
35
40
|
if frame.present?
|
36
41
|
{
|
37
42
|
target_id: frame[:id],
|
38
43
|
target: target_id_to_target(frame[:id])
|
39
44
|
}
|
45
|
+
elsif ele.present?
|
46
|
+
{
|
47
|
+
target_id: ele[:id],
|
48
|
+
target: target_id_to_target(ele[:id])
|
49
|
+
}
|
40
50
|
else
|
41
51
|
{}
|
42
52
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: render_turbo_stream
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- christian
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-06-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -29,8 +29,8 @@ description: 'A set of helpers that allow a UNIFIED WORKFLOW for TurboStream and
|
|
29
29
|
from the controller. There is no need to write *.turbo_stream.* templates anymore.
|
30
30
|
Logic can stay on in the controller. Javascript actions can also be executed directly
|
31
31
|
from the controller. TESTING: To reduce the amount of hard-to-maintain system tests,
|
32
|
-
|
33
|
-
|
32
|
+
request tests are possible. A DEMO PROJECT with all this built in, along with system
|
33
|
+
and request tests, is linked in the README.'
|
34
34
|
email:
|
35
35
|
- christian@sedlmair.ch
|
36
36
|
executables: []
|
@@ -41,11 +41,13 @@ files:
|
|
41
41
|
- Rakefile
|
42
42
|
- app/controllers/render_turbo_stream/application_controller.rb
|
43
43
|
- app/controllers/render_turbo_stream/render_controller.rb
|
44
|
+
- app/models/render_turbo_stream/option.rb
|
44
45
|
- app/views/layouts/_add_turbo_frame_tag.html.erb
|
45
46
|
- app/views/render_turbo_stream.turbo_stream.erb
|
46
47
|
- app/views/render_turbo_stream_command.html.erb
|
47
48
|
- app/views/render_turbo_stream_empty_template.html.erb
|
48
49
|
- app/views/render_turbo_stream_request_test.html.erb
|
50
|
+
- db/migrate/20230616070450_create_render_turbo_stream_options.rb
|
49
51
|
- lib/render_turbo_stream.rb
|
50
52
|
- lib/render_turbo_stream/channel_libs.rb
|
51
53
|
- lib/render_turbo_stream/channel_view_helpers.rb
|
@@ -86,5 +88,5 @@ requirements: []
|
|
86
88
|
rubygems_version: 3.4.12
|
87
89
|
signing_key:
|
88
90
|
specification_version: 4
|
89
|
-
summary:
|
91
|
+
summary: Make working with Turbo fun!
|
90
92
|
test_files: []
|