Indice dei Contenuti
Filament di Laravel è un potente strumento che semplifica la creazione di pannelli di amministrazione eleganti e funzionali per le tue applicazioni web. Questa libreria PHP open-source ti permette di costruire interfacce amministrative complete in pochi minuti, risparmiando tempo prezioso nello sviluppo e permettendoti di concentrarti sulla logica di business della tua applicazione.
Requisiti
Filament richiede quanto segue per funzionare:
- PHP 8.1+
- Laravel v10.0+
- Livewire v3.0+
Installazione
Installa Filament eseguendo i seguenti comandi nella directory del tuo progetto Laravel:
composer require filament/filament:"^3.3" -W
php artisan filament:install --panels
Durante l’installazione ti verrà chiesto come chiamare il path di Filament, di base ti verrà proposto admin
.
Questo creerà e registrerà un nuovo service provider Laravel chiamato app/Providers/Filament/AdminPanelProvider.php
.
Creare un utente
Puoi creare un nuovo account utente con il seguente comando:
php artisan make:filament-user
Apri /admin
nel tuo browser web, accedi e inizia a costruire la tua applicazione!
Il concetto di Resource
In Filament, una “Resource” rappresenta un’entità del tuo database che desideri gestire attraverso il pannello di amministrazione. In pratica, è un insieme di classi PHP che definiscono come visualizzare, creare, modificare ed eliminare record di un modello specifico.
Ogni Resource in Filament può avere diversi componenti:
- List page: Mostra tutti i record in una tabella con funzionalità di ordinamento, filtro e ricerca.
- Create/Edit form: Interfacce per aggiungere o modificare i record con validazione.
- View page: Una visualizzazione dettagliata di un singolo record.
- Relation managers: Gestione delle relazioni tra modelli (uno-a-molti, molti-a-molti).
Creazione di una Resource
Per creare una Resource per il modello User, puoi utilizzare il comando:
php artisan make:filament-resource User
Questo comando genera diversi file nella directory app/Filament/Resources/UserResource
:
-
UserResource.php
: La classe principale che definisce le proprietà e i comportamenti della Resource. -
Pages/CreateUser.php
: Gestisce la creazione di nuovi utenti. -
Pages/EditUser.php
: Gestisce la modifica degli utenti esistenti. -
Pages/ListUsers.php
: Gestisce la visualizzazione di tutti gli utenti in una tabella. -
Pages/ViewUser.php
: Gestisce la visualizzazione dei dettagli di un singolo utente (solo se presente il parametro—view
).
Lanciare questo comando non includerà automaticamente tutti i campi del modello User.
Avrai un UserResource vuoto senza campi (form()
, table()
, infolist()
).
In Filament, una “Resource” rappresenta un’entità del tuo database che desideri gestire attraverso il pannello di amministrazione. In pratica, è un insieme di classi PHP che definiscono come visualizzare, creare, modificare ed eliminare record di un modello specifico.
Personalizzazione con parametri aggiuntivi
–simple (resources modali)
L’opzione --simple
è utilizzata quando i tuoi modelli sono abbastanza semplici da poter essere gestiti su una singola pagina, utilizzando finestre modali per creare, modificare ed eliminare i record:
php artisan make:filament-resource User --simple
Con questa opzione, la tua Resource avrà solo una pagina “Manage”, che è una pagina List con finestre modali aggiunte. Inoltre, la tua resource semplice non avrà il metodo getRelations()
, poiché i relation managers vengono visualizzati solo nelle pagine Edit e View, che non sono presenti nelle resource semplici. Tutto il resto rimane uguale.
–generate (generazione automatica di form e tabelle)
Se desideri risparmiare tempo, Filament può generare automaticamente il form e la tabella per te, basandosi sulle colonne del database del tuo modello:
php artisan make:filament-resource User --generate
Questa opzione analizza la struttura del database e crea automaticamente i campi del form e le colonne della tabella appropriate per il tuo modello.
–view (generazione della pagina View)
Per impostazione predefinita, vengono generate solo le pagine List, Create ed Edit per la tua Resource. Se desideri anche una pagina View per visualizzare i dettagli di un record senza possibilità di modifica, utilizza il flag --view
:
php artisan make:filament-resource User --view
Questi parametri possono essere combinati per personalizzare la tua Resource secondo le tue esigenze specifiche. Ad esempio:
php artisan make:filament-resource User --generate --view --simple
Dopo aver creato la Resource, potrai accedere alla gestione degli utenti tramite il percorso /admin/users
nel tuo pannello di amministrazione, dove troverai un’interfaccia completa per gestire gli utenti secondo le opzioni che hai specificato.
Implementazione di un CMS
Questo progetto necessita di tre modelli e migrazioni:
User
, Post
e Category
.
Usa i seguenti comandi artisan per crearli:
php artisan make:model Post -m
php artisan make:model Category -m
php artisan make:migration create_category_post_table
Definizione delle migrazioni
Utilizza i seguenti schemi di base per le migrazioni del database:
// create_posts_table
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('body');
$table->unisgnedBigInteger('user_id');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users');
});
// create_categories_table
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->boolean('is_active')->default('true');
$table->timestamps();
});
// create_treatments_table
Schema::create('category_post', function (Blueprint $table) {
$table->unisgnedBigInteger('post_id');
$table->unisgnedBigInteger('category_id');
$table->foreign('post_id')->references('id')->on('posts');
$table->foreign('category_id')->references('id')->on('categories');
$table->timestamps();
$table->primary(['post_id', 'category_id']);
});
Esegui le migrazioni con il comando php artisan migrate
.
Disabilitare la protezione dei modelli
Per brevità in questa guida, disabiliteremo la protezione da mass assignment di Laravel.
Filament salva solo dati validi nei modelli, quindi i modelli possono essere “unguarded” in sicurezza.
Per disabilitare la protezione per tutti i modelli Laravel contemporaneamente, aggiungi Model::unguard()
al metodo boot()
in app/Providers/AppServiceProvider.php
:
use Illuminate\Database\Eloquent\Model;
public function boot(): void
{
Model::unguard();
}
Configurazione delle relazioni tra i modelli
Definiamo le relazioni tra i modelli. Nel nostro sistema, i proprietari (owners) possono avere più animali domestici (patients), e i pazienti possono avere molti trattamenti (treatments):
Model: User
<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Relations\HasMany;
class User extends Authenticatable
{
/** @use HasFactory<\Database\Factories\UserFactory> */
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var list<string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var list<string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}
}
Model: Post
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Post extends Model
{
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function categories(): BelongsToMany
{
return $this->belongsToMany(Category::class)
->withTimestamps();
}
}
Model: Category
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Category extends Model
{
public function posts(): BelongsToMany
{
return $this->belongsToMany(Post::class)
->withTimestamps();
}
}
Crea le Resource relative
Usa il seguente comando artisan per creare una nuova risorsa Filament per il modello Post:
php artisan make:filament-resource Post
Questo creerà diversi file nella directory app/Filament/Resources
:
+-- PostResource.php
+-- PostResource
| +-- Pages
| | +-- CreatePost.php
| | +-- EditPost.php
| | +-- ListPosts.php
Visita /admin/posts
nel tuo browser e osserva un nuovo link chiamato “Posts” nella navigazione. Cliccando sul link verrà visualizzata una tabella vuota. Aggiungiamo un form per creare nuovi post.
Configurazione del form della risorsa
Se apri il file PostResource.php
, troverai un metodo form()
con un array vuoto schema([...])
.
Aggiungendo campi form a questo schema, costruirai un form che può essere utilizzato per creare e modificare nuovi post.
Campo di testo “Title” Filament include una vasta selezione di campi form. Iniziamo con un semplice campo di input testuale:
use Filament\Forms;
use Filament\Forms\Form;
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('title'),
]);
}
Visita /admin/posts/create
(o clicca sul pulsante “Nuovo Post”) e osserva che è stato aggiunto un campo form per il titolo del post.
Poiché questo campo è obbligatorio nel database e ha una lunghezza massima di 255 caratteri, aggiungiamo due regole di validazione al campo title:
use Filament\Forms;
Forms\Components\TextInput::make('title')
->required()
->maxLength(255)
Campo di testo “Body” Aggiungiamo un campo per il contenuto del post:
use Filament\Forms;
use Filament\Forms\Form;
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('title')
->required()
->maxLength(255),
Forms\Components\Textarea::make('body')
->required(),
]);
}
Selezione “User ID”
Dobbiamo aggiungere un utente quando creiamo un nuovo post. Poiché abbiamo aggiunto una relazione BelongsTo nel modello Post (associandolo al modello User correlato), possiamo utilizzare il metodo relationship()
dal campo select per caricare un elenco di utenti tra cui scegliere:
use Filament\Forms;
use Filament\Forms\Form;
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('title')
->required()
->maxLength(255),
Forms\Components\Textarea::make('body')
->required(),
Forms\Components\Select::make('user_id')
->relationship('user', 'name')
->required(),
]);
}
Rendiamo anche il campo utente obbligatorio, searchable()
e preload()
i primi 50 utenti nella lista ricercabile:
use Filament\Forms;
Forms\Components\Select::make('user_id')
->relationship('user', 'name')
->searchable()
->preload()
->required()
Selezione “Categories”
Aggiungiamo anche un campo per selezionare più categorie per il post utilizzando un campo CheckboxList
:
use Filament\Forms;
use Filament\Forms\Form;
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('title')
->required()
->maxLength(255),
Forms\Components\Textarea::make('body')
->required(),
Forms\Components\Select::make('user_id')
->relationship('user', 'name')
->searchable()
->preload()
->required(),
Forms\Components\CheckboxList::make('categories')
->relationship('categories', 'name')
->columns(2),
]);
}
Creazione di nuove categorie senza lasciare la pagina
Aggiungiamo un modo per creare nuove categorie direttamente dal form del post:
use Filament\Forms;
Forms\Components\Select::make('categories')
->multiple()
->relationship('categories', 'name')
->searchable()
->preload()
->createOptionForm([
Forms\Components\TextInput::make('name')
->required()
->maxLength(255),
Forms\Components\Toggle::make('is_active')
->label('Categoria attiva')
->default(true),
])
->required()
Configurazione della tabella dei post
Visita nuovamente la pagina /admin/posts
. Se hai creato un post, dovrebbe essere presente una riga vuota nella tabella con un pulsante di modifica. Aggiungiamo alcune colonne alla tabella per visualizzare i dati effettivi del post.
Aggiunta di colonne di testo
Filament include una vasta selezione di colonne per le tabelle. Utilizziamo semplici colonne di testo per tutti i campi nella tabella dei post:
use Filament\Tables;
use Filament\Tables\Table;
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('title'),
Tables\Columns\TextColumn::make('user.name'),
Tables\Columns\TextColumn::make('created_at'),
]);
}
Rendere le colonne ricercabili
La possibilità di cercare post direttamente nella tabella sarebbe utile. Puoi rendere le colonne ricercabili concatenando il metodo searchable()
alla colonna. Rendiamo ricercabili il titolo del post e il nome dell’utente:
use Filament\Tables;
use Filament\Tables\Table;
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('title')
->searchable(),
Tables\Columns\TextColumn::make('user.name')
->searchable(),
Tables\Columns\TextColumn::make('created_at'),
]);
}
Rendere le colonne ordinabili
Per rendere la tabella dei post ordinabile per data di creazione, aggiungiamo il metodo sortable()
alla colonna created_at
:
use Filament\Tables;
use Filament\Tables\Table;
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('title')
->searchable(),
Tables\Columns\TextColumn::make('user.name')
->searchable(),
Tables\Columns\TextColumn::make('created_at')
->sortable(),
]);
}
Filtrare la tabella per categoria
Filament include un filtro SelectFilter
precostruito che puoi aggiungere ai filtri della tabella:
use Filament\Tables;
use Filament\Tables\Table;
use Filament\Tables\Enums\FiltersLayout;
public static function table(Table $table): Table
{
return $table
->filtersLayout(FiltersLayout::AboveContent)
->filtersFormColumns(3)
->columns([
// ...
])
->filters([
Tables\Filters\SelectFilter::make('categories')
->relationship('categories', 'name'),
]);
}
Ricarica la pagina e dovresti vedere una nuova icona di filtro nell’angolo in alto a destra (accanto al form di ricerca). Il filtro apre un menu a discesa con un elenco delle categorie. Prova a filtrare i tuoi post per categoria.
Cosa sono i Relation Manager in Filament
Attualmente, i post possono essere associati con i loro utenti nel nostro sistema. Ma cosa succede se vogliamo un terzo livello? I post possono appartenere a diverse categorie, e il sistema dovrebbe essere in grado di registrare queste associazioni.
Una opzione è creare una nuova CategoryResource con un campo select per associare categorie ai post. Tuttavia, gestire le categorie separatamente dal resto delle informazioni del post è scomodo per l’utente.
Filament utilizza i “Relation Manager” per risolvere questo problema.
I relation manager sono tabelle che mostrano i record correlati a una risorsa esistente nella schermata di modifica della risorsa principale. Ad esempio, nel nostro progetto, potresti visualizzare e gestire le categorie di un post direttamente sotto il form di modifica.
Puoi anche utilizzare le ACTIONS di Filament per aprire un form modale per creare, modificare ed eliminare categorie direttamente dalla tabella dei post.
Usa il comando artisan make:filament-relation-manager
per creare rapidamente un relation manager, collegando la risorsa post alle categorie correlate:
php artisan make:filament-relation-manager PostResource categories name
-
PostResource
è il nome della classe resource per il modello post. Poiché le categorie appartengono ai post, le categorie dovrebbero essere visualizzate nella pagina Edit Post. -
categories
è il nome della relazione nel modello Post che abbiamo creato in precedenza. -
name
è la colonna da visualizzare dalla tabella categories.
Questo creerà un file PostResource/RelationManagers/CategoriesRelationManager.php
.
Devi registrare il nuovo relation manager nel metodo getRelations()
del PostResource:
use App\Filament\Resources\PostResource\RelationManagers;
public static function getRelations(): array
{
return [
RelationManagers\CategoriesRelationManager::class,
];
}
Il file CategoriesRelationManager.php
contiene una classe che è precompilata con un form e una tabella utilizzando i parametri del comando artisan make:filament-relation-manager
. Puoi personalizzare i campi e le colonne nel relation manager in modo simile a come faresti in una risorsa:
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Tables;
use Filament\Tables\Table;
public function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name')
->required()
->maxLength(255),
]);
}
public function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('name'),
]);
}
Visita la pagina Edit per uno dei tuoi post. Dovresti già essere in grado di creare, modificare, eliminare ed elencare categorie per quel post.
Configurazione del form delle categorie
Per impostazione predefinita, i campi di testo coprono solo metà della larghezza del form. Aggiungiamo il campo is_active
, che può essere utilizzato per attivare o disattivare una categoria. Possiamo usare un campo toggle:
use Filament\Forms;
use Filament\Forms\Form;
public function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name')
->required()
->maxLength(255)
->columnSpan('full'),
Forms\Components\Toggle::make('is_active')
->label('Categoria attiva')
->default(true),
]);
}
Configurazione della tabella delle categorie
Quando il relation manager è stato generato in precedenza, la colonna di testo name
è stata aggiunta automaticamente. Aggiungiamo anche una colonna per lo stato di attivazione:
use Filament\Tables;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('name'),
Tables\Columns\IconColumn::make('is_active')
->boolean()
->sortable(),
]);
}
Aggiungiamo anche una colonna per indicare quando è stata creata la categoria utilizzando il timestamp created_at
predefinito. Usa il metodo dateTime()
per visualizzare la data e l’ora in un formato leggibile:
use Filament\Tables;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('name'),
Tables\Columns\IconColumn::make('is_active')
->boolean()
->sortable(),
Tables\Columns\TextColumn::make('created_at')
->dateTime(),
]);
}
Puoi passare qualsiasi stringa di formattazione della data PHP valida al metodo dateTime()
(ad esempio dateTime('d-m-Y H:i')
).
Introduzione ai widget
I widget di Filament sono componenti che visualizzano informazioni sulla tua dashboard, in particolare statistiche. I widget vengono in genere aggiunti alla Dashboard predefinita del pannello, ma puoi aggiungerli a qualsiasi pagina, incluse le pagine delle risorse. Filament include widget integrati come il widget stats, per visualizzare statistiche importanti in una semplice panoramica; widget chart, che può rendere un grafico interattivo; e widget table, che ti consente di incorporare facilmente il Table Builder.
Aggiungiamo un widget stats alla nostra pagina della dashboard predefinita che include una statistica per ogni tipo di post e un grafico per visualizzare le categorie nel tempo.
Creazione di un widget stats
Crea un widget stats per visualizzare le statistiche dei post utilizzando il seguente comando artisan:
php artisan make:filament-widget PostOverview --stats-overview
Quando richiesto, non specificare una risorsa e seleziona “admin” per la posizione.
Questo creerà un nuovo file app/Filament/Widgets/PostOverview.php
.
Aprilo e restituisci le istanze Stat dal metodo getStats()
:
<?php
namespace App\Filament\Widgets;
use App\Models\Post;
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;
class PostOverview extends BaseWidget
{
protected function getStats(): array
{
return [
Stat::make('Totale Post', Post::query()->count()),
Stat::make('Post oggi', Post::query()->whereDate('created_at', today())->count()),
Stat::make('Post mese', Post::query()->whereMonth('created_at', now()->month)->count()),
];
}
}
Apri la tua dashboard e dovresti vedere il tuo nuovo widget visualizzato. Ogni statistica dovrebbe mostrare il numero totale di post per il periodo specificato.
Creazione di un widget chart
Aggiungiamo un grafico alla dashboard per visualizzare il numero di post creati nel tempo. Utilizza il seguente comando artisan per creare un nuovo widget chart:
php artisan make:filament-widget PostsChart --chart
Apri app/Filament/Widgets/PostsChart.php
e imposta l’$heading
del grafico su “Posts”.
Il metodo getData()
restituisce un array di dataset ed etichette.
Ogni dataset è un array etichettato di punti da tracciare sul grafico, e ogni etichetta è una stringa. Questa struttura è identica alla libreria Chart.js, che Filament utilizza per renderizzare i grafici.
Per popolare i dati del grafico da un modello Eloquent, Filament consiglia di installare il pacchetto flowframe/laravel-trend
:
composer require flowframe/laravel-trend
Aggiorna getData()
per visualizzare il numero di post per mese nell’ultimo anno:
use App\Models\Post;
use Flowframe\Trend\Trend;
use Flowframe\Trend\TrendValue;
protected function getData(): array
{
$data = Trend::model(Post::class)
->between(
start: now()->subYear(),
end: now(),
)
->perMonth()
->count();
return [
'datasets' => [
[
'label' => 'Posts',
'data' => $data->map(fn (TrendValue $value) => $value->aggregate),
],
],
'labels' => $data->map(fn (TrendValue $value) => $value->date),
];
}
Ora, dai un’occhiata al tuo nuovo widget chart nella dashboard!
Puoi personalizzare la tua pagina dashboard per modificare la griglia e il numero di widget visualizzati.