render_turbo_stream 4.3.1 → 4.3.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 414f885f38878ae67239db4d797a57f1a0826daf8fdea5f94d6ce7a1b2a0a54a
4
- data.tar.gz: eb8b5012eec604e899f088337697491c41522337bf4cec7fc66067462089cc2a
3
+ metadata.gz: d66f0d9cb7dc4822dbcaf38e286b855386e8637b07a922db1714b14ab63d0c6d
4
+ data.tar.gz: 017a6047f0c07a1f2847f7be92d810483c00690e1c31f0cb31581004d48f8f18
5
5
  SHA512:
6
- metadata.gz: 454f651f6801fdb48a2bd2a76167a8d8d0fafd2712242aa9ce5db5f4d72d30bc95a7e4406e7d9da0f67b1542262b2d46a0c60b47cf52ce4773544fc94cdb636b
7
- data.tar.gz: 386d2f4bf0d2a940969fe14fd280cb9afe9d09fac6568b9fc5ea98ddcd054a48de547d1a677275e6c418389efe309b10f621258e617c515329105db72b5960eb
6
+ metadata.gz: a3853c69389798f965cb41e629fb208e6926b3a4ce2d5f0f925554cec41d470fa5963ad6d88dd1712e787be3db683f1e61cce7411c78f8dda574069f7d5a9b55
7
+ data.tar.gz: 78719ff0ab9c7299639161ba2a966786d18dc79b9f401e8112b58656f2270436c51119c3eb6297f73c4df4e40dc7843bebe4496a9a5cbcc6d187b6898fa00245
data/README.md CHANGED
@@ -31,13 +31,21 @@ gem 'render_turbo_stream'
31
31
  bundle install
32
32
  ```
33
33
 
34
+ **Include the helpers**
35
+
34
36
  ApplicationController
35
37
 
36
38
  ```ruby
37
39
  include RenderTurboStream::ControllerHelpers
38
40
  ```
39
41
 
40
- spec/rails_helper.rb
42
+ Create a Initializer
43
+
44
+ ```ruby
45
+ ActionView::Base.send :include, RenderTurboStream::ViewHelpers
46
+ ```
47
+
48
+ spec/rails_helper.rb (We are using rspec instead of minitest)
41
49
 
42
50
  ```ruby
43
51
  RSpec.configure do |config|
@@ -55,6 +63,8 @@ Required Configurations for Flash Partial
55
63
  config.x.render_turbo_stream.flash_partial = 'layouts/flash'
56
64
  config.x.render_turbo_stream.flash_target_id = 'flash-box'
57
65
  config.x.render_turbo_stream.flash_turbo_action = 'prepend'
66
+
67
+ # In case of redirection a flash cannot be sent by TurboStream
58
68
  config.x.render_turbo_stream.allow_channel_to_me_for_turbo_stream_save = true
59
69
  ```
60
70
 
@@ -102,15 +112,28 @@ The Rails team has integrated `ActionCable` as `Turbo::StreamsChannel` into `Tur
102
112
  def update
103
113
  turbo_stream_save(
104
114
  @article.update(article_params),
105
- if_success_turbo_redirect_to: articles_path,
106
- target_id: 'customer-form',
115
+ if_success_redirect_to: articles_path,
107
116
  partial: 'form'
108
117
  )
109
118
  end
110
119
  ```
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:
112
120
 
113
- If no partial is given, it renders the default template as turbo_stream.
121
+ Assuming we want to build a form that works within a turbo-frame, including flash messages and redirects, we have to build all that inside a `turbo-frame`, and, within that we need a target-id, that must not be a turbo-frame. For that, there is a helper:
122
+
123
+ ```haml
124
+ = turbo_target_tag do
125
+ = simple_form ...
126
+ ```
127
+
128
+ This will generate an element like `<turbo-target id="new-article-form">`.
129
+
130
+ And the form should work!
131
+
132
+ If the update succeeds, it sends a flash message by channel(!), because stream cannot work alongside redirect, and redirects to articles#index. If it fails, it sends a flash message by stream and replaces the form tag by stream so that the invalid fields are marked red and you can see the errors inside the form.
133
+
134
+ Technical details? see later in this README.
135
+
136
+ As mentioned above, the turbo stream actions are handled by the `render_turbo_stream` controller helper:
114
137
 
115
138
  ```ruby
