Skip to content

Commit de6b106

Browse files
authored
[7.x] Once Blocks (#33812)
Once blocks for Blade.
1 parent 78afbcb commit de6b106

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

src/Illuminate/View/Compilers/Concerns/CompilesConditionals.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Illuminate\View\Compilers\Concerns;
44

5+
use Illuminate\Support\Str;
6+
57
trait CompilesConditionals
68
{
79
/**
@@ -279,4 +281,26 @@ protected function compileEndSwitch()
279281
{
280282
return '<?php endswitch; ?>';
281283
}
284+
285+
/**
286+
* Compile an once block into valid PHP.
287+
*
288+
* @return string
289+
*/
290+
protected function compileOnce($id = null)
291+
{
292+
$id = $id ? $this->stripParentheses($id) : "'".(string) Str::uuid()."'";
293+
294+
return '<?php if (! $__env->hasRenderedOnce('.$id.')): $__env->markAsRenderedOnce('.$id.'); ?>';
295+
}
296+
297+
/**
298+
* Compile an end-once block into valid PHP.
299+
*
300+
* @return string
301+
*/
302+
public function compileEndOnce()
303+
{
304+
return '<?php endif; ?>';
305+
}
282306
}

src/Illuminate/View/Factory.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,13 @@ class Factory implements FactoryContract
8383
*/
8484
protected $renderCount = 0;
8585

86+
/**
87+
* The "once" block IDs that have been rendered.
88+
*
89+
* @var array
90+
*/
91+
protected $renderedOnce = [];
92+
8693
/**
8794
* Create a new view factory instance.
8895
*
@@ -352,6 +359,28 @@ public function doneRendering()
352359
return $this->renderCount == 0;
353360
}
354361

362+
/**
363+
* Determine if the given once token has been rendered.
364+
*
365+
* @param string $id
366+
* @return bool
367+
*/
368+
public function hasRenderedOnce(string $id)
369+
{
370+
return isset($this->renderedOnce[$id]);
371+
}
372+
373+
/**
374+
* Mark the given once token as having been rendered.
375+
*
376+
* @param string $id
377+
* @return void
378+
*/
379+
public function markAsRenderedOnce(string $id)
380+
{
381+
$this->renderedOnce[$id] = true;
382+
}
383+
355384
/**
356385
* Add a location to the array of view locations.
357386
*
@@ -434,6 +463,7 @@ public function addExtension($extension, $engine, $resolver = null)
434463
public function flushState()
435464
{
436465
$this->renderCount = 0;
466+
$this->renderedOnce = [];
437467

438468
$this->flushSections();
439469
$this->flushStacks();

tests/View/ViewFactoryTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,16 @@ public function testExistsPassesAndFailsViews()
5959
$this->assertTrue($factory->exists('bar'));
6060
}
6161

62+
public function testRenderingOnceChecks()
63+
{
64+
$factory = $this->getFactory();
65+
$this->assertFalse($factory->hasRenderedOnce('foo'));
66+
$factory->markAsRenderedOnce('foo');
67+
$this->assertTrue($factory->hasRenderedOnce('foo'));
68+
$factory->flushState();
69+
$this->assertFalse($factory->hasRenderedOnce('foo'));
70+
}
71+
6272
public function testFirstCreatesNewViewInstanceWithProperPath()
6373
{
6474
unset($_SERVER['__test.view']);

0 commit comments

Comments
 (0)