Sconto del 20% su tutti i corsi inserendo nel form il codice SPRING20 | Fino al 30 aprile
Sconto del 20% su tutti i corsi inserendo nel form il codice SPRING20 | Fino al 30 aprile

Guide per aspiranti programmatori

Lezione 15 / 30

Template Blade in Laravel

Blade è il php template engine fornito di default dal framework Laravel. È pensato per rendere semplice la scrittura di template, mantenendo, allo stesso tempo, la possibilità di definire template non banali che possono utilizzare al loro interno codice PHP.

Lo scopo di un template engine è quello di creare uno specifico contenuto da presentare partendo da un modello e applicando ad esso dati. Il modello è salvato, abitualmente, in un file chiamato, per l’appunto, “template”, mentre i dati vengono recuperati da altre porzioni della propria applicazione e applicati al template tramite l’invocazione di un opportuno metodo.

Ciò consente di separare, nella propria applicazione, la parte di logica del recupero dei dati dalla parte di presentazione del dato (per intenderci, possiamo applicare lo stesso dato a diversi template e ottenere pagine diverse nell’aspetto, oppure possiamo scegliere cosa mostrare in base ai dati che abbiamo recuperato in quel momento).

I file di template Blade hanno estensione .blade.php e sono raccolti nella directory resources/views di una applicazione Laravel. L’elaborazione del template avviene invocando il metodo helper view, come visto nella precedente lezione.

Elementi base di un template Blade in Laravel

I template definiti con Blade fanno uso di particolari costrutti, chiamati statement o direttive, per permettere allo sviluppatore web di decidere come mostrare il contenuto.

<!-- resources/views/hello.blade.php -->
<html>
  <body>
    <h1>Hello {{ $name }}</h1>
    <p>Today is {{ time() }}</p>
  </body>
</html>

Lo statement più semplice e importante è {{ }}, indicato anche come echo statement. Tra le doppie parentesi graffe è possibile inserire del codice PHP che verrà elaborato e il suo risultato verrà inserito nel rendering del template. È possibile usare variabili (che verranno passate al template engine dal metodo helper view) o altri metodi del linguaggio PHP.

<!-- resources/views/hello.blade.php -->
<html>
  <body>
    <h1>
    @if($name)
      Hello {{ $name }}
    @else
      Hello Laravel
    @endif
    </h1>
  </body>
</html>
// routes/web.php
Route::get('/hello', function (Request $request) {
  $name = $request->query('name');
  return view('hello', ['name' => $name]);
});

Altre direttive permettono di aggiungere logica (di presentazione) al proprio template, semplificando, quindi, il codice lato route / controller. L’esempio qui sopra è una versione alternativa di quanto visto nella lezione sulle rotte, in cui la scelta di cosa mostrare, nel caso in cui non sia stato passato un name in query string, passa dal controller alla view, grazie alle funzionalità offerte dalla direttiva @if del template engine Blade.

NOTA: nel caso in esempio, l’uso della direttiva @if è esagerato. È possibile, infatti, usare l’operatore null coalescence di PHP dentro a un echo statement per ottenere lo stesso risultato in modo più elegante e chiaro: <h1>Hello {{ $name ?? ‘Laravel’ }}</h1>. Non dimenticare mai che i template Blade sono pur sempre file PHP, anche se l’esecuzione di codice PHP è permessa in particolari posizioni.

Direttive Blade di flusso

Alcune direttive di Blade risultano particolarmente utili per mostrare contenuti in base a determinate condizioni, basate ovviamente sui valori passati al template e letti da Blade come variabili PHP. Una caratteristica comune a queste direttive è che racchiudono la logica tra una direttiva d’apertura e una direttiva di “end”.

Direttiva @if in Blade

È possibile realizzare costrutti “if” usando le direttive @if, @elseif, @else e @endif. Queste direttive funzionano in maniera identica agli analoghi PHP.

@if (count($likes) === 1)
  You have only one like :-(
@elseif (count($likes) > 1 && count($likes) < 10)
  You have {{ count($likes) }} likes :-)
@elseif (count($likes) >= 10)
  People really likes you :-D
@else
  No likes :'(
@endif

Al fine di rendere il template più leggibile, Blade mette a disposizione alcune direttive di comodità che ricadono nell’ambito degli “if”:

  • @unless(<condition>) … @endunless che corrisponde a un “if not”
  • @isset(<variable>) … @endisset che controlla se la variabile è definita e non ha valore null
  • @empty(<variable>) … @endempty che controlla è “empty”

Direttiva @switch in Blade

Le direttive @switch, @case, @break, @default e @endswitch permettono di costruire costrutti “switch”, sempre operando in maniera analoga alle controparti PHP.

@switch($variable)
  @case(1)
    First case...
    @break

  @case(2)
    Second case...
    @break

  @default
    Default case...
@endswitch

Direttive di loop in Blade

Sono, ovviamente, disponibili direttive analoghe a quelle PHP per gestire con strutture di loop, che operano nello stesso modo.

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

