Introduzione
L’articolo che state per leggere è una traduzione, dalla documentazione ufficiale di Laravel, della pagina che potete trovare a questo indirizzo.
Questa guida di “avvio veloce” fornisce un’introduzione basilare a Laravel ed alle sue funzionalità principali. Partendo dalle migration del database fino alle view, passando per Eloquent ORM, il sistema di routing e quello di valutazione. Senza scordarsi del sistema di templating Blade. Perchè una cosa del genere? Semplice: iniziare è molto più semplice se si ha a disposizione, insieme alla documentazione, qualcosa di più pratico su cui mettere le mani.
Continuando a leggere, impareremo insieme ad usare Laravel attraverso l’uso pratico di una selezione di alcune delle sue feature principali, con l’obiettivo di creare un’applicazione che tenga traccia di tutte le cose che abbiamo da fare. Insomma: la classica “to-do” list. Il codice completo dell’applicazione è già disponibile su GitHub.
Installazione
Per cominciare, abbiamo bisogno di un’installazione fresca fresca del Framework, nella sua ultima versione. Ovviamente dovremo avere a disposizione anche un ambiente di lavoro su cui esercitarci: consiglio di usare Homestead, la vagrant box ufficiale di Laravel. Per creare un nuovo progetto con l’ultima versione di Laravel, eseguiamo
composer create-project laravel/laravel quickstart –prefer-dist
… e via! Al resto penserà il nostro caro Composer. Comodo, vero?
Installazione del Progetto (Opzionale)
Se vuoi, puoi leggerti questo articolo senza andare a dover programmare l’applicazione. Come detto poco fa, infatti, il codice dell’applicazione è già disponibile su un repository GitHub. Esegui le seguenti istruzioni per “portarti avanti con il lavoro”.
git clone https://github.com/laravel/quickstart-basic quickstart
cd quickstart
composer install
php artisan migrate
Preparazione del Database
Migration
Innanzitutto, usiamo una migration per definire quella che sarà la struttura delle tabelle, sul database, necessarie a tenere traccia dei nostri task. Il sistema di migration di Laravel è perfetto per definire tali strutture con una sintassi fluida, semplice e soprattutto senza doversi scostare dal PHP. Tra l’altro, le migration fungono anche da sistema di versioning del tuo database: una volta messe sotto source control i nostri colleghi non dovranno fare altro che eseguirle e saranno sempre al passo con lo sviluppo dell’applicazione, senza dover aggiungere manualmente questa o quella colonna.
Torniamo a noi: abbiamo bisogno di una tabella per i task. Il tool da linea di comando di Laravel, Artisan, viene in nostro soccorso. Precisamente, il comando che ci serve è
php artisan make:migration create_tasks_table –create=tasks
Il file di migration verrà piazzato, di default, nella cartella database/migrations
del tuo progetto. Inoltre, il comando aggiunge ad ogni file, automaticamente, un timestamp ed un ID univoco. Modifichiamo il file appena creato:
increments(‘id’);
$table->string(‘name’);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop(‘tasks’);
}
}
A questo punto la nostra migration è pronta ad essere eseguita per creare la tabella sul database. Nota: nel caso in cui ci stessimo affidando ad Homestead per ciò che riguarda l’ambiente di sviluppo, il comando seguente dovrà essere eseguito dalla shell della macchina virtuale (in quanto la macchina host non ha accesso diretto al suo database).
php artisan migrate
Fatto? Bene! Questo comando creerà le tabelle del database. Andando a dare uno sguardo alla struttura del database (con un qualsiasi client a tua scelta) vedremo la nuova tabella pronta ad essere usata, esattamente come definita nella migration.
Ora che il database c’è, bisogna definire quali model andranno ad interagire con esso. Passiamo a definire i model Eloquent!
I Model Eloquent
Eloquent è l’ORM (object relational mapper) presente out of the box in Laravel. Semplifica tutte quelle operazioni di lettura e scrittura dal/sul database, fornendo un livello di astrazione che trova la sua “concretizzazione” in quelle classi dette model. Nella maggior parte dei casi, per ogni model c’è una tabella nel database.
Detto questo: abbiamo creato la nostra tabella tasks
, adesso abbiamo bisogno di un model Task
. Anche qui possiamo usare Artisan per generare velocemente il file di cui abbiamo bisogno.
php artisan make:model Task
Di default, il model verrà posizionato nella cartella app
dell’applicazione. Allo stato attuale, inoltre, il model è praticamente vuoto. Tra l’altro, non dobbiamo neanche specificare un granchè: Eloquent, infatti, capisce da solo che a Task
va collegata la tabella tasks
(il suo plurale) andando a controllare i nomi di model e tabelle.
Ecco come appare un model vuoto:
‘web’], function () {
/**
* Show Task Dashboard
*/
Route::get(‘/’, function () {
//
});
/**
* Add New Task
*/
Route::post(‘/task’, function (Request $request) {
//
});
/**
* Delete Task
*/
Route::delete(‘/task/{task}’, function (Task $task) {
//
});
});
Mostrare una View
Le nostre route, anche se definite, al momento non fanno praticamente nulla. Vediamo di cambiare le cose. Abbiamo la route /
che corrisponde alla pagina principale dell’applicazione. Vogliamo fare in modo che qui vengano mostrati i vari task memorizzati nel sistema, oltre ad un form che ne permetta l’aggiunta.
In Laravel, tutte le view sono memorizzate in resources/views
. Tramite l’helper view
possiamo renderizzare uno di questi template da una route in modo molto semplice.
Route::get(‘/’, function () {
return view(‘tasks’);
});
Passando la stringa “tasks” all’helper view
stiamo chiedendo a Laravel di cercare il file in questione e renderizzarlo. Precisamente, il file cercato è resources/views/tasks.blade.php
. Che, tuttavia, ancora non esiste!
Rimediamo.
Costruire Layout e View
Nel caso della nostra applicazione manterremo le cose semplici: una sola view, che conterrà il form per l’aggiunta di un nuovo task e subito dopo la lista di quelli già inseriti. Per aiutarti a visualizzare il risultato finale, ecco uno screenshot di quello che sarà il lavoro finito.
Definiamo il Layout
Quasi tutte le web application esistenti usano, come “fondamenta” per la grafica, lo stesso layout di base. Come appena visto nello screen, nella nostra task list sarà presente una barra di menu che potrebbe tranquillamente essere riproposta su ogni eventuale pagina. Il sistema di template di Laravel rende semplice realizzare dei risultati all’altezza delle aspettative senza troppi sforzi, attraverso Blade.
Tutte le view di un’applicazione Laravel vengono generalmente messe nella directory resources/views
. Definiamo quindi una nuova view resources/views/layouts/app.blade.php
. L’estensione .blade.php
serve a spiegare al framework che per quel file dovrà essere usato il sistema di template.
Nulla, ovviamente, ti vieta di usare il classico PHP, anche se Blade può aumentare enormemente la tua produttività per quanto riguarda i layout e le view.
Ecco come apparirà il nostro file:
@yield(‘content’)
Notiamo il @yield('content')
presente nel layout. Si tratta di un’istruzione speciale di Blade: indica che tutte le pagine che estendono questo layout dovranno iniettare proprio lì il loro contenuto. Come? Vediamolo subito, definendo una “child view” che faccia uso del layout appena costruito.
Definiamo una Child View
Dunque: abbiamo bisogno di definire una nuova view che contenga un form per la creazione di un nuovo task, ed una tabella che elenchi quelli già presenti. Creiamo un nuovo file resources/views/tasks.blade.php
.
Salteremo la parte relativa a Bootstrap per evitare di andare fuori tema. D’altronde, l’intero progetto può essere trovato su GitHub. Ecco il contenuto del file:
@extends(‘layouts.app’)
@section(‘content’)
@include(‘common.errors’)
@endsection
Prima di andare avanti, vediamo cosa c’è da capire qui. Innanzitutto, questo template estende il layout creato in precedenza tramite la direttiva @extends
. Di conseguenza, tutto il contenuto tra @section('content')
e @endsection
verrà iniettato in corrispondenza della direttiva @yield('content')
del layout principale.
La direttiva @include('common.errors')
specifica invece un’inclusione di un altro template, che si dovrebbe trovare in resources/views/common/errors.blade.php
. Diciamo “dovrebbe” perché non ancora esiste: rimedieremo a breve.
Ora che abbiamo definito un layout ed una view per la nostra applicazione possiamo effettivamente usare il codice qui di seguito
Route::get(‘/’, function () {
return view(‘tasks’);
});
per mostrare qualcosa all’utente finale.
Adesso facciamo un altro passo avanti, capendo come aggiungere un nuovo task al sistema creando una route POST che risponda all’URL /task
.
Aggiunta di Task
Validazione
Dobbiamo aggiungere, finalmente, del codice alla route POST /task
per validare l’input inserito dall’utente e creare, di conseguenza, un nuovo task. Partiamo dalla validazione.
Per questo form, diciamo che vogliamo fare in modo che sia obbligatorio inserire il nome del task, e che questo deve avere una lunghezza massima di 255 caratteri. Nel caso in cui la validazione dovesse fallire, il nostro utente deve essere rimandato alla pagina principale con un messaggio extra di “spiegazioni”.
Route::post(‘/task’, function (Request $request) {
$validator = Validator::make($request->all(), [
‘name’ => ‘required|max:255’,
]);
if ($validator->fails()) {
return redirect(‘/’)
->withInput()
->withErrors($validator);
}
// Creiamo il task…
});
La Variabile $errors
Fermiamoci un secondo per parlare dell’istruzione ->withErrors($validator)
. Questa chiamata, infatti, mette in una sessione “flash” i dati ottenuti dalla procedura di validazione (gli errori, praticamente) in maniera tale da poter essere visti, nella view successiva, usando la variabile $errors
.
Ricordiamoci che poco fa abbiamo usato la direttiva @include('common.errors')
per renderizzare una view appositamente concepita per gli eventuali errori. Finalmente, è arrivato il momento di crearla (file resources/views/common/errors.blade.php
):
@if (count($errors) > 0)
-
@foreach ($errors->all() as $error)
- {{ $error }}
@endforeach
@endif
Nota: la variabile $errors
è disponibile in ogni view Laravel. Se non ci sono degli errori di validazione in sessione, tale variabile verrà “popolata” con un’istanza vuota della classe ViewErrorBag
.
Creazione del Task
Validata la nostra richiesta possiamo procedere con la creazione vera e propria. Dopo la creazione del task, che ovviamente avverrà facendo uso dei dati passati in POST, l’utente verrà reindirizzato alla schermata principale dell’applicazione. Per creare il task, fondamentalmente, creiamo una nuova istanza del model relativo, popolandone le proprietà e salvandola tramite save()
.
Così:
Route::post(‘/task’, function (Request $request) {
$validator = Validator::make($request->all(), [
‘name’ => ‘required|max:255’,
]);
if ($validator->fails()) {
return redirect(‘/’)
->withInput()
->withErrors($validator);
}
$task = new Task;
$task->name = $request->name;
$task->save();
return redirect(‘/’);
});
Voilà! Fine! Adesso puoi creare tutti i task che vuoi. Rimane solo da capire come visualizzarli! Direi che è arrivato il momento di costruire la nostra lista.
La Lista dei Task
Prima di tutto, dobbiamo tornare a modificare la nostra route /
, per fare in modo tale da passare, alla view che abbiamo creato in precedenza, l’insieme dei task già presenti. Come? Così:
Route::get(‘/’, function () {
$tasks = Task::orderBy(‘created_at’, ‘asc’)->get();
return view(‘tasks’, [
‘tasks’ => $tasks
]);
});
Una volta passati i dati, possiamo usare un qualsiasi ciclo in tasks.blade.php
per stamparli in una tabella. Il costrutto @foreach
di Blade permette agevolmente di fare una cosa del genere. In questo modo:
@extends(‘layouts.app’)
@section(‘content’)
@if (count($tasks) > 0)
@foreach ($tasks as $task)
@endforeach
Task | |
---|---|
{{ $task->name }}
|
@endif
@endsection
La nostra applicazione è quasi completa. Manca solo un’ultima cosa… la possibilità di cancellare un task una volta completato!
Cancellazione dei Task
Aggiungere il Tasto “Delete”
Poco fa abbiamo lasciato una nota “TODO” nel nostro codice, un segnaposto per indicare dove il pulsante di cancellazione dovrebbe trovarsi. Bene, andiamo a fare questa ultima sostituzione. Useremo un semplice pulsante per ogni task in lista. Una volta premuto, partirà una richiesta verso la route DELETE /task
.
Un Cenno sul Method Spoofing
Abbiamo appena visto che la richiesta viene mandata tramite un form per ogni task… ma il method usato è il POST! Nel caso tu non lo sapessi già, i form HTML supportano solo ed esclusivamente richieste GET e POST. Gli altri HTTP Verb, come DELETE appunto, non vengono contemplati. Tramite la funzione method_field
, tuttavia, è possibile scavalcare l’ostacolo e mandare a tutti gli effetti una richiesta che verrà, poi, riconosciuta da Laravel come DELETE e non POST.
Precisamente, Laravel controllerà il valore della variabile “speciale” _method
inviata nella richiesta.
Problema risolto!
Cancellazione del Task
A questo punto non rimane che creare la logica vera e propria di cancellazione del task desiderato. Per velocizzare il lavoro, possiamo usare una tecnica chiamata “implicit model binding”, che fa in modo, partendo dall’id di uno specifico task, di recuperare direttamente la relativa istanza e, quindi, di poterci lavorare agevolmente.
A questo punto, una volta cancellato il task, bisognerà reindirizzare l’utente verso la pagina principale, come al solito.
Route::delete(‘/task/{task}’, function (Task $task) {
$task->delete();
return redirect(‘/’);
});
Non è stato poi così difficile… vero?