4

In old-style Laravel blade templated we used to use @section('section-name') in the following way:

{{-- h1para.blade.php --}}
<h1>
    @section('heading')
        Heading from Template
    @endsection
</h1>
<p>
    @yield('details')
</p>

And then extend that template with:

{{-- content.blade.php --}}
@extends('h1para')

@section('details')
    Content from content page
@endsection

In the above, my rendered HTML output would look like the following, because the "missing" 'heading' section in the extending file means that we default back to the content in the template:

<h1>Heading from Template</h1>
<p>Content from content page</p>

But in the new components way of doing things, I do:

{{-- .../components/h1para.blade.php --}}
<h1>{{ $heading }}</h1>
<p>{{ $slot }}</p>

In case you haven't gathered, the question is: how do I set a default value for a slot's contents, such that if it isn't supplied in the extending component/template, it falls back to that default?

(I've done my searches, but haven't been able to find the same question asked before)


EDIT:

I should add that I've seen the solution (in the Laravel documentation):

<h1>{{ $heading ?? 'Default Heading Here' }}</h1>

But this seems only to be appropriate if the default value is a short easy to manage string. If the default is a long stream of HTML, then it wouldn't work for my needs.


EDIT 2:

Just to reiterate: the whole point of the question is that the default content could be a long stream of HTML. Solving the problem by passing in a string (be that formatted as HTML or not) wouldn't work for my real-world needs.

matiaslauriti
  • 7,065
  • 4
  • 31
  • 43
cartbeforehorse
  • 3,045
  • 1
  • 34
  • 49

2 Answers2

3

I think the solution is this:

{{-- .../component/template.blade.php --}}
<div>
    @if (isset($heading))
        {{ $heading }}
    @else
        <h1>Default Heading<span class="subhead">default subheadin and lots of other html content</span></h1>
    @endif
    <p>{{ $slot }}</p>
</div>

It's not super elegant, but I think it's the only solution. Anyone else have a better answer, I'd love to hear it.

cartbeforehorse
  • 3,045
  • 1
  • 34
  • 49
-1

If you pass data like:

<x-h1para header="<span>Header content</span>">
   <div>Default slot content here</div>
</x-h1para>

You can display in your component like:

 <div>
    <h1>{!! $heading ?? 'Default Heading Here' !!}</h1>
     {{ $slot }}
 </div>
  • Please see EDIT in the original question (which I think existed before you posted your answer). I don't want to pass long streams of HTML content via strings. That is exactly what I'm trying to avoid. – cartbeforehorse Aug 09 '21 at 19:52