From cd1234b9923a0763ba4bedca07bbdbe0d5451444 Mon Sep 17 00:00:00 2001 From: Joel Drapper Date: Mon, 9 Sep 2024 03:16:57 +0100 Subject: [PATCH] SGML#to_proc (#775) Experimenting with a `to_proc` interface on SGML components. --- lib/phlex/sgml.rb | 29 +++++++++-------------------- quickdraw/sgml/to_proc.test.rb | 29 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 20 deletions(-) create mode 100644 quickdraw/sgml/to_proc.test.rb diff --git a/lib/phlex/sgml.rb b/lib/phlex/sgml.rb index 3c4aad65..c4b0b7b7 100644 --- a/lib/phlex/sgml.rb +++ b/lib/phlex/sgml.rb @@ -84,6 +84,10 @@ def await(task) end end + def to_proc + proc { |c| c.render(self) } + end + # Renders the view and returns the buffer. The default buffer is a mutable String. def call(buffer = +"", context: Phlex::Context.new, view_context: nil, parent: nil, fragments: nil, &block) @_buffer = buffer @@ -243,9 +247,6 @@ def safe(value) alias_method :🦺, :safe - private - - # @api private def flush return if @_context.capturing @@ -254,23 +255,7 @@ def flush buffer.clear end - # Render another component, block or enumerable - # @return [nil] - # @overload render(component, &block) - # Renders the component. - # @param component [Phlex::SGML] - # @overload render(component_class, &block) - # Renders a new instance of the component class. This is useful for component classes that take no arguments. - # @param component_class [Class] - # @overload render(proc) - # Renders the proc with {#yield_content}. - # @param proc [Proc] - # @overload render(enumerable) - # Renders each item of the enumerable. - # @param enumerable [Enumerable] - # @example - # render @items - def render(renderable, &) + def render(renderable = nil, &) case renderable when Phlex::SGML renderable.call(@_buffer, context: @_context, view_context: @_view_context, parent: self, &) @@ -288,6 +273,8 @@ def render(renderable, &) end when String plain(renderable) + when nil + yield_content(&) if block_given? else raise Phlex::ArgumentError.new("You can't render a #{renderable.inspect}.") end @@ -295,6 +282,8 @@ def render(renderable, &) nil end + private + # Like {#capture} but the output is vanished into a BlackHole buffer. # Because the BlackHole does nothing with the output, this should be faster. # @return [nil] diff --git a/quickdraw/sgml/to_proc.test.rb b/quickdraw/sgml/to_proc.test.rb new file mode 100644 index 00000000..3f52b0f4 --- /dev/null +++ b/quickdraw/sgml/to_proc.test.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class App < Phlex::HTML + def view_template + render Example do |e| + e.slot(&Sub.new) + end + end +end + +class Example < Phlex::HTML + def view_template(&) + article(&) + end + + def slot(&) + render(&) + end +end + +class Sub < Phlex::HTML + def view_template + h1 { "Sub" } + end +end + +test do + expect(App.new.call) == "

Sub

" +end