Module: ExpoTurbo::Rails::Controller
- Extended by:
- ActiveSupport::Concern
- Includes:
- ActionController::Helpers, ActionView::Rendering
- Defined in:
- lib/expo_turbo/rails/controller.rb
Instance Method Summary collapse
- #broadcast_expo_turbo_refresh_later_to(*streamables, request_id: ::Turbo.current_request_id, **attributes) ⇒ Object
- #broadcast_expo_turbo_refresh_to(*streamables, request_id: ::Turbo.current_request_id, **attributes) ⇒ Object
- #broadcast_expo_turbo_stream_later_to(*streamables, content: nil) ⇒ Object
- #broadcast_expo_turbo_stream_to(*streamables, content: nil) ⇒ Object
- #expo_turbo_cache_key(*keys) ⇒ Object
- #expo_turbo_cache_variant ⇒ Object
- #expo_turbo_client_modules ⇒ Object
- #expo_turbo_client_supports?(module_name, requirement) ⇒ Boolean
- #expo_turbo_frame_request? ⇒ Boolean
- #expo_turbo_frame_request_id ⇒ Object
- #expo_turbo_stream ⇒ Object
- #expo_turbo_vary_by_frame! ⇒ Object
- #render_expo_turbo(template, locals: {}, status: :ok) ⇒ Object
- #render_expo_turbo_stream(*streams, status: :ok) ⇒ Object
Instance Method Details
#broadcast_expo_turbo_refresh_later_to(*streamables, request_id: ::Turbo.current_request_id, **attributes) ⇒ Object
275 276 277 |
# File 'lib/expo_turbo/rails/controller.rb', line 275 def broadcast_expo_turbo_refresh_later_to(*streamables, request_id: ::Turbo.current_request_id, **attributes) ExpoTurbo::Rails::Streams.broadcast_refresh_later_to(*streamables, request_id:, **attributes) end |
#broadcast_expo_turbo_refresh_to(*streamables, request_id: ::Turbo.current_request_id, **attributes) ⇒ Object
271 272 273 |
# File 'lib/expo_turbo/rails/controller.rb', line 271 def broadcast_expo_turbo_refresh_to(*streamables, request_id: ::Turbo.current_request_id, **attributes) ExpoTurbo::Rails::Streams.broadcast_refresh_to(*streamables, request_id:, **attributes) end |
#broadcast_expo_turbo_stream_later_to(*streamables, content: nil) ⇒ Object
263 264 265 266 267 268 269 |
# File 'lib/expo_turbo/rails/controller.rb', line 263 def broadcast_expo_turbo_stream_later_to(*streamables, content: nil) raise ArgumentError, "provide content or a block, not both" if block_given? && !content.nil? content = yield(expo_turbo_stream) if block_given? expo_turbo_validate_broadcast_stream!(content) ExpoTurbo::Rails::Streams.broadcast_later_to(*streamables, content: content) end |
#broadcast_expo_turbo_stream_to(*streamables, content: nil) ⇒ Object
255 256 257 258 259 260 261 |
# File 'lib/expo_turbo/rails/controller.rb', line 255 def broadcast_expo_turbo_stream_to(*streamables, content: nil) raise ArgumentError, "provide content or a block, not both" if block_given? && !content.nil? content = yield(expo_turbo_stream) if block_given? expo_turbo_validate_broadcast_stream!(content) ExpoTurbo::Rails::Streams.broadcast_to(*streamables, content: content) end |
#expo_turbo_cache_key(*keys) ⇒ Object
111 112 113 114 |
# File 'lib/expo_turbo/rails/controller.rb', line 111 def expo_turbo_cache_key(*keys) expo_turbo_vary_by_frame! [*keys, *expo_turbo_cache_variant] end |
#expo_turbo_cache_variant ⇒ Object
95 96 97 98 99 |
# File 'lib/expo_turbo/rails/controller.rb', line 95 def expo_turbo_cache_variant negotiation = expo_turbo_module_negotiation module_variant = negotiation.fetch(:latest) ? :latest : negotiation.fetch(:cache_variant) [*Frames.cache_variant(expo_turbo_frame_request_id), :modules, module_variant] end |
#expo_turbo_client_modules ⇒ Object
73 74 75 |
# File 'lib/expo_turbo/rails/controller.rb', line 73 def expo_turbo_client_modules expo_turbo_module_negotiation.fetch(:modules) end |
#expo_turbo_client_supports?(module_name, requirement) ⇒ Boolean
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/expo_turbo/rails/controller.rb', line 77 def expo_turbo_client_supports?(module_name, requirement) raise ArgumentError, "module_name must be a String" unless module_name.is_a?(String) raise ArgumentError, "requirement must be a String" unless requirement.is_a?(String) raise ArgumentError, "requirement must not be empty" if requirement.strip.empty? requirement_parts = requirement.split(",", -1).map(&:strip) raise ArgumentError, "requirement must not contain empty clauses" if requirement_parts.any?(&:empty?) parsed_requirement = Gem::Requirement.new(*requirement_parts) negotiation = expo_turbo_module_negotiation return true if negotiation.fetch(:latest) version = negotiation.fetch(:modules)[module_name] return false unless version parsed_requirement.satisfied_by?(Gem::Version.new(version)) end |
#expo_turbo_frame_request? ⇒ Boolean
63 64 65 |
# File 'lib/expo_turbo/rails/controller.rb', line 63 def expo_turbo_frame_request? expo_turbo_frame_request_id.present? end |
#expo_turbo_frame_request_id ⇒ Object
67 68 69 70 71 |
# File 'lib/expo_turbo/rails/controller.rb', line 67 def expo_turbo_frame_request_id frame_id = request.get_header("HTTP_TURBO_FRAME") frame_id = frame_id.dup.force_encoding(Encoding::UTF_8) if frame_id.is_a?(String) Frames.valid_id?(frame_id) ? frame_id : nil end |
#expo_turbo_stream ⇒ Object
116 117 118 |
# File 'lib/expo_turbo/rails/controller.rb', line 116 def expo_turbo_stream view_context.expo_turbo_stream end |
#expo_turbo_vary_by_frame! ⇒ Object
101 102 103 104 105 106 107 108 109 |
# File 'lib/expo_turbo/rails/controller.rb', line 101 def expo_turbo_vary_by_frame! values = response.headers["Vary"].to_s.split(",").map(&:strip).reject(&:blank?) return response.headers["Vary"] if values.include?("*") values << "Accept" if request.should_apply_vary_header? && values.none? { |value| value.casecmp?("Accept") } values << "Turbo-Frame" if values.none? { |value| value.casecmp?("Turbo-Frame") } values << "X-Expo-Turbo-Modules" if values.none? { |value| value.casecmp?("X-Expo-Turbo-Modules") } response.set_header "Vary", values.join(", ") end |
#render_expo_turbo(template, locals: {}, status: :ok) ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/expo_turbo/rails/controller.rb', line 42 def render_expo_turbo(template, locals: {}, status: :ok) body = render_to_string( inline: File.read(expo_turbo_template_file(template)), type: :erb, formats: [:xml], layout: false, locals: locals ) raise TemplateError, "Expo Turbo templates must render valid UTF-8" unless body.encoding == Encoding::UTF_8 && body.valid_encoding? document = XmlFragments.parse_document(body) XmlFragments.validate_document_ids!(document) expo_turbo_validate_document!(document) render plain: body, content_type: MIME_TYPE, status: status rescue XmlFragments::DocumentIdError raise TemplateError, "Expo Turbo templates must use unique nonblank literal ids" rescue XmlFragments::ParseError raise TemplateError, "Expo Turbo templates must render well-formed UTF-8 XML" end |
#render_expo_turbo_stream(*streams, status: :ok) ⇒ Object
242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'lib/expo_turbo/rails/controller.rb', line 242 def render_expo_turbo_stream(*streams, status: :ok) streams << yield(expo_turbo_stream) if block_given? body = streams.flatten.compact.join raise TemplateError, "Expo Turbo Stream responses must render valid UTF-8" unless body.encoding == Encoding::UTF_8 && body.valid_encoding? document = XmlFragments.parse_stream_fragment(body) expo_turbo_validate_stream_fragment!(document) render plain: body, content_type: TURBO_STREAM_MIME_TYPE, status: status rescue XmlFragments::ParseError raise TemplateError, "Expo Turbo Stream responses must contain well-formed XML Stream fragments" end |