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

Instance Method Details

#broadcast_expo_turbo_refresh_later_to(*streamables, request_id: ::Turbo.current_request_id, **attributes) ⇒ Object



125
126
127
# File 'lib/expo_turbo/rails/controller.rb', line 125

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



121
122
123
# File 'lib/expo_turbo/rails/controller.rb', line 121

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

Raises:

  • (ArgumentError)


113
114
115
116
117
118
119
# File 'lib/expo_turbo/rails/controller.rb', line 113

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

Raises:

  • (ArgumentError)


105
106
107
108
109
110
111
# File 'lib/expo_turbo/rails/controller.rb', line 105

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



83
84
85
86
# File 'lib/expo_turbo/rails/controller.rb', line 83

def expo_turbo_cache_key(*keys)
  expo_turbo_vary_by_frame!
  [*keys, *expo_turbo_cache_variant]
end

#expo_turbo_cache_variantObject



70
71
72
# File 'lib/expo_turbo/rails/controller.rb', line 70

def expo_turbo_cache_variant
  Frames.cache_variant(expo_turbo_frame_request_id)
end

#expo_turbo_frame_request?Boolean

Returns:

  • (Boolean)


60
61
62
# File 'lib/expo_turbo/rails/controller.rb', line 60

def expo_turbo_frame_request?
  expo_turbo_frame_request_id.present?
end

#expo_turbo_frame_request_idObject



64
65
66
67
68
# File 'lib/expo_turbo/rails/controller.rb', line 64

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_streamObject



88
89
90
# File 'lib/expo_turbo/rails/controller.rb', line 88

def expo_turbo_stream
  view_context.expo_turbo_stream
end

#expo_turbo_vary_by_frame!Object



74
75
76
77
78
79
80
81
# File 'lib/expo_turbo/rails/controller.rb', line 74

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") }
  response.set_header "Vary", values.join(", ")
end

#render_expo_turbo(template, locals: {}, status: :ok) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/expo_turbo/rails/controller.rb', line 39

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



92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/expo_turbo/rails/controller.rb', line 92

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