2016-07-01 9 views
8

próbuję utworzyć widget HTML z laravel ostrze podobny do poniższego (widget.blade.php):Jak mieć pchnięcie jednorazowym ostrzem laravel

@push('scripts') 
    <script src="{{ asset('js/foo.js') }}"></script> 
    <script> 
    ... 
    </script> 
@endpush 
@push('styles') 
    <link href="{{ asset('css/bar.css') }}" rel="stylesheet"> 
@endpush 
<div> 
... HTML contents 
</div> 

i używam widżet w sposób drugie ostrze jak:

<div> 
    ... 
    @include('widget') 
</div> 
<div> 
    ... 
    @include('widget') 
</div> 

problemem jest to, kiedy korzystać z widgetów wielokrotnie w stronę „skrypty” i powtarzane wiele razy „style”.

Jak mogę zapobiec wielokrotnemu przesyłaniu skryptów i stylów przez Laravel?

+0

użyć '@ yield' i' @ Sekcją – aldrin27

+0

@ aldrin27 Mógłbyś rozwinąć bardziej lub zrobić mi przykład proszę? UWAGA: "skrypty" i "style" były używane z innymi ostrzami, nawet ostrza zawierające widżet –

+0

. Na podstawie mojego zrozumienia, chcesz uwzględnić pliki skryptów i spersonalizowany widget we wszystkich ostrzach? Czy to jest poprawne? – aldrin27

Odpowiedz

7

W poniższej odpowiedzi Zakładałem, że znasz Blade extension. Ta metoda została przetestowana na Laravel 5.2 i 5.3 (patrz uwaga poniżej).

Po przetestowaniu Ismail RBOUH's Answer (więc proszę ją przeczytać) Wygląda na to, istnieją dwa problemy z rozwiązania:

1- Zmienna $ isDisplayed nie jest w takim samym zakresie z drugiej strony zawarte widgety więc każdy @include naciśnięciem jego skrypty do stosu. W rezultacie zmieniam go na:

Blade::directive('pushonce', function ($expression) { 
    $isDisplayed = '__pushonce_'.trim(substr($expression, 2, -2)); 
    return "<?php if(!isset(\$__env->{$isDisplayed})): \$__env->{$isDisplayed} = true; \$__env->startPush{$expression}; ?>"; 
}); 
Blade::directive('endpushonce', function ($expression) { 
    return '<?php $__env->stopPush(); endif; ?>'; 
}); 

2- Rozwiązanie ogranicza korzystanie z @pushonce do jednego widgetu. tj. w przypadku 2 lub większej liczby widżetów (widget1.blade.php, widget2.blade.php, ...) uniemożliwia to wypychanie innych skryptów widżetów. Więc dodać domenę do @pushonce z następującego kodu:

Blade::directive('pushonce', function ($expression) { 
    $domain = explode(':', trim(substr($expression, 2, -2))); 
    $push_name = $domain[0]; 
    $push_sub = $domain[1]; 
    $isDisplayed = '__pushonce_'.$push_name.'_'.$push_sub; 
    return "<?php if(!isset(\$__env->{$isDisplayed})): \$__env->{$isDisplayed} = true; \$__env->startPush('{$push_name}'); ?>"; 
}); 
Blade::directive('endpushonce', function ($expression) { 
    return '<?php $__env->stopPush(); endif; ?>'; 
}); 

Zastosowanie:

widget1.blade.php

@pushonce('scripts:widget1') 
    <script src="{{ asset('js/foo.js') }}"></script> 
    <script> 
    ... 
    </script> 
@endpushonce 

widget2.blade.php

@pushonce('scripts:widget2') 
    <script src="{{ asset('js/bar.js') }}"></script> 
    <script> 
    ... 
    </script> 
@endpushonce 

UWAGA DLA L 5.3: zmiana następujący wiersz:

$domain = explode(':', trim(substr($expression, 2, -2))); 

do

$domain = explode(':', trim(substr($expression, 1, -1))); 
+1

Lepiej jest skopiować kod dyrektywy '@ endpushonce' do swojej odpowiedzi. W przeciwnym razie jest to nieco mylące. – mixel

+0

@mixel masz rację. Edytuję odpowiedź. –

3

Jednym z rozwiązań jest rozszerzenie Ostrze tworząc dyrektywy pushonce następująco:

Blade::directive('pushonce', function ($expression) { 

    $isDisplayed = '$__pushonce_'.trim(substr($expression, 2, -2)); 

    return "<?php if(!isset({$isDisplayed})): {$isDisplayed} = true; \$__env->startPush{$expression}; ?>"; 
}); 

Blade::directive('endpushonce', function ($expression) { 

    return '<?php $__env->stopPush(); endif; ?>'; 
}); 

Należy dodać do AppServiceProviderboot metody.

Zastosowanie:

@pushonce('scripts') 
    <script src="{{ asset('js/foo.js') }}"></script> 
    <script> 
    ... 
    </script> 
@endpushonce 

@pushonce('styles') 
    <script src="{{ asset('js/foo.js') }}"></script> 
    <script> 
    ... 
    </script> 
@endpushonce 

proszę przetestować go i daj mi znać, jeśli to pomaga.

+0

Dzięki. Rozwiązanie jest ** częściowo poprawne **. Prawidłowy jest zbyt długi, a Stackoverflow nie pozwala mi tego komentować. Więc dodałem to jako nową odpowiedź. –

+0

Okey. Powodzenia;) –

-1

Zmieniłem kod nieco:

Blade::directive('pushonce', function ($expression) { 
    $var = '$__env->{"__pushonce_" . md5(__FILE__ . ":" . __LINE__)}'; 

    return "<?php if(!isset({$var})): {$var} = true; \$__env->startPush({$expression}); ?>"; 
}); 

Blade::directive('endpushonce', function ($expression) { 
    return '<?php $__env->stopPush(); endif; ?>'; 
}); 

Używam pliku i numer linii, aby ustawić zmienna, więc może po prostu zrobić:

@pushonce('scripts') 
    Whatever 
@endpushonce 

Zamiast:

@pushonce('scripts:widget1') 
    Whatever 
@endpushonce 
Powiązane problemy