LARAVEL BLADE ENGINE

Blade è un potente e semplice motore di template fornito da laravel che rende la costruzione delle view molto duttile e semplice.

All’interno delle blade view,  l’utente è libero di utilizzare puro codice php oltre alle direttive fornite dal blade engine , questo perché Laravel compila tutto in codice php e lo salva in un’apposita cache fino a quando non subisce modifiche. Tutto ciò rende le view create, utilizzando il blade engine, particolarmente efficienti. Le view vengono salvate a partire dalla cartella resources/views e terminano con l’estensione .blade.php.

Vediamo ora le principali caratteristiche di questo sistema:

La principale peculiarità del blade engine è quella di consentire l’ereditarietà tra le views, mi spiego meglio… poiché molte applicazioni web mantengono un layout comune, sarebbe molto comodo avere una pagina master, che definisce il layout comune, dalla quale poi le singole pagine ereditano e alla quale inviano contenuti in apposite sezioni predisposte.

Utilizziamo un esempio per chiarire meglio:

<!—pagina salvata come  resources/views/layouts/app.blade.php –>

<html>
    <head>
        <title>App Name - @yield('title')</title>
    </head>
    <body>
        @section('sidebar')
            This is the master sidebar.
        @show
        <div class="container">
            @yield('content')
        </div>
    </body>
</html>

In questa pagina, oltre al comune mark-up html, sono presenti alcune direttive, @section e @yield;

la direttiva @section definisce una porzione di contenuti, mentre la direttiva @yield serve a richiamare e visualizzare i contenuti di una specifica @section.

A questo punto, dopo aver definito il layout, definiamo una pagina child che lo utilizza:

<!—pagina salvata in  resources/views/child.blade.php –>

@extends('layouts.app') 
@section('title', 'Titolo pagina')
@section('sidebar')
    @parent
    <p>Contenuto aggiunto alla sidebar.</p>
@endsection
@section('content')
    <p>Corpo del documento.</p>
@endsection

Possiamo subito notare che la prima direttiva @extends(‘layouts.app’) , dichiara che questa pagina eredita il suo layout dalla pagina memorizzata in resources/view/layouts e con nome file app.blade.php (non è necessario specificare il suffisso .blade.php).

La seconda  direttiva @section(‘title’, ‘Titolo pagina’) definisce il titolo che poi viene visualizzato dalla pagina master mediante la direttiva @yield(‘title’). Seguono le sezioni contenenti la sidebar e la sezione  @section(‘content’) che verrà richiamata dalla pagina master grazie alla direttiva @yield(‘content’).

Da notare che la @section(sidebar)  utilizza @parent per richiamare i contenuti già definiti nella pagina master. Occorre precisare la differenza che intercorre quando una direttiva @section viene chiusa con @show, rispetto a quando la si chiude con @endsection, quando si usa @endsection la sezione viene semplicemente definita, mentre quando si utilizza @show la sezione viene visualizzata come quando si usa @yield.

COMPONENTS & SLOTS

Una caratteristica molto interessante ed utile offerta dal blade engine di Laravel è la possibilità di creare delle componenti riutilizzabili e facilmente  richiamabili all’interno delle view:

Creiamo il file resources/views/alert.blade.php

<div class="alert alert-danger">

    {{ $slot }}

</div>

Il contenuto di questo file rappresenta una componente riutilizzabile all’interno di una view, la variabile $slot sarà sostituita di volta in volta dal contenuto specificato, come si può vedere di seguito:

File resources/views/testcomponente.blade.php

@extends('layout.app')
@section('title', 'Modulo prova jquery')
@section('content')
    <div class="row">
        <div class="offset-md-3 col-md-6 col-xs-12">
            @component('alert')

                               Attenzione, Attenzione!!!
            @endcomponent
        </div>
    </div>
@endsection

Talvolta all’interno della componente potrebbero essere necessari più placeholders ad esempio:

<div class="alert alert-danger">

    <h1>{{ $title }}</h1>

    {{ $slot }}

</div>

Si può notare la presenza del segnaposto {{ $title }}, ecco come utilizzare componenti con questa caratteristica aggiuntiva:

@extends('layout.app')
@section('title', 'Modulo prova jquery')
@section('content')
     <div class="row">
        <div class="offset-md-3 col-md-6 col-xs-12">
            @component('alert')
                @slot('title')
                               Titolo componente
                @endslot
                               Attenzione, Attenzione!!
            @endcomponent
        </div>
    </div>
@endsection

Quando si richiama una componente, le si possono passare delle variabili, ecco come:

@component('test.alert',['nome' => 'Francesco'])
            @slot('title')
            Titolo componente
            @endslot
            Attenzione, Attenzione {{$nome}}
@endcomponent

VISUALIZZARE I DATI

In parte lo abbiamo già visto, per visualizzare i dati passati alle views è sufficiente racchiudere i nomi delle variabili all’interno di una doppia parentesi graffa:

Ciao, {{ $nome }}

L’ora corrente è {{ time() }}

La doppia parentesi graffa applica alla variabile la funzione PHP htmlspecialchars per evitare attacchi di tipo XSS. Se si vuole evitare il filtro di htmlspecialchars è sufficiente usare la sintassi seguente:

Ciao, {!! $nome !!}.

STRUTTURE DI CONTROLLO

Il blade template, oltre all’ereditarietà ed alle componenti, offre un’efficace insieme di strutture di controllo (selezione, loop ecc) simili a quelle offerte da php.

Passiamole in rasegna:

@if….@endif

@if (count($records) === 1)
  <p class=”alert alert-info”>Un record trovato</p>
@elseif (count($records) > 1)
  <p class=”alert alert-info”>{{ $records }} record trovati</p>
@else
  <p class=”alert alert-info”>Nessun record trovato</p>
@endif

@unless

@unless (Auth::check()) 
   You are not signed in.
@endunless

Questo codice viene eseguito se la condizione Auth::check() restituisce false (Auth::check() verifica se vi è un utente loggato,  restituendo true se lo è)

@isset

Questa direttiva è la controparte di isset() di php

@isset($records)

    <p>Variabile definita</p>

@endisset

@empty controparte della funzione php empty()

@empty($records)

    <p>La variabile è vuota</p>

@endempty

@auth e @guest

@auth e @guest verificano se l’utente è autenticato (la prima) se non lo è la seconda.

@auth     

   <p> Utente loggato</p>

@endauth

@guest     

   <p>Non sei loggato</p>

@endguest

@hasSection, questa direttiva verifica se una sezione possiede contenuti

@hasSection('navigation')

    <div class="text-right">

        @yield('navigation')

    </div>

    <div class="clearfix"></div>

@endsection

@switch ….@endswitch

@switch($i)

    @case(1)

        Primo...

        @break

    @case(2)

        Secondo...

        @break

    @default

        Default …...

@endswitch

Loops

@for ($i = 0; $i < 10; $i++)
    The current value is {{ $i }}
@endfor

@foreach ($users as $user)
    <p>This is user {{ $user->id }}</p>
@endforeach

@forelse ($users as $user)
    <li>{{ $user->name }}</li>
@empty
    <p>No users</p>
@endforelse


@while (true)
    <p>I'm looping forever.</p>
@endwhile


@foreach ($users as $user)
    @if ($user->type == 1)
        @continue
    @endif
    <li>{{ $user->name }}</li>
    @if ($user->number == 5)
        @break
    @endif
@endforeach

Caratteristica molto comoda del blade engine è quella di usare le condizioni in un’unica riga come mostrato nell’esempio seguente:

@foreach ($users as $user)
    @continue($user->type == 1)   // se è vera la condizione salta all'iterazione successiva
    <li>{{ $user->name }}</li>
    @break($user->number == 5) // se è vera la condizione esce dal ciclo
@endforeach

Durante  il loop si ha la possibilità di usare la  variabile $loop, che fornisce accesso ad alcune informazioni relative al ciclo in esecuzione (se è la prima iterazione, se è l’ultima, il numero totale di iterazioni, se è un’iterazione di indice pari o dispari ecc.)

@foreach ($users as $user)

    @if ($loop->first)

        This is the first iteration.

    @endif

    @if ($loop->last)

        This is the last iteration.

    @endif

    <p>This is user {{ $user->id }}</p>

@endforeach

Vi è la possibilità di accedere da un loop annidato alle informazioni del padre, come di seguito mostrato:

@foreach ($users as $user)

    @foreach ($user->posts as $post)

        @if ($loop->parent->first)

            This is first iteration of the parent loop.

        @endif

    @endforeach

@endforeach

Ecco un elenco di tutte le proprietà della variabile $loop:

Proprietà Descrizione
$loop->index Indice dell’iterazione corrente (parte da 0).
$loop->iteration Numero iterazione (inizia da 1).
$loop->remaining Quante iterazioni rimangono.
$loop->count Numero totale di iterazioni.
$loop->first Vero se è la prima iterazione.
$loop->last Vero se è l’ultima iterazione.
$loop->even Vero se è un’iterazione di indice pari.
$loop->odd Vero se è un’iterazione di indice dispari.
$loop->depth Livello di annidamento del loop.
$loop->parent Variabile loop del genitore (si applica ad un loop figlio).

 

Inserire un commento in una view blade:

{{– Semplice commento –}}

Se si desidera usare del codice php puro, può essere molto comodo farlo utilizzando la direttiva @php … @endphp, invece di <?php …. ?>

@php    Codice php  @endphp

CSRF e SPOOFING DEI METODI NEI MODULI

Quando in una blade view si crea una form, per scongiurare gli attacchi CSRF (cross site request forgery), laravel utilizza un campo nascosto _token che viene verificato dal middleware predisposto per la protezione da attacchi csrf.

Il suddetto campo viene così definito:

<input name=”_token” type=”hidden” value=”{!! csrf_token() !!}” />

Ebbene, anche in questo il blade engine rende le cose molto più semplici, infatti per generare un tale campo è sufficiente utilizzare la direttiva @csrf, come di seguito indicato

<form method="POST" action="/profile">

    @csrf

    ...

</form>

Un’altra feature veramente utile, offerta dal blade engine, è quella che permette di fare lo spoofing del metodo di invio del modulo. Per cambiare il metodo di invio è sufficiente utilizzare la direttiva @method(‘nome metodo’), esempio:

<form action="/foo/bar" method="POST">

    @method('PUT')

   ...

</form>

Nell’esempio appena visto, il metodo di invio dei dati del modulo sarà PUT e non post. Se si volesse usare il metodo DELETE, sarebbe sufficiente fare così:

<form action="/foo/bar" method="POST">

    @method('DELETE')

   ...

</form>

Validazione form e visualizzazione degli errori

La direttiva @error(‘nome campo’)…@enderror permette di mostrare o includere contenuti solo nel caso in cui, durante la validazione dei dati del modulo, si sono riscontrati per il campo passato come argomento, violazioni delle regole.

<label for="title">Linux kernel</label>

<input id="title" type="text" class="@error('title') is-invalid @enderror">

@error('title')

    <div class="alert alert-danger">{{ $message }}</div>

@enderror

L’esempio non ha bisogno di spiegazioni, ma mostra la potenza e la versatilità di questa direttiva.

INCLUDERE SUB-VIEW

Mediante la direttiva @include, è possibile includere una sub-view all’interno di una view, tutte le variabili della view principale sono visibili anche nella sub-view.

<div>
    @include('errors')
    <form>
        <!—contenuti del form -->
    </form>
</div>

Nonostante la view erediti le variabili dalla principale, è possibile passarne altre utilizzando il secondo parametro della direttiva @include():

@include(‘nomeview’, [‘key’ => ‘value’])

Se si cerca di includere una view che non esiste, laravel lancia un’eccezione. Per evitare la segnalazione di errori, è posibile usare @includeIf():

@includeIf(‘nomeview’, [‘key’ => ‘value’])

Utilizzando @includeIf(), se la view non esiste il programma continua normalmente la sua esecuzione.

Se l’inclusione di una view dipende dal verificarsi di una condizione, allora è possibile utilizzare @includeWhen():

@includeWhen($boolean, ‘nomeview’, [‘key’ => ‘value’])

Se si desidera includere la prima view esistente tra un elenco, allora occorre usare @includeFirst()

@includeFirst([‘custom.admin’, ‘admin’], [‘some’ => ‘data’])

Utilizzare una view all’interno di un ciclo

Supponiamo di avere una collection o un array che elenca un insieme di opzioni e di voler creare una lista simile alla seguente:

<ul>

<li>Opzione 1 </li>

<li>Opzione 2 </li>

<li>Opzione 3 </li>

.

.

<li>Opzione n </li>

</ul>

Utilizzando la direttiva @each() tutto diventa molto più semplice, infatti è sufficiente creare una partial view opzioni.blade.php con il contenuto seguente:

<li>{{$opzione}}</li>

mentre nella view principale va usato il codice seguente:

<ul>

@each(‘opzioni’,$colletion_opzioni,’opzione’)

</ul>

I parametri passati hanno il seguente significato:

‘opzioni’ -> nome della view,  $colletion_opzioni -> contiene l’elenco delle opzioni, ‘opzione’ -> nome della variabile che conterrà ad ogni ciclo l’opzione corrente. Volendo, è possibile usare un quarto parametro contenente il nome della view da utilizzare se la variabile $colletion_opzioni è vuota.

Di seguito un esempio completo sull’uso della direttiva @each():

Nel file routes/web.php creare la seguente route

Route::get('/testsubview',function() {

    $opts = ['opzione 1','opzione 2','opzione 3','opzione 4',];

    return view('test.testsubview',['opts' => $opts]);

});

Creare poi in resources/views/test la view testsubview.blade.php con il seguente contenuto

<div>

    <h1>Test sub-view</h1>

    <ul>

                @each('test.opzioni',$opts,'opt')

    </ul>

</div>

Infine creare in resources/views/test  la partial view opzioni.blade.php con il seguente contenuto

<li>{{ $opt }}</li>

A questo punto se puntiamo il browser su http://laraapp.webserver.loc/testsubview , comparirà il nostro elenco puntato:

Test sub-view

  • opzione 1
  • opzione 2
  • opzione 3
  • opzione 4

Chiudiamo questo articolo informando che laravel dà la possibilità di creare direttive personalizzate, per ulteriori approfondimenti consultare la guida ufficiale (https://laravel.com/docs/5.8/blade#extending-blade )

 

Articoli correlati

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *