Skip to content

Commit

Permalink
Allow context to be set via call (#821)
Browse files Browse the repository at this point in the history
This PR is doing more than one thing 🙈

If you want me to split this up, let me know. But in addition to
allowing `context` to be passed via `call`, I've also moved where
`view_context` is stored. It's now inside of the `Phlex::Context`
instead of in an ivar of SGML.

I think that ultimately, `view_context` as a concept can be fully
removed from Phlex, and only defined in phlex-rails which is the only
place it gets used. But as I went down that path the changes got more
and more complicated. `phlex-rails` then needs to redefine `call`, which
means it needs to be tightly coupled to `phlex`'s definition of
`call`... it got messy.

Let me know what you think, and if you want me to leave `@_view_context`
alone, that's fine too. I'll open a sibling PR over on phlex-rails to
coincide with this change.
  • Loading branch information
willcosgrove authored Nov 25, 2024
1 parent dc1248a commit 960ad5a
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 10 deletions.
5 changes: 3 additions & 2 deletions lib/phlex/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@

# @api private
class Phlex::Context
def initialize(user_context = {})
def initialize(user_context: {}, view_context: nil)
@buffer = +""
@capturing = false
@user_context = user_context
@fragments = nil
@in_target_fragment = false
@halt_signal = nil
@view_context = view_context
end

attr_accessor :buffer, :capturing, :user_context, :in_target_fragment

attr_reader :fragments
attr_reader :fragments, :view_context

def target_fragments(fragments)
@fragments = fragments.to_h { |it| [it, true] }
Expand Down
17 changes: 9 additions & 8 deletions lib/phlex/sgml.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,16 @@ def to_proc
proc { |c| c.render(self) }
end

def call(buffer = +"", context: Phlex::Context.new, view_context: nil, parent: nil, fragments: nil, &block)
def call(buffer = +"", context: {}, view_context: nil, parent: nil, fragments: nil, &block)
@_buffer = buffer
@_context = context
@_view_context = view_context
@_context = phlex_context = parent&.__context__ || Phlex::Context.new(user_context: context, view_context:)
@_parent = parent

raise Phlex::DoubleRenderError.new("You can't render a #{self.class.name} more than once.") if @_rendered
@_rendered = true

if fragments
@_context.target_fragments(fragments)
phlex_context.target_fragments(fragments)
end

block ||= @_content_block
Expand All @@ -89,7 +88,7 @@ def call(buffer = +"", context: Phlex::Context.new, view_context: nil, parent: n
Fiber[:__phlex_component__] = self
end

@_context.around_render do
phlex_context.around_render do
before_template(&block)

around_template do
Expand All @@ -113,10 +112,12 @@ def call(buffer = +"", context: Phlex::Context.new, view_context: nil, parent: n
if Phlex::SUPPORTS_FIBER_STORAGE
Fiber[:__phlex_component__] = original_fiber_storage
end
buffer << context.buffer
buffer << phlex_context.buffer
end
end

protected def __context__ = @_context

def context
@_context.user_context
end
Expand Down Expand Up @@ -205,10 +206,10 @@ def flush
def render(renderable = nil, &)
case renderable
when Phlex::SGML
renderable.call(@_buffer, context: @_context, view_context: @_view_context, parent: self, &)
renderable.call(@_buffer, parent: self, &)
when Class
if renderable < Phlex::SGML
renderable.new.call(@_buffer, context: @_context, view_context: @_view_context, parent: self, &)
renderable.new.call(@_buffer, parent: self, &)
end
when Enumerable
renderable.each { |r| render(r, &) }
Expand Down

0 comments on commit 960ad5a

Please sign in to comment.