@foreach ($fruits as $fruit)
  <p>Fruit {{ $fruit->$name }} in your order</p>
@endforeach

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

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

L’esecuzione della iterazione corrente del loop può essere saltata tramite le direttive @countinue e @break (usando una direttiva @if per definire la condizione di skip).

Una particolarità della direttiva @foreach è quella di rendere disponibile una speciale variabile $loop all’interno del loop stesso. Tale variabile permette di accedere a informazioni sul loop stesso, come, per esempio, l’iterazione corrente ($loop->iteration, che parte da 1, oppure $loop->index che parte da 0) oppure se è la prima/ultima del loop ($loop->first e $loop->last, entrambi booleani).

Direttive Blade di contenuto

Alcune direttive Blade sono state rese disponibili per semplificare l’elaborazione di determinati elementi HTML partendo dai valori passati al rendering del template

La direttiva @class permette di compilare una stringa per definire una classe CSS.

// valori passati al template engine
$isActive = false;
$hasError = true;
<!-- file .blade.php -->
<span @class([
   'font-bold' => $isActive,
   'text-gray-500' => ! $isActive,
   'bg-red' => $hasError,
])></span>
<!-- output -->
<span class="text-gray-500 bg-red"></span>

Questa direttiva accetta un array chiave/valore in cui la chiave è il nome della classe CSS da aggiungere e il valore è una espressione booleana che stabilisce se aggiungere tale classe.

La direttiva @checked può essere usata per aggiungere l’attributo checked a un elemento HTML di tipo <input> quando la condizione indicata ha valore true.

<input type="checkbox"
   name="newsletter"
   value="newsletter"
   @checked(@old('newsletter), $user->$newsletterOK)
/>

In modo analogo operano le direttive @selected per le option di una select HTML (), @disabled, @readonly e @required.

Layout e view child in Blade

Il vero punto di forza del template engine Blade risiede, però, nella sua capacità di poter separare parti comuni a vari singoli template in file separati e ricostruire, poi, il contenuto assemblando insieme le varie porzioni, con una logica basata sulla ereditarietà. Questo meccanismo prende il nome di template layout.

La possibilità di avere uno o più template base condivisi è molto importante per la creazione di siti web, poiché gran parte delle pagine di un sito o di una web app mantengono una struttura comune ed elementi ripetuti. Se si dovesse creare un file di template con l’HTML completo per ogni tipo di pagina erogata, si finirebbe con il dover modificare su più file le parti di codice che sono in comune (header, footer, ..).

Cominciamo con un pratico esempio, ipotizzando di voler realizzare un template layout in cui ci sono parti comuni (per esempio, i titoli con il nome del sito) e parti specifiche della pagina che stiamo realizzando.

Layout

Layout

Il file di template blade che rappresenterà la nostra “base” per tutte le pagine potrà essere salvato nella directory resources/views/layouts/ – quanto meno per ricordarci che è uno dei template layout di base – e avrà il seguente contenuto:

{{-- resources/views/layouts/page.blade.php --}}

<html>
  <head>
    <title>@yield('title') - Yet No Name</title>
  </head>
  <body>
    @section('header')
    <p>This is the website Yet No Name</p>
    @show

    <div class="content">
      @yield('content')
    </div>
  </body>
</html>

In questo template abbiamo definito l’intera struttura di una pagina HTML e abbiamo utilizzato alcune direttive speciali di Blade: @section e @yeld. La direttiva @section serve a definire una sezione di un contenuto, mentre la direttiva @yeld è usata come segnaposto per dire dove andare a inserire una @section con lo stesso nome.

È possibile, a questo punto, definire una vista “child” che erediterà questo layout di base tramite la direttiva @extends:

{{-- resources/views/one.blade.php --}}

@extends('layouts.page')

@section('title', 'Page One')

@section('header')
  @parent

  <p>This is the page one.</p>
@endsection

@section('content')
  <p>This is the content for Page One.</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
@endsection

Una child view usa la direttiva @extends per indicare la view layout genitore da cui il child dovrebbe “ereditare”. All’interno della child view è possibile indicare il contenuto da iniettare nel genitore tramite le direttive @section. L’esatta composizione dipende dalla modalità con cui sono state definite le varie sezioni nel layout genitore e nella view figlia.

In particolare notare:

  • @yeld(‘title’) nel layout e @section(‘title’, ‘Page One’) nel child → in questo modo nel layout abbiamo indicato un segnaposto, lasciando al child fornire il contenuto.
  • @yield(‘content’)nel layout e @section(‘content’) … @endsection nel child → si comporta come il precedente, ma essendo un contenuto più complesso è compreso tra la direttiva di apertura e quella di chiusura della sezione.
  • @section(‘sidebar’) … @show nel layout e @section(‘sidebar’) @parent … @endsection nel child → in questo caso, la section si apre nel layout e viene chiusa nel child, poiché è stata indicata la direttiva @show nel layout e @parent nel child.

Il file HTML generato invocando view(‘one’) sarà, quindi, il seguente

<html>
<head>
  <title>Page One - Yet No Name</title>
</head>
<body>
<p>This is the website Yet No Name</p>
<p>This is the page one.</p>
<div class="content">
  <p>This is the content for Page One.</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</body>
</html>

SubView incluse

NOTA: riportiamo per completezza la direttiva @include anche se il suggerimento degli sviluppatori di Laravel è quello di usare per la stessa esigenza i componenti Blade

La direttiva @include di Blade opera nel modo che il nome suggerisce: include una view all’interno di una view.

{{-- ... -- }}
@section('content')

@include('shared.footer')

La view inclusa riceverà tutti i dati disponibili nella view genitore, ma sarà possibile passarne altri indicando un array di coppie chiave / valore.

Sono disponibili alcune varianti della direttiva: @includeWhen, @includeUnless (condizione booleana per includere la view) e @includeFirst (la prima view trovata in un array di view).

View di collection

È disponibile una direttiva che unisce in sé le funzioni delle direttive @foreach e @include

{{-- file resources/view/page.blade.php --}}

@each('shared.order', $orders, 'order')

{{-- file resources/view/shared/fruit.blade.php --}}
<span>{{ $order->$id }} - {{ $order->$amount }} - {{ $order->$status }}</span>

Il primo parametro della direttiva @each è il nome della view da utilizzare, il secondo parametro è l’array o la collection su cui iterare, il terzo argomento è il nome che avrà il singolo elemento su cui si sta iterando all’interno della view.

Pagamento rateale

Valore della rata: A PARTIRE DA 115 €/mese.

Esempio di finanziamento 

Importo finanziato: € 2440 in 24 rate da € 115 – TAN fisso 9,55% TAEG 12,57% – importo totale del credito € 2841.

Il costo totale del credito comprende: interessi calcolati al TAN indicato, oneri fiscali (imposta di bollo sul contratto 16,00 euro*) addebitati sulla prima rata, costo mensile di gestione pratica € 3,90, spesa di istruttoria € 0,00, spesa per invio rendicontazione periodica cartacea € 0,98 (o spesa per invio rendicontazione periodica cartacea € 0,00), imposta di bollo su rendicontazione periodica € 0,00. Modalità di rimborso obbligatoria: addebito diretto su c/c. La scadenza delle rate è determinata dal giorno della liquidazione del contratto; la data di scadenza delle rate è prevista il giorno 15 del mese. L’importo di ciascuna rata comprende una quota di capitale crescente e interessi decrescente secondo un piano di ammortamento “alla francese”. Offerta valida dal 01/01/2024 al 31/12/2024.

Messaggio pubblicitario con finalità promozionale. Per le informazioni precontrattuali richiedere sul punto vendita il documento “Informazioni europee di base sul credito ai consumatori” (SECCI) e copia del testo contrattuale. Salvo approvazione di Sella Personal Credit S.p.A. Aulab S.r.l. opera quale intermediario del credito NON in esclusiva.

*In fase di richiesta del finanziamento verrà proposta la facoltà di selezionare, in alternativa all’imposta di bollo sul contratto di 16,00 euro, l’imposta sostitutiva, pari allo 0,25% dell’importo finanziato.

Pagamento rateale

Valore della rata: A PARTIRE DA 210 €/mese.

Esempio di finanziamento  

Importo finanziato: € 4500 in 24 rate da € 210,03 – TAN fisso 9,68% TAEG 11,97% – importo totale del credito € 5146,55.

Il costo totale del credito comprende: interessi calcolati al TAN indicato, oneri fiscali (imposta di bollo sul contratto 16,00 euro*) addebitati sulla prima rata, costo mensile di gestione pratica € 3,90, spesa di istruttoria € 0,00, spesa per invio rendicontazione periodica cartacea € 0,98 (o spesa per invio rendicontazione periodica cartacea € 0,00), imposta di bollo su rendicontazione periodica € 0,00. Modalità di rimborso obbligatoria: addebito diretto su c/c. La scadenza delle rate è determinata dal giorno della liquidazione del contratto; la data di scadenza delle rate è prevista il giorno 15 del mese. L’importo di ciascuna rata comprende una quota di capitale crescente e interessi decrescente secondo un piano di ammortamento “alla francese”. Offerta valida dal 01/01/2024 al 31/12/2024.

Messaggio pubblicitario con finalità promozionale. Per le informazioni precontrattuali richiedere sul punto vendita il documento “Informazioni europee di base sul credito ai consumatori” (SECCI) e copia del testo contrattuale. Salvo approvazione di Sella Personal Credit S.p.A. Aulab S.r.l. opera quale intermediario del credito NON in esclusiva.

* In fase di richiesta del finanziamento verrà proposta la facoltà di selezionare, in alternativa all’imposta di bollo sul contratto di 16,00 euro, l’imposta sostitutiva, pari allo 0,25% dell’importo finanziato.

Contattaci senza impegno per informazioni sul corso

Scopriamo insieme se i nostri corsi fanno per te. Compila il form e aspetta la chiamata di uno dei nostri consulenti.