116
139
  render_turbo_stream(
@@ -130,9 +153,6 @@ render_turbo_stream(
130
153
 
131
154
  If the update succeeds, it will do a `redirect_to` action from turbo_power
132
155
 
133
-
134
- **locals**: The hash for locals goes through a `symbolize_keys`, so you need to use locals in used partials like this: `locals[:message]`.
135
-
136
156
  **More options**
137
157
 
138
158
  `render_turbo_stream` interprets a hash as a partial to be sent by `turbo_stream` and an array as a command to be sent. This allows you to perform most actions from, e.g., [turbo_power](https://github.com/marcoroth/turbo_power). An example of adding a css class to an html element and updating the browser history would look like this:
@@ -163,7 +183,30 @@ If this config is set to true, Turbo::StreamsChannel is installed and a current
163
183
 
164
184
  If an `if_success_redirect_to` argument is provided and the save action was successful, `turbo_stream_save` would send the partials by channel.
165
185
 
166
- **target-ID: Avoid the same definition in multiple places**
186
+ **Target-ID**
187
+
188
+ The target ID for turbo has to be unique for sure, and it has to be nice, because, at least during testing the developer has to deal with it. Since the default ID builder dom_id is too simple for this, there are some helpers. How it works is best shown by the `request-test helper target_id`:
189
+
190
+ ```ruby
191
+ # target_id(virtual_view_path, object)
192
+ target_id('customers/_form', Customer.new) #=> 'new-customer-form'
193
+ target_id('customers/_form', Customer.first) #=> 'customer-1-form'
194
+ target_id('customers/_form', nil) #=> 'customers-form'
195
+ target_id('customers/_form', 'hi-joe') #=> 'hi-joe'
196
+ ```
197
+
198
+ View-helper: Assuming we are inside `customers/_my_form`:
199
+
200
+ ```ruby
201
+ #=> Assuming controller-name "customers" and variable @customer is present
202
+ target_id
203
+ #=> 'customer-1-my-form'
204
+
205
+ target_id(Customer.new)
206
+ #=> 'new-customer-my-form'
207
+ ```
208
+
209
+ **Target-ID: Avoid the same definition in multiple places**
167
210
 
168
211
  Without this gem a turbo action would be wrapped within two frames, for example:
169
212
 
@@ -187,7 +230,7 @@ This means that the target id must be defined in several places: inside a partia
187
230
  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:
188
231
 
189
232
  1. Render the partial with the provided locals
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.
233
+ 2. Grabs into the partial by Nokogiri and looks for the first `turbo-frame` or `turbo-target` element, get the id and uses this as target_id.
191
234
  3. If all that not is found it raises a exception
192
235
  4. wraps the partial within the `turbo_stream.*` and sends this to the front.
193
236
 
@@ -7,7 +7,6 @@
7
7
  <% if args.is_a?(Array) %>
8
8
 
9
9
  <% ctl = "turbo_stream.#{args.first}, #{args[1..-1].join(', ')}" %>
10
- <% Rails.logger.debug(" • render-turbo-stream => #{ctl}") %>
11
10
  <%= turbo_stream.send args.first, *(args[1..-1]) %>
12
11
 
13
12
 
@@ -26,7 +25,9 @@
26
25
 
27
26
  <% unless args[:target].present? %>
28
27
  <% args[:target] = RenderTurboStream::Libs.fetch_arguments_from_rendered_string(rendered_html)[:target] %>
29
- <% unless args[:target].present? %>
28
+ <% if args[:target].present? %>
29
+ <% Rails.logger.debug(" • Target #{args[:target]} found in #{args[:partial]}") %>
30
+ <% else %>
30
31
  <% raise 'No target specified by arguments and no target found inside the rendered partial' %>
31
32
  <% end %>
32
33
  <% end %>
@@ -38,7 +39,6 @@
38
39
 
39
40
 
40
41
  <% if args[:action].present? %>
41
- <% Rails.logger.debug(" • render-turbo-stream #{args[:action].upcase} => #{info}") %>
42
42
  <%= turbo_stream.send args[:action].to_sym, target_id do %>
43
43
 
44
44
  <%= rendered_html %>
@@ -37,6 +37,7 @@ module RenderTurboStream
37
37
  r = RenderTurboStream::Libs.fetch_arguments_from_rendered_string(rendered_html)
38
38
  target_id = r[:target_id]
39
39
  target = r[:target]
40
+ Rails.logger.debug(" • Target #{r[:target]} found in #{partial.to_s + template.to_s}")
40
41
  end
41
42
  end
42
43
 
@@ -12,7 +12,7 @@ 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: the gem grabs inside the rendered content for turbo_frame_tag or element with attribute data_turbo_target and takes the id from there.
15
+ target_id: nil, # IF NIL: the gem grabs inside the rendered content for turbo-frame tag or turbo-target (element from helper of this gem) tag and takes the id from there.
16
16
  partial: nil, # if nil: the gem renders the default template by turbo-stream
17
17
  action: 'replace', # options: append, prepend
18
18
  locals: {},
@@ -79,6 +79,7 @@ module RenderTurboStream
79
79
  response.status = 302
80
80
  flash[:alert] = flashes[:alerts]
81
81
  flash[:notice] = flashes[:notices]
82
+ Rails.logger.debug(" • Successful saved && Redirect by «turbo_redirect_to»")
82
83
  Rails.logger.debug(" • Set flash[:alert] => #{flashes[:alerts]}") if flashes[:alerts].present?
83
84
  Rails.logger.debug(" • Set flash[:notice] => #{flashes[:notices]}") if flashes[:notices].present?
84
85
  render_turbo_stream([
@@ -91,18 +92,21 @@ module RenderTurboStream
91
92
  elsif save_action && if_success_redirect_to.present?
92
93
  response.status = 303
93
94
  if allow_channel
94
- Rails.logger.debug(" • Sent #{streams.length} actions through Turbo::StreamsChannel to enable defined redirection because allowed in configs.")
95
+ Rails.logger.debug(" • Send actions through Turbo::StreamsChannel")
95
96
  c_libs = RenderTurboStream::ChannelLibs.new(response)
96
97
  c_libs.send_actions_to_channel("authenticated-user-#{helpers.current_user.id}", streams, @render_turbo_stream_evaluate_instance_variables)
97
98
  else
98
99
  flash[:alert] = flashes[:alerts]
99
100
  flash[:notice] = flashes[:notices]
101
+ Rails.logger.debug(" • Turbo::StreamsChannel NOT ALLOWED BY CONFIGS!")
100
102
  Rails.logger.debug(" • Set flash[:alert] => #{flashes[:alerts]}") if flashes[:alerts].present?
101
103
  Rails.logger.debug(" • Set flash[:notice] => #{flashes[:notices]}") if flashes[:notices].present?
104
+ Rails.logger.debug(" • Could not send #{streams.length} actions => #{streams}")
102
105
  end
103
106
  redirect_to if_success_redirect_to
104
107
 
105
108
  else
109
+ Rails.logger.debug(" • Respond by TurboStream in #{streams.length} #{'action'.pluralize(streams.length)}")
106
110
  streams += libs.generate_action(controller_path, target_id, action, partial, (partial ? nil : action_name), locals)
107
111
  render_turbo_stream(streams)
108
112
 
@@ -114,6 +118,7 @@ module RenderTurboStream
114
118
 
115
119
  ary = []
116
120
  array.each do |pr|
121
+ cmd = nil
117
122
  if !pr.present?
118
123
  Rails.logger.warn " WARNING render_turbo_stream: Empty element inside attributes: «#{array}»"
119
124
  elsif pr.is_a?(Hash)
@@ -133,13 +138,15 @@ module RenderTurboStream
133
138
  end
134
139
  r[:type] = 'stream-partial'
135
140
 
136
- ary.push(r)
141
+ cmd = r
137
142
  elsif pr.is_a?(Array)
138
143
  raise "array has to contain at least one element: #{pr}" unless pr.first.present?
139
- ary.push(pr)
144
+ cmd = pr
140
145
  else
141
146
  raise "ERROR render_turbo_stream invalid type: Only hash or array allowed"
142
147
  end
148
+ ary.push(cmd) if cmd
149
+ Rails.logger.debug(" • Stream => #{cmd}")
143
150
  end
144
151
 
145
152
  if request.format.to_sym == :turbo_stream
@@ -36,7 +36,7 @@ module RenderTurboStream
36
36
  def self.fetch_arguments_from_rendered_string(rendered_string)
37
37
  noko = Nokogiri::HTML(rendered_string)
38
38
  frame = noko.at_css('turbo-frame')
39
- ele = noko.at_css('[data_turbo_target]')
39
+ ele = noko.at_css('turbo-target')
40
40
  if frame.present?
41
41
  {
42
42
  target_id: frame[:id],
@@ -52,5 +52,29 @@ module RenderTurboStream
52
52
  end
53
53
  end
54
54
 
55
+ def self.target_id(virt_view_path, id)
56
+ if id.is_a?(String)
57
+ id
58
+ elsif !id
59
+ [
60
+ virt_view_path.gsub('/', '-').gsub('-_', '-')
61
+ ].join('-')
62
+ else
63
+ unless id.methods.include?(:id)
64
+ raise("target_id / argument ID: Only String or object with method :id accepted")
65
+ end
66
+ (
67
+ (
68
+ id.id ?
69
+ [id.class.to_s.downcase, id.id] :
70
+ ['new', id.class.to_s.downcase]
71
+ ) +
72
+ [
73
+ virt_view_path.split('/').last.sub(/^_/, '')
74
+ ]
75
+ ).join('-')
76
+ end
77
+ end
78
+
55
79
  end
56
80
  end
@@ -84,6 +84,11 @@ module RenderTurboStream
84
84
  )
85
85
  end
86
86
 
87
+ def target_id(relative_view_path, object)
88
+ libs = RenderTurboStream::Libs
89
+ libs.target_id(relative_view_path, object)
90
+ end
91
+
87
92
  end
88
93
  end
89
94
  end
@@ -1,3 +1,3 @@
1
1
  module RenderTurboStream
2
- VERSION = "4.3.1"
2
+ VERSION = "4.3.3"
3
3
  end
@@ -0,0 +1,20 @@
1
+ module RenderTurboStream
2
+ module ViewHelpers
3
+
4
+ def turbo_target_tag(id = nil, &block)
5
+ content_tag :'turbo-target', id: target_id(id) do
6
+ if block_given?
7
+ capture(&block)
8
+ end
9
+ end
10
+ end
11
+
12
+ def target_id(id = nil)
13
+ libs = RenderTurboStream::Libs
14
+ virt_path = self.instance_variable_get('@current_template').instance_variable_get('@virtual_path')
15
+ obj = (id ? id : eval("@#{controller_name.singularize}"))
16
+ libs.target_id(virt_path, obj)
17
+ end
18
+
19
+ end
20
+ end
@@ -10,6 +10,7 @@ require 'render_turbo_stream/controller_helpers'
10
10
  require 'render_turbo_stream/controller_channel_helpers'
11
11
 
12
12
  require 'render_turbo_stream/channel_view_helpers'
13
+ require 'render_turbo_stream/view_helpers'
13
14
 
14
15
  require 'render_turbo_stream/channel_libs'
15
16
  require 'render_turbo_stream/controller_libs'
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.3.1
4
+ version: 4.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - christian
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-16 00:00:00.000000000 Z
11
+ date: 2023-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -62,6 +62,7 @@ files:
62
62
  - lib/render_turbo_stream/test/request/helpers.rb
63
63
  - lib/render_turbo_stream/test/request/libs.rb
64
64
  - lib/render_turbo_stream/version.rb
65
+ - lib/render_turbo_stream/view_helpers.rb
65
66
  - lib/tasks/render_turbo_stream_tasks.rake
66
67
  homepage: https://gitlab.com/sedl/renderturbostream
67
68
  licenses: