render_turbo_stream 1.4.15 → 2.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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f1923db5dbed0c8a3f0cc583ba8de9469b16f0d09fdf3d46b48002ee1099537a
|
4
|
+
data.tar.gz: 7c2bdf446e15de06c2704311fc2725b84613592ac91827eaa4df69a51d383d1a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2258c4ae8b77734f82837a883011591a5d6798d1110f3b63cf7ea557a3a3c60e8f5a358dd9a3dc963c02e0215979d91842d25dd94dfaf6c79e8cc3cc4483e59
|
7
|
+
data.tar.gz: 1495b280772066632effbc8bf484c9d5aa867e3c8fe86d745b6264fb1e0b029420be850bfe432765ade82bc0d5617fcb1dcce2ca2a5611e4c8e01b150483f5bb
|
data/README.md
CHANGED
@@ -2,17 +2,21 @@
|
|
2
2
|
|
3
3
|
Defining templates like `(create|update).turbo_stream.haml` annoyed me.
|
4
4
|
|
5
|
-
|
5
|
+
The biggest advantage of this gem is the testing strategy.
|
6
|
+
|
7
|
+
Working consistently with turbo_stream means shooting lots of partials from the backend to the frontend. This always requires the same attributes: the path to the partial, the html-id that turbo_stream points to, and maybe some locals. This gem serialises that: Partials can be controlled directly from the controller. It sets the status, generates a flash message, handles redirection, pushes it all to the front. Includes helpers for enabling request tests.
|
6
8
|
|
7
9
|
And build it dynamically: Most [turbo_power](https://github.com/marcoroth/turbo_power) commands, such as adding a css class to an html element or pushing a state to the browser history, work directly from the controller. Since turbo allows it, custom javascript functions are also possible.
|
8
10
|
|
9
11
|
ATTENTION: This plugin is in a early state.
|
10
12
|
|
11
|
-
Hope this gem can help you.
|
12
|
-
|
13
13
|
An overview of how we design a rails-7 application with turbo
|
14
14
|
is [published on dev.to](https://dev.to/chmich/rails-7-vite-wrapping-up-1pia).
|
15
15
|
|
16
|
+
A quick and dirty application with all the features, including tests, built in is [here](https://gitlab.com/sedl/renderturbostream_railsapp).
|
17
|
+
|
18
|
+
Hope it can help you.
|
19
|
+
|
16
20
|
## Installation
|
17
21
|
|
18
22
|
```ruby
|
@@ -71,6 +75,9 @@ To get redirection and many other options working, you need to follow the instal
|
|
71
75
|
|
72
76
|
A comprehensive tutorial on turbo and how to check that it is working properly can be found at [hotrails.dev](https://www.hotrails.dev/turbo-rails).
|
73
77
|
|
78
|
+
**Turbo::StreamsChannel**
|
79
|
+
|
80
|
+
The Rails team has seamlessly integrated `ActionCable` as `Turbo::StreamsChannel` into `Turbo Rails`. For installation along with this gem, see the [README](https://gitlab.com/sedl/renderturbostream/-/blob/main/README-cable.md).
|
74
81
|
## Usage
|
75
82
|
|
76
83
|
`turbo_stream_save` is a special method for streamlining `update` or `create` functions with `turbo_stream`. A controller action for update might look like this:
|
@@ -140,11 +147,19 @@ render_turbo_stream(
|
|
140
147
|
|
141
148
|
Under the hood, inside a `*.turbo_stream.erb` template, it does the following: `= turbo_stream.send args.first, *(args[1..-1])`
|
142
149
|
|
143
|
-
**
|
150
|
+
**WORKAROUNDS for redirects inside frame**
|
144
151
|
|
145
152
|
Suppose you have a CRUD controller that should do all its actions inside a turbo frame. Classic redirect_to, together with a turbo_stream action on the same response, would raise «Render and/or redirect were called multiple times in this action». See [issue](https://gitlab.com/sedl/renderturbostream/-/issues/3).
|
146
153
|
|
147
|
-
|
154
|
+
There are two workarounds:
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
config.x.render_turbo_stream.use_cable_for_turbo_stream_save = true
|
158
|
+
```
|
159
|
+
|
160
|
+
With this config, the `turbo_stream_save` method will send flash messages through `Turbo::StreamsChannel` (if installed as described above) to a channel to the currently logged in user in parallel with the redirect.
|
161
|
+
|
162
|
+
Another workaround is to use the src attribute of the parent frame. `turbo_frame_set_src` comes from turbo_power. The code might look like this:
|
148
163
|
|
149
164
|
```ruby
|
150
165
|
def update
|
@@ -162,17 +177,6 @@ def update
|
|
162
177
|
|
163
178
|
```
|
164
179
|
|
165
|
-
**Turbo::StreamsChannel**
|
166
|
-
|
167
|
-
Another workaround as described above, but with more advantages, is to use Turbo Streams, which are seamlessly integrated into `turbo rails`. See the [README](https://gitlab.com/sedl/renderturbostream/-/blob/main/README-cable.md).
|
168
|
-
If setup well and configured by
|
169
|
-
|
170
|
-
```ruby
|
171
|
-
config.x.render_turbo_stream.use_cable = true
|
172
|
-
```
|
173
|
-
|
174
|
-
The `turbo_stream_save` method, in the case of classical redirects (by redirect_to), would send the flashes plus additional partials, declared on arguments by `Turbo::StreamsChannel` in parallel to the redirect.
|
175
|
-
|
176
180
|
**Parameters for turbo_stream_save**
|
177
181
|
|
178
182
|
save_action,
|
@@ -1,18 +1,29 @@
|
|
1
1
|
module RenderTurboStream
|
2
2
|
module TurboCableHelpers
|
3
3
|
|
4
|
-
def
|
4
|
+
def cable_to_all_authenticated_users
|
5
5
|
if user_signed_in?
|
6
6
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
10
|
+
def cable_to_me(id, action, *args, partial: nil, locals: nil)
|
11
|
+
begin
|
12
|
+
u_id = helpers.current_user&.id
|
13
|
+
a=1
|
14
|
+
unless u_id.present?
|
15
|
+
Rails.logger.debug(' • SKIP RenderTurboStream.cable_to_me because current_user is nil')
|
16
|
+
return
|
17
|
+
end
|
18
|
+
rescue
|
19
|
+
Rails.logger.debug(' • ERROR RenderTurboStream.cable_to_me because current_user is not available')
|
20
|
+
return
|
21
|
+
end
|
11
22
|
if Rails.env.test?
|
12
23
|
args = {
|
13
|
-
target:
|
24
|
+
target: "##{id}",
|
14
25
|
action: action,
|
15
|
-
type: '
|
26
|
+
type: 'cable-partial',
|
16
27
|
args: args,
|
17
28
|
partial: partial,
|
18
29
|
locals: locals
|
@@ -33,9 +44,9 @@ module RenderTurboStream
|
|
33
44
|
"broadcast_#{action}_to",
|
34
45
|
"current_user_#{helpers.current_user.id}",
|
35
46
|
*args,
|
36
|
-
target:
|
47
|
+
target: id,
|
37
48
|
partial: partial,
|
38
|
-
locals: locals,
|
49
|
+
locals: locals&.symbolize_keys,
|
39
50
|
layout: false
|
40
51
|
)
|
41
52
|
else
|
@@ -1,15 +1,27 @@
|
|
1
1
|
module RenderTurboStream
|
2
2
|
module TurboCableViewHelpers
|
3
3
|
|
4
|
-
def
|
4
|
+
def cable_from_me
|
5
5
|
if current_user
|
6
6
|
turbo_stream_from "current_user_#{current_user.id}"
|
7
|
+
else
|
8
|
+
Rails.logger.debug(" • SKIP CABLE_FROM_ME because not authenticated")
|
7
9
|
end
|
8
10
|
end
|
9
11
|
|
10
|
-
def
|
12
|
+
def cable_from_all_authenticated_users
|
11
13
|
if user_signed_in?
|
12
|
-
turbo_stream_from "
|
14
|
+
turbo_stream_from "all_authenticated_users"
|
15
|
+
else
|
16
|
+
Rails.logger.debug(" • SKIP CABLE_FROM_ALL_AUTHENTICATED_USERS because not authenticated")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def local_model(object)
|
21
|
+
if (object.is_a?(String) && object[0..5] == 'gid://') || object.is_a?(GlobalID)
|
22
|
+
GlobalID::Locator.locate(object)
|
23
|
+
else
|
24
|
+
object
|
13
25
|
end
|
14
26
|
end
|
15
27
|
|
data/lib/render_turbo_stream.rb
CHANGED
@@ -158,11 +158,11 @@ module RenderTurboStream
|
|
158
158
|
])
|
159
159
|
elsif save_action && redirect_on_success_to.present?
|
160
160
|
response.status = 302
|
161
|
-
if Rails.configuration.x.render_turbo_stream.
|
161
|
+
if Rails.configuration.x.render_turbo_stream.use_cable_for_turbo_stream_save && helpers.user_signed_in?
|
162
162
|
streams.each do |s|
|
163
163
|
next unless s.is_a?(Hash)
|
164
164
|
Rails.logger.debug(" • Send by Cable => «#{s}»")
|
165
|
-
|
165
|
+
cable_to_me(
|
166
166
|
s[:id],
|
167
167
|
:prepend,
|
168
168
|
partial: s[:partial],
|
@@ -211,6 +211,7 @@ module RenderTurboStream
|
|
211
211
|
if request.format.to_sym == :turbo_stream
|
212
212
|
render template: 'render_turbo_stream', locals: { streams: ary }, layout: false, formats: :turbo_stream
|
213
213
|
else
|
214
|
+
Rails.logger.debug(" • Render Turbo Stream RENDERING AS HTML because request.format => #{request.format}")
|
214
215
|
render template: 'render_turbo_stream', locals: { streams: ary }, layout: false, formats: :html
|
215
216
|
end
|
216
217
|
end
|
@@ -236,7 +237,24 @@ module RenderTurboStream
|
|
236
237
|
class Libs
|
237
238
|
def self.all_responses(response)
|
238
239
|
e = Nokogiri::HTML(response.body).search('#rendered-partials').first
|
239
|
-
|
240
|
+
if e.present?
|
241
|
+
res = JSON.parse(e.inner_html)
|
242
|
+
else
|
243
|
+
res = []
|
244
|
+
end
|
245
|
+
cables = response.headers.to_h.select { |k| k.match(/^test-turbo-cable-[\d]+$/) }
|
246
|
+
cables.each do |k, v|
|
247
|
+
args = JSON.parse(v)
|
248
|
+
html = ApplicationController.render(partial: args['partial'], locals: args['locals'].symbolize_keys)
|
249
|
+
res.push(
|
250
|
+
args.merge(
|
251
|
+
{
|
252
|
+
'html_response' => html,
|
253
|
+
}
|
254
|
+
)
|
255
|
+
)
|
256
|
+
end
|
257
|
+
res
|
240
258
|
end
|
241
259
|
|
242
260
|
# if partial is one word, its checked against the last behind the slash, example: 'articles/form' matches 'form'
|
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
|
+
version: 2.0.0
|
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-05-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|