RobinRadic / blade-extensions

Laravel Blade extensions like $loop->odd/$loop->index in foreach, view blocks and partials, etc
http://robin.radic.nl/blade-extensions
MIT License
267 stars 35 forks source link

BLADE-60 ⁃ @push to parent extends inside @embed #57

Closed vabatta closed 8 years ago

vabatta commented 8 years ago

Hi,

would be great to be able to @push something from the @embed directive to the parent. Example: component.blade.php

@yield('content')
@push('js')
  <script>alert('pushed 1!');</script>
  @stack('js')
@endpush

layout.blade.php

@yield('content')
@stack('js')

page.blade.php

@extends('layout')
@section('content')
  @embed('component')
    Should push two scripts!
    @push('js')
      <script>alert('pushed 2!');</script>
    @endpush
  @endembed
@endsection
RobinRadic commented 8 years ago

this will never be possible.

the embed directive has been created in such a way that it does not share the environment. This is done on purpose. This way its possible to create sections with the same name and provides other functionality that i dont know out of the top of my head.

vabatta commented 8 years ago

You actually don't share anything with the environment. @push if used inside the component itself, actually push the content to the parent, while using it inside @embed push to the component. I don't see a break on the concept, or am I wrong?

See edited https://github.com/RobinRadic/blade-extensions/issues/57#issue-165743835

RobinRadic commented 8 years ago

it would break:

component

@yield('content')
@stack('js')

view

@embed('component')
   @section('content')
   @show
   @push('js')
   @endpush
@endembed

// somehwere else 
@stack('js')
vabatta commented 8 years ago

@RobinRadic It's different from what I mean; the way you used the @push would actually break the directive, but if you look at https://github.com/RobinRadic/blade-extensions/issues/57#issue-165743835 you could see that it won't break. This way would be useful to develop a modular component which could have scripts included to the parent stack, for example to the bottom of the page (as recommended in yahoo dev).

But actually it would push something from the component to the parent which could be messy or chaotic.

RobinRadic commented 8 years ago

if id implemented that, everyone using the way i mentioned will be forced to change their code. so it breaks backward compatibility.

use

view()->getFactory()->startPush('js')

alternatively, make a custom directive @parentpush or something.

vabatta commented 8 years ago

I've created the @parentpush and @endparentpush directives this way: AppServiceProvider.php

Blade::directive('parentpush', function($expression) {
  return '<?php view()->startPush(' . $expression . '); ?>';
});

Blade::directive('endparentpush', function() {
  return '<?php view()->stopPush(); ?>';
});

And used this way: component.blade.php

@yield('content')
@parentpush('js')
  <script>alert('pushed 1!');</script>
  @stack('js')
@endparentpush

layout.blade.php

@yield('content')
@stack('js')

page.blade.php

@extends('layout')
@section('content')
  @embed('component')
    Should push two scripts!
    @push('js')
      <script>alert('pushed 2!');</script>
    @endpush
  @endembed
@endsection

Got perfectly working!

RobinRadic commented 8 years ago

:+1: glad you got it working