Skip to content

Commit

Permalink
Add render_1 and render_2 rendering methods
Browse files Browse the repository at this point in the history
  • Loading branch information
bradgessler committed Feb 8, 2024
1 parent 69c64f8 commit c9e0951
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 50 deletions.
80 changes: 62 additions & 18 deletions lib/phlex/rails/sgml/overrides.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,68 @@ module Phlex
module Rails
module SGML
module Overrides
def self.prepended(klass)
klass.alias_method :super_render, :render
klass.include RenderMethods
klass.extend ClassMethods
# Set the version to 1 by default.
klass.version 1
end

module RenderMethods
def render_1(*args, **kwargs, &block)
renderable = args[0]

warn "Phlex 2.0 will render #{renderable} using render_2" if renderable.is_a?(String)

case renderable
when Phlex::SGML, Proc
return super_render(*args, **kwargs, &block)
when Class
return super_render(*args, **kwargs, &block) if renderable < Phlex::SGML
when Enumerable
return super_render(*args, **kwargs, &block) unless renderable.is_a?(ActiveRecord::Relation)
else
captured_block = -> { capture(&block) } if block
@_context.target << @_view_context.render(*args, **kwargs, &captured_block)
end

nil
end

def render_2(*args, **kwargs, &block)
renderable = args[0]

case renderable
when Phlex::SGML, Proc, String
return super_render(*args, **kwargs, &block)
when Class
return super_render(*args, **kwargs, &block) if renderable < Phlex::SGML
when Enumerable
return super_render(*args, **kwargs, &block) unless renderable.is_a?(ActiveRecord::Relation)
else
captured_block = -> { capture(&block) } if block
@_context.target << @_view_context.render(*args, **kwargs, &captured_block)
end

nil
end
end

module ClassMethods
# Class method to switch render method implementations
def version(version)
case version
when 1
alias_method :render, :render_1
when 2
alias_method :render, :render_2
else
raise ArgumentError, "Unknown render method version: #{version}"
end
end
end

def helpers
if defined?(ViewComponent::Base) && @_view_context.is_a?(ViewComponent::Base)
@_view_context.helpers
Expand All @@ -12,24 +74,6 @@ def helpers
end
end

def render(*args, **kwargs, &block)
renderable = args[0]

case renderable
when Phlex::SGML, Proc
return super
when Class
return super if renderable < Phlex::SGML
when Enumerable
return super unless renderable.is_a?(ActiveRecord::Relation)
else
captured_block = -> { capture(&block) } if block
@_context.target << @_view_context.render(*args, **kwargs, &captured_block)
end

nil
end

def render_in(view_context, &block)
if block_given?
call(view_context: view_context) do |*args|
Expand Down
138 changes: 106 additions & 32 deletions spec/phlex/sgml_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,123 @@
require "spec_helper"

RSpec.describe Phlex::SGML do
describe "#render" do
context "when given a block" do
it "renders content in the proper order" do
context "1.0" do
describe "#render" do
context "when given a block" do
it "renders content in the proper order" do
component = Class.new(Phlex::HTML) do
def template(&block)
plain "Component A\n"
render("examples/sgml/wrap", &block)
plain "Component B\n"
end
end

content = ExamplesController.render(inline: <<~ERB, locals: { component: component })
ERB A
<%= render component.new do %>
Hello
<% end %>
ERB B
ERB

expect(content).to eq(<<~OUTPUT)
ERB A
Component A
Partial A
Hello
Partial B
Component B
ERB B
OUTPUT
end
end

it "renders a template without a block" do
component = Class.new(Phlex::HTML) do
def template(&block)
plain "Component A\n"
render("examples/sgml/wrap", &block)
plain "Component B\n"
def template
render(template: "examples/sgml/template")
end
end

content = ExamplesController.render(inline: <<~ERB, locals: { component: component })
ERB A
<%= render component.new do %>
Hello
<% end %>
ERB B
ERB

expect(content).to eq(<<~OUTPUT)
ERB A
Component A
Partial A
Hello
Partial B
Component B
ERB B
OUTPUT
content = ExamplesController.render(component)

expect(content).to eq("Plain template.")
end

it "does not render a string" do
component = Class.new(Phlex::HTML) do
def template
render("Plain string.")
end
end

expect{ExamplesController.render(component)}.to raise_error(ActionView::MissingTemplate)
end
end
end

it "renders a template without a block" do
component = Class.new(Phlex::HTML) do
def template
render(template: "examples/sgml/template")
context "2.0" do
before { Phlex::SGML.version(2) }
after { Phlex::SGML.version(1) }
describe "#render" do
context "when given a block" do
it "renders content in the proper order" do
component = Class.new(Phlex::HTML) do
def template(&block)
plain "Component A\n"
render(partial: "examples/sgml/wrap", &block)
plain "Component B\n"
end
end

content = ExamplesController.render(inline: <<~ERB, locals: { component: component })
ERB A
<%= render component.new do %>
Hello
<% end %>
ERB B
ERB

expect(content).to eq(<<~OUTPUT)
ERB A
Component A
Partial A
Hello
Partial B
Component B
ERB B
OUTPUT
end
end

it "renders a template without a block" do
component = Class.new(Phlex::HTML) do
def template
render(template: "examples/sgml/template")
end
end

content = ExamplesController.render(component)

expect(content).to eq("Plain template.")
end

content = ExamplesController.render(component)
it "renders a string" do
component = Class.new(Phlex::HTML) do
def template
render("Plain string.")
end
end

content = ExamplesController.render(component)

expect(content).to eq("Plain template.")
expect(content).to eq("Plain string.")
end
end
end
end

0 comments on commit c9e0951

Please sign in to comment.