10 Direttive @component @slot @include

I componenti e gli slot sono stati introdotti a partire dalla versione 5 di laravel, diciamo che eseguono la stessa funzione delle sezioni, ma risultano maggiormente comodi e versatili rispetto alle @section.

Vediamo subito l’utilizzo supponendo di avere un codice da passare nelle varie pagine, prendiamo per esempio il componente card da bootstrap

<div class="card" style="width: 18rem;"> 
 <img class="card-img-top" src="..." alt="Card image cap">
 <div class="card-body"> 
  <h5 class="card-title">Card title</h5>
  <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
  <a href="#" class="btn btn-primary">Go somewhere</a>
 </div>
</div>

inseriamo il codice dentro ad un nuovo file resources/views/components/card.blade.php e andiamo a sostituire il testo statico e i riferimenti con i segnaposti in stile blade {{ }}

<div class="card" style="width: 18rem;">
 <img class="card-img-top" src="{{$img_url}}" alt="{{$img_title}}">
 <div class="card-body">
 <h5 class="card-title">{{$img_title}}</h5>

 </div>
</div>

il resto del contenuto che abbiamo eliminato lo facciamo caricare dai componenti esterni tramite la direttiva {{$slot}} che sta ad indicare che qualunque altro dati che non siano le variabili indicate mettimenlo in questo punto

<div class="card" style="width: 18rem;">
 <img class="card-img-top" src="{{$img_url}}" alt="{{$img_title}}">
 <div class="card-body">
  <h5 class="card-title">{{$img_title}}</h5>
  {{$slot}}
 </div>
</div>

a questo punto trasformiamo la nostra pagina blog.php in blog.blade.php

@extends('templates.layout')
@section('title','Blog')
@section('content')
 <h1>Blog</h1>

@endsection

@section('footer')
 @parent
@endsection

adesso definiamo l’inizio del nostro component dichiarando dichiarando il nome come parametro, ovvero quale caricare @component(‘cartella.nome’) e la fine con @endcomponent

@section('content')
 <h1>Blog</h1>

@component('components.card')

@endcomponent

@endsection

passare le variabili

abbiamo 2 modi per passare le variabili dichiarate nel componente

tramite array

diamo come secondo parametro di @component l’array che specifica le variabili

@component('components.card',
 [
  'img_title' => 'Immagine blog',
  'img_url' => 'http://lorempixel.com/400/200'
 ]
)
@endcomponent

adesso l’elemento card è stato facilmente caricato nella nostra pagina http://localhost:8000/pages/blog.

Per il contenuto testuale della card, potevamo inserirlo col segnaposto e le variabili, oppure come in questo caso possiamo inserirlo nel corpo del component e verrà catturato automaticamente da @slot

@component('components.card',
 [
  'img_title' => 'Immagine blog',
  'img_url' => 'http://lorempixel.com/400/200'
 ]
)
<p>Guardate che bella immagine</p>
@endcomponent

il <p> verrà passato a @slot e qualsiasi altro codice inseriamo

tramite @slot

è sufficente mettere all’interno del @component la direttiva @slot che acceterà come primo parametro il nome della variabile da passare e come secondo il suo valore

@component('components.card')
 @slot('img_title','Immagine2 blog')
 @slot('img_url','http://lorempixel.com/400/200')
 <p>Guardate che altra bella immagine</p>
@endcomponent

I 2 metodi per passare i dai ai componenti producono lo stesso risultato, il metodo tramite array risulta più ordinato quando si devono passare numerose variabili, il metodo @slot quando ce ne sono poche.

I componenti risultano molto più comodi da usare rispetto alle @section.

@include

Vediamo ora come includere parti di codice da un template a una pagina tramite @include.

Lavoriamo sempre sul nostro esempio card aggiungendo l’ @include(‘components.card’)

@include('components.card')

a questo punto possiamo far iniettare le variabili dal nostro controller PageController nella funzione blog(), inseriamo l’array con i dati come secondo parametro della view()

public function blog() {
 return view('blog',
  [
  'img_title' => 'Immagine blog inclusa',
  'img_url' => 'http://lorempixel.com/400/200'
  ]
 );
}

a questo punto otterremo un errore, perchè nella card abbiamo dichiarato la variabile generica $slot che va bene solo per @component. Dobbiamo quindi aggiungere nell’array del controller una variabile slot, anche vuota.

Possiamo anche passare l’array di dati direttamente come secondo parametro dell’@include sempre specificando la variabile $slot

@include('components.card',
 [
  'img_title' => 'Immagine blog inclusa',
  'img_url' => 'http://lorempixel.com/400/200',
  'slot' => ''
 ]
)

La differenza tra passarle nel controller e passarle nell’include della pagina sta nel fatto che nel primo caso esistono globalmente per tutte le pagine.

L’utilizzo dell’include comunque è sconsigliato perchè il @component è più versatile e flessibile permettendo di iniettare codice