Skip to content
Creare un manuale in linea per il backend Filament

Creare un manuale in linea per il backend Filament

By Pier Luigi Papeschi

Ogni applicazione che realizziamo in teoria… necessita di un manuale perché noi sappiamo bene cosa fa ogni pagina o parte della nostra creatura, ma chi andrà ad usarla forse no! Dicamo pure che in molti casi è proprio obbligatorio fornire un manuale utente, più o meno dettagliato.

Dato che amiamo realizzare app web con Laravel e FilamentPHP, vediamo come farne uno per chi userà questo backend.

Struttura

L’idea è creare una risorsa chiamata ManualPages che descriverà ogni pagina che l’utente userà. Poi creiamo un Trait di Laravel e lo facciamo usare ad ogni pagina. Questo trait consentirà di definire la chiave della pagina da descrivere e che in precedenza avevamo scritto e associato a qusta chiave in modo da aprire solo la pagina interessata. Ma forse è meglio vedere in pratica come si fa 😉

Model e Resource

Definiamo la struttura delle pagine del manuale creando il modello dei dati:

php artisan make:model ManualPage -m

e strutturiamo la migration in questo modo:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('manual_pages', function (Blueprint $table) {
            $table->id();
            $table->string('key')->nullable();
            $table->string('title');
            $table->string('slug')->unique();
            $table->unsignedInteger('sort')->default(0);
            $table->longText('content')->nullable();
            $table->boolean('is_published')->default(true);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('manual_pages');
    }
};

Lanciamo il comando per creare la tabella del database: php artisan migrate

e creiamo infine la risorsa Filament per scrivere le pagine:

php artisan make:filament-resource ManualPage

Mi raccomando di usare lo stesso nome del modello usato all’inizio.

La Trait

Adesso usiamo uno strumento di PHP che aumenta le potenzialità delle classi chiamato appunto Trait. In pratica questo strumento viene in soccorso ad un limite strutturale del PHP che consente ad una classe di estendere solo una classe genitore. Infatti un trait (che altro non è che una classe particolare) può essere usato in tutte le classi che vogliamo senza bisogno che queste la estendano, ma facendo sì che acquisiscano le proprietà e i metodi del trait.

Bene, creiamo il trait che ci interessa e che aggiungerà la possibilità di aprire l’aiuto in linea alle pagine della nostra app, questo il codice:

<?php

namespace App\Traits;

use App\Filament\Resources\ManualPages\ManualPageResource;
use App\Models\ManualPage;
use Filament\Actions\Action;
use Filament\Support\Icons\Heroicon;

trait HasHelpPage
{
  /**
   * Restituisce un'azione per il manuale, se esiste una pagina pubblicata con la chiave corrispondente.
   *
   * La chiave della pagina manuale viene definita nella classe che utilizza questo trait tramite la proprietà statica `$pageKey`.
   * Se non è definita o se non esiste una pagina pubblicata con quella chiave, restituisce null.
   *
   * @return Action|null
   */
  public static function getHelpAction(): ?Action
  {
    $key = static::$pageKey ?? null;

    if (! $key) {
      return null;
    }

    $page = ManualPage::where('key', $key)
      ->where('is_published', true)
      ->first();

    if (! $page) {
      return null;
    }

    return Action::make('help')
      ->label('Manuale')
      ->icon(Heroicon::OutlinedQuestionMarkCircle)
      ->url(ManualPageResource::getUrl('view', ['record' => $page->id]));
  }
}

Adesso dobbiamo aggiungerla alla classe che vogliamo abbia la pagina di manuale inserendo use \App\Traits\HasHelpPage;

all’apertura della classe stessa (per esempio ListProducts.php all’interno di app/Filament/Resources/Products/Pages). Poi all’interno del metodo che crea l’header della pagina posizioniamo il pulsante:

<?php

namespace App\Filament\Resources\Products\Pages;

use App\Filament\Resources\Products\CitizenResource;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;

class ListProducts extends ListRecords
{
    use \App\Traits\HasHelpPage;

    protected static string $resource = CitizenResource::class;
    protected static ?string $pageKey = 'products.index';

    protected function getHeaderActions(): array
    {
        return array_values(array_filter([
            CreateAction::make(),
            $this->getHelpAction(),
        ]));
    }
}

Andiamo a creare una pagina del manuale con esattamente la key “products.index” e vediamo che effetto fa…