Le viste rappresentano il componente di Laravel che si occupa di definire la struttura delle pagine HTML e dei dati che verranno serviti agli utenti. Laravel supporta viste definite in semplici file PHP e viste Blade, un template system diffuso nel mondo della programmazione Web. Il riconoscimento dell'engine è automatico e basato su una convenzione a livello di filename (se la vista ha estensione .php
verrà utilizzato l'engine classico, altrimenti se la vista ha estensione .blade.php
verrà utilizzato l'engine di blade).
Laravel favorisce l'utilizzo di Blade in quanto strumento più avanzato sia funzionalmente che sintatticamente rispetto ai classici file PHP.
View e Controller
Le views vengono definite principalmente all'interno dei controller una volta impostata la logica di business dell'applicazione. Tutto avviene tramite l'helper view
:
return view('nomeview', $datiDaPassareAllaView);
Le views vengono automaticamente ricercate all'interno della folder resources/views
. Sono disponibili anche subfolder all'interno del nome della view usando il carattere punto (.). L'estensione del file non viene mai comunicata esplicitamente delegando così a Laravel la scelta dell'engine. Per esempio, la view resources/views/user/detail.blade.php
avrà come riferimento la stringa user.detail
.
I parametri
I parametri alle views possono essere comunicati in due diversi modi, tramite il secondo parametro dell'helper view
o tramite il metodo with
. Nel primo caso l'oggetto dovrebbe essere un array associativo, mentre nel secondo caso può essere anche un oggetto plain. Nel dettaglio queste due righe sono a tutti gli effetti equivalenti:
return view('user.detail', [ 'username' => 'abottarini', 'email' => 'ab@gmail.com']);
return view('user.detail')->with('username', 'abottarini')->with('email', 'ab@gmail.com');
I view composer
I view composer sono componenti avanzati che permettono di condividere dati tra views diverse evitando di duplicare le logiche di business per l'ottenimento dei dati. Devono essere definiti all'interno di un service provider e permettono di associare ad una determinata view un particolare metodo (o una closure). In particolare con questo esempio comunichiamo al framework di invocare il metodo nomemetodo
quando la view nomeview
viene inclusa in altre views o invocata direttamente.
view()->composer('nomeview', 'nomemetodo');
Blade
Blade rappresenta il principale strumento per definire views all'interno di Lavarel. E' un linguaggio di templating compilato in file PHP e cacheato in modo da non generare nessun tipo di overhead. I file Blade hanno l'estesione .blade.php
e grazie a questa Laravel li distingue da normali views PHP.
Ereditarietà
I template definiti con Blade sfruttano l'ereditarietà dei linguaggi orientati agli oggetti. E' infatti possibile definire layout padri astratti e layout figli che li estendono e aggiungono funzionalità e sezioni HTML. I costrutti principali per utilizzare l'ereditarietà sono @yield
e @section
:
<!-- views/layouts/master.blade.php -->
<html>
<head>
<title>@yield('title')</title>
</head>
<body>
<div class="sidebar">
@yield('sidebar')
</div>
<div class="container">
@yield('content')
</div>
</body>
</html>
<!-- views/view.blade.php -->
@extends('layouts.master')
@section('title', 'Page Title')
@section('sidebar')
<p>This is my sidebar.</p>
@endsection
@section('content')
<p>This is my content.</p>
@endsection
Il primo file rappresenta un layout, una sorta di scheletro astratto con tre sezioni configurabili, title
, sidebar
e container
, definite tramite il costrutto @yield
. Il secondo file rappresenta invece una view concreta che estende il precedente layout e ne definisce le sezioni tramite @section
.
Non c'è limite al livello gerarchico che si puo implementare. Possono esistere anche viste che estendono viste già complete con l'unico scopo di modificarne una sezione. Inoltre, grazie al costrutto @parent
, è possibile embeddare in una vista figlia il contenuto del padre senza sovrascriverlo.
Stampa dei dati
Per visualizzare delle variabili all'interno dei template usiamo la sintassi {{ $nomevariabile }}
. Uno strumento spesso sottovalutato è la possibilità di definire un default nel caso la variabile non sia definita: {{ $nomevariabile or 'stringa di default' }}
. In automatico eventuali caratteri HTML vengono escapati da Laravel, ma nel caso fosse necessario stampare il valore della variabile senza filtri addizionali possiamo scrivere {!! $nomevariabile !!}
.
Controllo del flusso
L'ereditarietà rappresenta la principale differenza di Blade rispetto agli altri linguaggi di templating. Oltre a questo aspetto, Blade presenta comunque tutti gli altri strumenti classici.
Grazie a @if
, @elseif
e @else
possiamo definire template condizionali. Utilizzando @for
, @foreach
, @forelse
, @empty
e @while
possiamo renderizzare strutture HTML ripetitive all'interno di cicli. Tramite @include
sarà possibile includere frammenti comuni all'interno di views (spesso sfruttando i ViewComposer descritti in precedenza).
Biblios parte: introduciamo le Views
La quarta parte del nostro tutorial ci permetterà di avere finalmente qualcosa di funzionante. L'obiettivo sarà quello di definire due views per i nostri controller getHome
e getBookDetail
e creare dei finti dati da mostrare agli utenti.
Per iniziare possiamo modificare la nostra classe FrontendController
aggiungendo due metodi privati che simulano l'interazione con il database e permettono di ottenere l'elenco dei libri disponibili e modificando i metodi pubblici come segue:
public function getHome() {
return view('home')->with('books', $this->getAllBooks());
}
public function getBookDetail($id) {
return view('bookdetail')->with('book', $this->getBook($id));
}
In questo modo abbiamo creato la logica di business per visualizzare nella home l'elenco di tutti i libri e le pagine di dettaglio. Passiamo ora alle views. Da best practice il primo passo è quello di definire un layout astratto per poi passare alla definizione delle varie pagine. Creiamo quindi il file resources/views/layout/biblios.blade.php
:
<html>
<head>
<title>Biblios - @yield('title')</title>
</head>
<body>
<h1>@yield('title')</h1>
<div id="content">
@yield('content')
</div>
</body>
</html>
e estendiamolo grazie a resources/views/home.blade.php
@extends('layouts.biblios')
@section('title', 'Home')
@section('content')
@foreach($books as $index => $book)
<h2>{{ $book->title }}</h2>
<p>
{{ $book->author }}<br/>
<a href="{{ route('bookDetail', [ 'id' => $index ]) }}">Guarda dettaglio</a>
</p>
@endforeach
@endsection
Oltre alla home definiamo il template della pagina di dettaglio. Una volta realizzato possiamo finalmente lanciare l'applicazione (con php artisan serve
) e iniziare a navigare tra le diverse pagine del portale.