diff --git a/spec/blueprint/html/enveloping_spec.cr b/spec/blueprint/html/enveloping_spec.cr deleted file mode 100644 index ad7af25..0000000 --- a/spec/blueprint/html/enveloping_spec.cr +++ /dev/null @@ -1,63 +0,0 @@ -require "../../spec_helper" - -private class MainLayout - include Blueprint::HTML - - private def blueprint(&) - html do - body do - yield - end - end - end -end - -private class BasePage - include Blueprint::HTML - - private def envelope(&) - render(MainLayout.new) do - yield - end - end -end - -private class Component - include Blueprint::HTML - - def blueprint - h1 "Hello World!" - end - - def envelope(&) - div class: "title" do - yield - end - end -end - -private class IndexPage < BasePage - private def blueprint - h1 "Home" - render Component.new - end -end - -describe "enveloping" do - it "allows defining a blueprint wrapper" do - page = IndexPage.new - expected_html = normalize_html <<-HTML - - -

Home

- -
-

Hello World!

-
- - - HTML - - page.to_s.should eq expected_html - end -end diff --git a/spec/blueprint/html/hooks_spec.cr b/spec/blueprint/html/hooks_spec.cr new file mode 100644 index 0000000..758af2e --- /dev/null +++ b/spec/blueprint/html/hooks_spec.cr @@ -0,0 +1,77 @@ +require "../../spec_helper" + +private class ExampleWithBlock + include Blueprint::HTML + + private def blueprint(&) + h1 { yield } + end + + private def before_render(&) + span { "Before render" } + end + + private def around_render(&) + span { "Around start" } + yield + span { "Around end" } + end + + private def after_render(&) + span { "After render" } + end +end + +private class ExampleWithoutBlock + include Blueprint::HTML + + private def blueprint + h1 "Without block" + end + + private def before_render(&) + span { "Before render" } + end + + private def around_render(&) + span { "Around start" } + yield + span { "Around end" } + end + + private def after_render(&) + span { "After render" } + end +end + +describe "hooks" do + context "with block" do + it "allows defining hooks before_render, around_render, after_render" do + actual_html = ExampleWithBlock.new.to_s { "With block" } + expected_html = normalize_html <<-HTML + Before render + Around start +

With block

+ Around end + After render + HTML + + actual_html.should eq expected_html + end + end + + context "without block" do + it "allows defining hooks before_render, around_render, after_render" do + actual_html = ExampleWithoutBlock.new.to_s + expected_html = normalize_html <<-HTML + Before render + Around start +

Without block

+ Around end + After render + HTML + + actual_html.should eq expected_html + end + end +end diff --git a/src/blueprint/html.cr b/src/blueprint/html.cr index 2246485..12dd753 100644 --- a/src/blueprint/html.cr +++ b/src/blueprint/html.cr @@ -39,7 +39,19 @@ module Blueprint::HTML @buffer = buffer - envelope { blueprint } + {% if @type.has_method?(:before_render) %} + before_render { } + {% end %} + + {% if @type.has_method?(:around_render) %} + around_render { blueprint } + {% else %} + blueprint + {% end %} + + {% if @type.has_method?(:after_render) %} + after_render { } + {% end %} end def to_s(buffer : String::Builder, &) : Nil @@ -47,16 +59,24 @@ module Blueprint::HTML @buffer = buffer - envelope do + {% if @type.has_method?(:before_render) %} + before_render { yield } + {% end %} + + {% if @type.has_method?(:around_render) %} + around_render do + blueprint { capture_content { yield } } + end + {% else %} blueprint { capture_content { yield } } - end + {% end %} + + {% if @type.has_method?(:after_render) %} + after_render { yield } + {% end %} end private def render? : Bool true end - - private def envelope(&) : Nil - yield - end end