Skip to content

Commit

Permalink
Quick and dirty implementation of crazy globals
Browse files Browse the repository at this point in the history
  • Loading branch information
joeldrapper committed Mar 12, 2024
1 parent aa50c60 commit f8cca44
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 0 deletions.
14 changes: 14 additions & 0 deletions fixtures/crazy_example.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module SomeNamespace
class CrazyComponent < Phlex::HTML

This comment has been minimized.

Copy link
@joeldrapper

joeldrapper Mar 12, 2024

Author Collaborator

Defining this component here, defines the CrazyComponent method on SomeNamespace.

def initialize(name)
@name = name
end

def template
article do
h1 { "Hello, #{@name}" }
yield
end
end
end
end
20 changes: 20 additions & 0 deletions lib/phlex/sgml.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ def call(...)
new(...).call
end

def inherited(subclass)
return unless subclass.name
return if subclass.name.start_with?("Sus::")
return if subclass.name.start_with?("Phlex::")
constant_path = subclass.name.split("::")
name = constant_path.pop
namespace = Module.const_get(constant_path.join("::"))

This comment has been minimized.

Copy link
@joeldrapper

joeldrapper Mar 12, 2024

Author Collaborator

Should obviously check that this module exists and is happy to have you define these methods on it. See #674


namespace.define_singleton_method(name) do |*args, **kwargs, &block|
Thread.current[:__phlex_current__].send(:render,

This comment has been minimized.

Copy link
@joeldrapper

joeldrapper Mar 12, 2024

Author Collaborator

This method is called with no context about where it should render, so it needs to use a Thread local.

subclass.new(*args, **kwargs), &block
)
end
end

# Create a new instance of the component.
# @note The block will not be delegated {#initialize}. Instead, it will be sent to {#template} when rendering.
def new(*args, **kwargs, &block)
Expand Down Expand Up @@ -103,6 +118,8 @@ def call(...)

# @api private
def __final_call__(buffer = +"", context: Phlex::Context.new, view_context: nil, parent: nil, fragment: nil, &block)
previous_rendering_component = Thread.current[:__phlex_current__]
Thread.current[:__phlex_current__] = self

This comment has been minimized.

Copy link
@joeldrapper

joeldrapper Mar 12, 2024

Author Collaborator

This is how we’re able to connect the dots when the SomeNamespace::CrazyComponent() method is called.

@_buffer = buffer
@_context = context
@_view_context = view_context
Expand Down Expand Up @@ -133,6 +150,9 @@ def __final_call__(buffer = +"", context: Phlex::Context.new, view_context: nil,
end

buffer << context.buffer unless parent

ensure
Thread.current[:__phlex_current__] = previous_rendering_component
end

# Access the current render context data
Expand Down
15 changes: 15 additions & 0 deletions test/phlex/crazy_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
require "crazy_example"

This comment has been minimized.

Copy link
@joeldrapper

joeldrapper Mar 12, 2024

Author Collaborator

Had to put the component in a fixture so it gets a “normal” name rather than a Sus name.


class Example < Phlex::HTML
def template
SomeNamespace::CrazyComponent("Joel") do
strong { "This is mad" }
end
end
end

describe Example do
it "renders a crazy example" do
expect(Example.new.call).to be == %(<article><h1>Hello, Joel</h1><strong>This is mad</strong></article>)
end
end

0 comments on commit f8cca44

Please sign in to comment.