Skip to content

Commit e8d2a45

Browse files
committed
initial pass at components and slots
1 parent bd14251 commit e8d2a45

2 files changed

Lines changed: 143 additions & 0 deletions

File tree

src/Illuminate/View/Compilers/BladeCompiler.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,50 @@ protected function compileIncludeIf($expression)
902902
return "<?php if (\$__env->exists($expression)) echo \$__env->make($expression, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
903903
}
904904

905+
/**
906+
* Compile the component statements into valid PHP.
907+
*
908+
* @param string $expression
909+
* @return string
910+
*/
911+
protected function compileComponent($expression)
912+
{
913+
return "<?php \$__env->startComponent{$expression}; ?>";
914+
}
915+
916+
/**
917+
* Compile the end component statements into valid PHP.
918+
*
919+
* @param string $expression
920+
* @return string
921+
*/
922+
protected function compileEndComponent($expression)
923+
{
924+
return "<?php echo \$__env->renderComponent(); ?>";
925+
}
926+
927+
/**
928+
* Compile the slot statements into valid PHP.
929+
*
930+
* @param string $expression
931+
* @return string
932+
*/
933+
protected function compileSlot($expression)
934+
{
935+
return "<?php \$__env->slot{$expression}; ?>";
936+
}
937+
938+
/**
939+
* Compile the end slot statements into valid PHP.
940+
*
941+
* @param string $expression
942+
* @return string
943+
*/
944+
protected function compileEndSlot($expression)
945+
{
946+
return "<?php \$__env->endSlot(); ?>";
947+
}
948+
905949
/**
906950
* Compile the stack statements into the content.
907951
*

src/Illuminate/View/Factory.php

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Illuminate\Support\Arr;
88
use Illuminate\Support\Str;
99
use InvalidArgumentException;
10+
use Illuminate\Support\HtmlString;
1011
use Illuminate\Contracts\Support\Arrayable;
1112
use Illuminate\View\Engines\EngineResolver;
1213
use Illuminate\Contracts\Events\Dispatcher;
@@ -93,6 +94,34 @@ class Factory implements FactoryContract
9394
*/
9495
protected $sectionStack = [];
9596

97+
/**
98+
* The components being rendered.
99+
*
100+
* @var array
101+
*/
102+
protected $componentStack = [];
103+
104+
/**
105+
* The original data passed to the component.
106+
*
107+
* @var array
108+
*/
109+
protected $componentData = [];
110+
111+
/**
112+
* The slot contents for the component.
113+
*
114+
* @var array
115+
*/
116+
protected $slots = [];
117+
118+
/**
119+
* The names of the slots being rendered.
120+
*
121+
* @var array
122+
*/
123+
protected $slotStack = [];
124+
96125
/**
97126
* The stack of in-progress loops.
98127
*
@@ -680,6 +709,75 @@ public static function parentPlaceholder()
680709
return static::$parentPlaceholder;
681710
}
682711

712+
/**
713+
* Start a component rendering process.
714+
*
715+
* @param string $name
716+
* @param array $data
717+
* @return void
718+
*/
719+
public function startComponent($name, array $data = [])
720+
{
721+
if (ob_start()) {
722+
$this->componentStack[] = $name;
723+
724+
$this->componentData[$name] = $data;
725+
726+
$this->slots[$name] = [];
727+
}
728+
}
729+
730+
/**
731+
* Render the current component.
732+
*
733+
* @return string
734+
*/
735+
public function renderComponent()
736+
{
737+
$contents = ob_get_clean();
738+
739+
$name = array_pop($this->componentStack);
740+
741+
$baseData = $this->componentData[$name];
742+
743+
$data = array_merge(
744+
$baseData, ['slot' => new HtmlString($contents)], $this->slots[$name]
745+
);
746+
747+
return tap($this->make($name, $data)->render(), function () use ($name) {
748+
unset($this->slots[$name]);
749+
unset($this->slotStack[$name]);
750+
unset($this->componentData[$name]);
751+
});
752+
}
753+
754+
/**
755+
* Start the slot rendering process.
756+
*
757+
* @param string $name
758+
* @return void
759+
*/
760+
public function slot($name)
761+
{
762+
if (ob_start()) {
763+
$this->slots[last($this->componentStack)][$name] = '';
764+
765+
$this->slotStack[last($this->componentStack)][] = $name;
766+
}
767+
}
768+
769+
/**
770+
* Save the slot content for rendering.
771+
*
772+
* @return void
773+
*/
774+
public function endSlot()
775+
{
776+
$current = last($this->componentStack);
777+
778+
$this->slots[$current][array_pop($this->slotStack[$current])] = new HtmlString(ob_get_clean());
779+
}
780+
683781
/**
684782
* Start injecting content into a push section.
685783
*
@@ -729,6 +827,7 @@ protected function extendPush($section, $content)
729827
if (! isset($this->pushes[$section])) {
730828
$this->pushes[$section] = [];
731829
}
830+
732831
if (! isset($this->pushes[$section][$this->renderCount])) {
733832
$this->pushes[$section][$this->renderCount] = $content;
734833
} else {

0 commit comments

Comments
 (0)