From bfde458766c333284565cb47164b44912eea2006 Mon Sep 17 00:00:00 2001 From: Bastian Allgeier Date: Tue, 17 Jan 2023 13:29:37 +0100 Subject: [PATCH 1/2] Add unit test for self-closing snippet with multiple slots --- src/Template/Slots.php | 12 ++++++++++- src/Template/Template.php | 15 +++++++++---- tests/Template/SlotsTest.php | 1 + tests/Template/SnippetTest.php | 21 +++++++++++++++++++ .../fixtures/layout-with-multiple-slots.php | 3 +++ 5 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 tests/Template/fixtures/layout-with-multiple-slots.php diff --git a/src/Template/Slots.php b/src/Template/Slots.php index e1e6991ddc..77bc148056 100644 --- a/src/Template/Slots.php +++ b/src/Template/Slots.php @@ -2,6 +2,8 @@ namespace Kirby\Template; +use Countable; + /** * The slots collection is simplifying * slot access. Slots can be accessed with @@ -14,7 +16,7 @@ * @copyright Bastian Allgeier * @license https://getkirby.com/license */ -class Slots +class Slots implements Countable { /** * Creates a new slots collection @@ -40,4 +42,12 @@ public function __call(string $name, array $args): Slot|null { return $this->__get($name); } + + /** + * Counts the number of defined slots + */ + public function count(): int + { + return count($this->slots); + } } diff --git a/src/Template/Template.php b/src/Template/Template.php index 3e083a329a..aac4c990ef 100644 --- a/src/Template/Template.php +++ b/src/Template/Template.php @@ -163,15 +163,22 @@ public function render(array $data = []): string // take the buffer output from the template as default slot // and render the snippet as final template output if ( - Snippet::$current !== null && - Snippet::$current->parent() === $snippet + Snippet::$current === null || + Snippet::$current->parent() !== $snippet ) { - $template = Snippet::$current->render($data, [ + return $template; + } + + // no slots have been defined, but the template code + // should be used as default slot + if (count(Snippet::$current->slots()) === 0) { + return Snippet::$current->render($data, [ 'default' => $template ]); } - return $template; + // let the snippet close and render natively + return Snippet::$current->render($data); } /** diff --git a/tests/Template/SlotsTest.php b/tests/Template/SlotsTest.php index a4d5c32695..1798c5da0a 100644 --- a/tests/Template/SlotsTest.php +++ b/tests/Template/SlotsTest.php @@ -25,5 +25,6 @@ public function testSlots() $this->assertSame($header, $slots->header()); $this->assertSame($footer, $slots->footer); $this->assertSame($footer, $slots->footer()); + $this->assertCount(2, $slots); } } diff --git a/tests/Template/SnippetTest.php b/tests/Template/SnippetTest.php index 956388399f..d627b31b04 100644 --- a/tests/Template/SnippetTest.php +++ b/tests/Template/SnippetTest.php @@ -223,6 +223,27 @@ public function testRenderWithoutClosing() $this->assertSame("

Layout

\ncontent\n", $snippet->render()); } + /** + * @covers ::render + */ + public function testRenderWithoutClosingAndMultipleSlots() + { + // all output must be captured + $this->expectOutputString(''); + + $snippet = new Snippet(__DIR__ . '/fixtures/layout-with-multiple-slots.php'); + + $snippet->slot('header'); + echo 'Header content'; + $snippet->endslot(); + + $snippet->slot(); + echo 'Body content'; + $snippet->endslot(); + + $this->assertSame("

Layout

\n
Header content
\n
Body content
\n", $snippet->render()); + } + /** * @covers ::render */ diff --git a/tests/Template/fixtures/layout-with-multiple-slots.php b/tests/Template/fixtures/layout-with-multiple-slots.php new file mode 100644 index 0000000000..5591e54de2 --- /dev/null +++ b/tests/Template/fixtures/layout-with-multiple-slots.php @@ -0,0 +1,3 @@ +

Layout

+
header() ?>
+
From ff90e6cbe9112e9ffb85ace64c3e276682ec8b17 Mon Sep 17 00:00:00 2001 From: Bastian Allgeier Date: Tue, 17 Jan 2023 13:40:11 +0100 Subject: [PATCH 2/2] Simplify counting slots Co-authored-by: Ahmet Bora --- src/Template/Template.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Template/Template.php b/src/Template/Template.php index aac4c990ef..a366ad8850 100644 --- a/src/Template/Template.php +++ b/src/Template/Template.php @@ -171,7 +171,7 @@ public function render(array $data = []): string // no slots have been defined, but the template code // should be used as default slot - if (count(Snippet::$current->slots()) === 0) { + if (Snippet::$current->slots()->count() === 0) { return Snippet::$current->render($data, [ 'default' => $template ]);