Is it possible to pass a variable from component into a slot. Here is an example:
{{-- index.blade.php --}}
@component('slider', ['entities' => [0, 1, 2]])
@slot('title')
Slider title
@endslot
@slot('slide')
Slider content no {{ $entity }}
@endslot
@endcomponent
{{-- slider.blade.php --}}
<h1>{{ $title }}</h1>
<ul>
@foreach($entities as $entity)
<li>{{ $slide }}</li>
@endforeach
</ul>
Current result :
Exception : $entity is not defined
Expected result:
<h1>Slider title</h1>
<ul>
<li>Slider content no 0</li>
<li>Slider content no 1</li>
<li>Slider content no 2</li>
</ul>
We can try with different way. Here, how I executed.
{{-- index.blade.php --}}
@component('slider', ['entities' => [0, 1, 2]])
@slot('title')
Slider title
@endslot
@slot('slide')
Slider content no
@endslot
@endcomponent
{{-- slider.blade.php --}}
<h1>{{ $title }}</h1>
<ul>
@foreach($entities as $entity)
<li>{{ $slide }} {{ $entity }}</li>
@endforeach
</ul>
It seems that there is no way to pass data from a component to a slot context. It is also the case with @section
/@yield
.
What I've discovered is the @each
function. https://laravel.com/docs/5.6/blade#rendering-views-for-collections
You'd need to have another view partial for the list item content (called item
here).
{{-- index.blade.php --}}
@component('slider', ['entities' => [0, 1, 2], 'item_view' => 'item'])
@slot('title')
Slider title
@endslot
@endcomponent
{{-- item.blade.php --}}
<li>
Slider content no $entity
</li>
{{-- slider.blade.php --}}
<h1>{{ $title }}</h1>
<ul>
@each($item_view, $entities, 'entity')
</ul>
Example: making a new slider with different content:
{{-- gallery.blade.php --}}
@component('slider', ['entities' => ['a.png', 'b.png', 'c.png'], 'item_view' => 'gallery_item'])
@slot('title')
Gallery
@endslot
@endcomponent
{{-- gallery_item.blade.php --}}
<li>
<img src={{ $entity }} />
</li>
UPDATE: I created a package adding scoped slots feature to Blade. Your problem is a perfect use-case for the scoped slots and it can be easily resolved using them. Check it out.
I struggled with the same problem and finally I found a way to "pass" variables from component to slot. The trick is to use @verbatim
directive which makes blade code not compile. Therefore we're able to pass blade code to a slot and then compile it in our component. However there is only one condition -- the name of variable used in foreach
loop has to be the same as the one used in the slot. (As shown in the example below -- the slide
slot uses $entity
variable and so does the foreach
loop in the component)
index.blade.php
@component('slider', ['entities' => [0, 1, 2]])
@slot('title')
Slider title
@endslot
@slot('slide')
@verbatim
Slide {{ $entity }}
@if ($entity === 0) {{-- Directives also work! --}}
<strong>Special slide</strong>
@endif
@endverbatim
@endslot
@endcomponent
slider.blade.php
<h1>{{ $title }}</h1>
<ul>
@foreach($entities as $entity)
<li>{!! eval('?>'.Blade::compileString($slide)) !!}</li>
@endforeach
</ul>
It is a little "hacky" solution to the problem but most importantly it does the job as you can see on the screenshot below.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With