e_mwng's avatar

Is there a way to use @push and @yield for complex laravel blade layout?

Working with blade I have a layout and I have created a package that has several view blade components, this components are then render on the apps blade as follows.

layout > apps

 <head>
    @stack('css')
    @yield('styles')
    </head>
     <body>
     <main class="py-4">
        @yield('content')
        {{--Render package components--}}
        @includeIf('package::view-blade')
      </main>
         @yield('scripts')
      </body>

I am able to render scripts from the components as follows:

package > resources > components > view-blade

@section('scripts')
    @parent
    <script src="{{asset('path-to-scripts')}}"></script>
@endsection

But when I try the same for styles it does not work, i.e

@section('styles')
        @parent
        <link type="text/css" href="{{asset('path-to-styles')}}"/>
    @endsection

Or

@push('css')
<link type="text/css" href="{{asset('path-to-styles')}}"/>
@endpush

How can i render styles to the app.blade file dynamically from the package component file? to clarify I am not extending the app layout on the component

0 likes
5 replies
bobbybouwmann's avatar

What you're trying to achieve should be done with stacks since it's possible that you need to add multiple styles or scripts.

Documentation: https://laravel.com/docs/8.x/blade#stacks

Your component should extend the layout in some way to make this work. Can you show how a component looks like and uses the main layout?

e_mwng's avatar

@bobbybouwmann I am not extending the layout on the component. Does this mean that one has to have the layout extended for stacks to work ? if so maybe I can instead render the component from a welcome.blade file which then extends the layout?

newbie360's avatar

if i understand your question correctly, you don't want to use @push on every files ?

a simple example

<head>
    @stack('css')
    @stack('styles')
</head>
<body>
    @section('sidebar')
        <p>master sidebar</p>
    @show

    <main class="py-4">
        @yield('content')

        {{--Render package components--}}
        @includeIf('package::view-blade')
    </main>
</body>

a.blade.php, without the section

@extends('layouts.master')

result:
<p>master sidebar</p>

b.blade.php, use section to append extra sidebar

@extends('layouts.master')

@section('sidebar')
    <p>top sidebar</p>
    @parent
    <p>bottom sidebar</p>
@endsection

result:
<p>top sidebar</p>
<p>master sidebar</p>
<p>bottom sidebar</p>

c.blade.php, use section to overwrite

@extends('layouts.master')

@section('sidebar')
    //@parent
    <p>user sidebar</p>
@endsection

result:
<p>user sidebar</p>

@push can used anywhere to @stack

e_mwng's avatar

@newbie360 I realized that for @push to work the file has to use @extends. since I was rendering the component directly into the layout app.blade, this means it could not work. Essentially I was setting the file as

 <head>
    @stack('css')
    @yield('styles')
    </head>
     <body>
     <main class="py-4">
        @yield('content')
        {{--Render package components--}}
      @section('styles')
        @parent
        <link type="text/css" href="{{asset('path-to-styles')}}"/>
    @endsection
      </main>
         @yield('scripts')
      </body>

What I don;t get is why the scripts worked but not the styles.

Any way I was able to sort it by moving the code @includeIf('package::view-blade') to a separate welcome.blade file which extends the app layout.

newbie360's avatar

i think you can't do in this way, and @push , @stack is something like global, even in component, it is used by anywhere

if you have a default styles for ALL page, why don't just hardcoded

<head>
    @stack('css')
    <link type="text/css" href="{{asset('path-to-styles')}}"/>
    @stack('styles')
</head>

Please or to participate in this conversation.