Skip to content

Commit

Permalink
Support nested Kits (#840)
Browse files Browse the repository at this point in the history
With this change, Kits will now propagate down to nested modules. There
is currently no way to disable this behaviour, but if anyone needs that,
the plan is to introduce `BasicKit` which will not propagate.
  • Loading branch information
joeldrapper authored Feb 3, 2025
1 parent 19a9271 commit 0c94fd5
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 15 deletions.
8 changes: 8 additions & 0 deletions fixtures/components.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,12 @@ module Components

autoload :SayHi, "components/say_hi"
autoload :Article, "components/article"

module Foo
class Bar < Phlex::HTML
def view_template
h1 { "Bar" }
end
end
end
end
35 changes: 20 additions & 15 deletions lib/phlex/kit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,27 +49,32 @@ def const_added(name)
me = self
constant = const_get(name)

if Class === constant && constant < Phlex::SGML
constant.include(self)
case constant
when Class
if constant < Phlex::SGML
constant.include(self)

constant = nil
constant = nil

define_method(name) do |*args, **kwargs, &block|
constant = me.const_get(name)
render(constant.new(*args, **kwargs), &block)
end
define_method(name) do |*args, **kwargs, &block|
constant = me.const_get(name)
render(constant.new(*args, **kwargs), &block)
end

define_singleton_method(name) do |*args, **kwargs, &block|
component, fiber_id = Thread.current[:__phlex_component__]
if (component && fiber_id == Fiber.current.object_id)
component.instance_exec do
constant = me.const_get(name)
render(constant.new(*args, **kwargs), &block)
define_singleton_method(name) do |*args, **kwargs, &block|
component, fiber_id = Thread.current[:__phlex_component__]
if (component && fiber_id == Fiber.current.object_id)
component.instance_exec do
constant = me.const_get(name)
render(constant.new(*args, **kwargs), &block)
end
else
raise "You can't call `#{name}' outside of a Phlex rendering context."
end
else
raise "You can't call `#{name}' outside of a Phlex rendering context."
end
end
when Module
constant.extend(Phlex::Kit)
end

super
Expand Down
6 changes: 6 additions & 0 deletions quickdraw/kit.test.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true

require "components"
require "sgml_helper"
include SGMLHelper

class Example < Phlex::HTML
include Components
Expand All @@ -19,3 +21,7 @@ def view_template
test "defines methods for its components" do
assert_equal Example.new.call, %(<article><h1>Hi Joel</h1><h1>Hi Joel</h1>Inside</article><article><h1>Hi Will</h1>Inside</article>)
end

test "nested kits" do
assert_equal_html phlex { Components::Foo::Bar() }, "<h1>Bar</h1>"
end

0 comments on commit 0c94fd5

Please sign in to comment.