Indice
Extends
Questa direttiva serve all’interno di una view per includere un layout; la direttiva riportata sotto indica alla view di includere il file resources\views\templates\layout.blade.php e riporta solo il percorso finale; il folder templates e il nome del file layout.blade.php sono stati creati ad hoc…non c’è una struttura folder fissa da seguire. Inoltre è possibile avere più layout all’interno dello stesso progetto quindi conviene dare dei nomi parlanti.
@extends('templates.layout')
NB: nel corso su Udemy il layout è copiato da un template standard di Bootstrap.
Yield
All’interno del layout questa direttiva serve per aggiungere del contenuto; il secondo parametro è il default nel caso il valore sia vuoto; esempio:
# scrive il valore di title passato dalla view; se manca viene scritto Home
<title>@yield('title', 'Home')</title>
# scrive il valore di content passato dalla view
<main role="main" class="container">
@yield('content')
</main>
Section
All’interno della view serve per definire una sezione che poi sarà richiamata nel layout tramite yield; può essere una singola riga oppure più righe; nel caso ci siano più righe la direttiva va chiusa con @endsection oppure @stop.
# riga singola con valore
@section('title', $title)
# la direttiva è aperta e chiusa, con del codice al suo interno
@section('content')
<h1>{{$title}} Template Blade</h1>
@if ($staff)
<ul>
@foreach($staff as $person)
<li>{{$person['name']}} {{$person['lastname']}}</li>
@endforeach
</ul>
@endif
@endsection
All’interno di un layout definisce una sezione che termina con @show; questa direttiva serve per mostrare subito il contenuto della sezione. Facendo delle prove ho capito che senza @show il contenuto della view è irrilevante e non sarà incluso (piuttosto usare @yield).
@section('footer')
...
...
...
@show
Se nella view definiamo una sezione con lo stesso nome essa andrà a sovrascrivere la sezione nel layout SOLO nel caso il layout contenga @show al fondo della sezione.
@section('footer')
...
...
...
@stop
Per mantere il contenuto della sezione nel layout dobbiamo usare la direttiva @parent; così facendo prima di includere il contenuto della view sarà aggiunto il contenuto del layout.
@section('footer')
@parent
...
@stop
Component
Sono simili alle section; i file si creano dentro il percorso resources\views\components\nome_componente.blade.php, mentre il codice html è nella view, a cui bisogna aggiungere dei segnaposto generici.
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="{{$img_path}}" alt="{{$img_title}}" title="{{$img_title}}">
<div class="card-body">
<h5 class="card-title">{{$img_title}}</h5>
{{$slot}}
</div>
</div>
Per passare i valori ai components si possono usare 2 modi
Array
Variabili e valori vengono passati come array nel secondo parametro del componente, mentre {{$slot}} viene popolato come codice html generico fuori dall’array ma all’interno del componente.
NB: ho provato ad aggiungere una variabile slot all’array ma non viene considerata.
@section('content')
<h1>Blog</h1>
@component('components.card',
[
'img_path' => 'https://lamberto.altervista.org/wp-content/uploads/2020/05/paperinik-pkna-il-vento-del-tempo-320x476.jpg',
'img_title' => 'My Image Blog',
]
)
<p>PK e il Razziatore</p>
@endcomponent
@endsection
Usando @slot
In questo caso la coppia variabile-valore è dentro la direttiva @slot, mentre il contenuto generico che sostituisce {{$slot}} nella view resta compreso all’interno del componente senza riferimenti.
@section('content')
<h1>Blog</h1>
@component('components.card')
@slot('img_path', 'https://lamberto.altervista.org/wp-content/uploads/2020/05/Lupo-alberto-320x470.jpg')
@slot('img_title', 'Lupo Alberto')
<p>Ehilà Beppe!!!</p>
@endcomponent
@endsection
Componente basato su classe
La documentazione si trova qui; rivedere corso sezione 7 lezioni 48-49-50.
Il comando per creare un componente è php artisan make:component nome_componente; lega un componente ad una view ed allo stesso tempo ad un template ed un controller.
Il comando php artisan make:component Alert crea la struttura folder/file app\View\Components\Alert.php e resources\views\components\alert.blade.php.
Aggiungendo il parametro --inline al comando sopra Laravel non crea la view corrispondente e nella funzione render() dentro la classe scrive direttamente il codice html, delimitato da <<<<<'blade' e blade.
public function render()
{
return <<<'blade'
<div class="alert alert-danger">
{{ $slot }}
</div>
blade;
}
In app\View\Components\Alert.php bisogna dichiarare le variabili $info e $message come pubbliche all’inizio della classe, passarle alla funzione __construct() (eventualmente settare dei valori default) e richiamarle al suo interno. La funzione render() si occuperà di mostrare il componente.
namespace App\View\Components;
use Illuminate\View\Component;
class Alert extends Component
{
public $info;
public $message;
/**
* Create a new component instance.
*
* @return void
*/
public function __construct($info = 'danger', $message = 'Ciao')
{
$this->info = $info;
$this->message = $message;
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\View\View|string
*/
public function render()
{
return view('components.alert');
}
}
Di seguito la view resources\views\components\alert.blade.php modificata per valorizzare le 2 variabili create.
<div class="alert alert-{{$info}}">
{{$message}}
</div>
In una view il componente si richiama con la dicitura <x-alert/>, dove alert è il nome del componente scelto al momento della creazione. Per passare un valore si usano i 2 punti davanti al nome della variabile usata nella classe; notare che, nell’esempio sotto, passando i valori tra apici singoli sono considerati delle stringhe; senza apici singoli Laravel le considera variabili PHP.
<x-alert :info="'info'" :message="'testo'"/>
Nell’esempio sotto il valore di :name non è più una stringa ma una variabile $name proveniente dalla route routes\web.php, recuparata dalla GET dell’url. Ovviamente bisogna modificare:
- la view del componente per mostare la nuova variabile
- la classe Alert come sopra
<x-alert :name="$name" :info="'info'" :message="'testo'"/>
Route::view('/', 'welcome', ['name' => Request::input('name')]);
Slot
Si mette dentro i componenti ed indica “qualunque altra cosa che non è passata attraverso le variabili”; generalmente è del codice html e nella view valorizza {{$slot}}.
Include
Serve per aggiungere del codice alla pagina; è simile ad un componente ma variabili e valori devono esistere globalmente e provengono dal controller invece che dalla view, nella quale c’è solo il richiamo.
Una sostanziale differenza è che nel controller DEVO specificare slot come se fosse una variabile normale, mentre nella view è opzionale.
NB: l’esempio sotto usa l’include come un componente ma non mi pare un’idea pratica.
# dentro la view resources\views\blog.blade.php
@include('components.card')
# dentro il controller app\Http\Controllers\PageController.php
public function blog()
{
return view('blog',
[
'img_path' => 'https://lamberto.altervista.org/wp-content/uploads/2020/05/STURM_Basket_01_low_2-320x320.jpg',
'img_title' => 'Sturmtruppen',
'slot' => 'Sturmtruppen play basketball'
]
);
}
Se non si vuole usare il controller i valori si possono passare come array, nel secondo parametro della direttiva, esattamente come il componente. Non riporterò questo esempio proprio perchè è identico al componente.