Photo by Carlos Muza on Unsplash
Hai passato le ultime X ore a costruire un sistema molto complesso, con tante interazioni e funzionalità complicate, hai scritto i test e ora tutto funziona. Ma non hai una Dashboard da cui monitorare i dettagli del tuo sistema ed eseguire operazioni CRUD sui suoi modelli, e non vuoi perdere troppo tempo a mettere in piedi una dashboard che non ti serve direttamente o che non userai direttamente, quindi?
Questo è, in breve, ciò che mi è capitato qualche giorno fa. Voglio darti un po' di contesto senza condizionare la tua opinione sull'intera idea di questo articolo. Dovevo costruire un sistema complesso in cui puoi eseguire una sola operazione, il sistema ha una sola funzionalità complessa: l'utente deve caricare dei file, scegliere una configurazione, inserire la sua email (sì, l'utente non ha login) e poi consegnare tutto al server che accoda un job; questo job lavora in background eseguendo ciò che deve fare e infine invia una email. È stato un sistema bellissimo da programmare (se ti piace programmare 💻 come a me), ho dovuto incollare Laravel con alcuni script bash, ho scritto i test, ho controllato le falle di sicurezza, ma... e se i manager volessero vedere lo stato attuale dei job e cosa fanno gli utenti? E ho iniziato a cercare il modo più veloce per costruire una bella dashboard con operazioni CRUD, con il minor codice da scrivere e il miglior risultato possibile, ed eccolo qui InfyOmLabs Laravel Generator!
🔧 Configurare tutto
Partirò da un progetto esistente, ma tutto ciò che vedi qui può essere replicato facilmente in qualunque progetto, anche uno nuovo.
Come detto prima, nel mio progetto non ho nessun modello utente (perché non ho login), quindi partirò dalla sua migration. Puoi tranquillamente prendere la migration integrata di Laravel e creare un utente programmaticamente via tinker o in qualche altro modo, metto il codice per tinker:
User::create([
'name' => 'Kalizi',
'email' => '****@******.***',
'password' => \Hash::make('myBeautifulPassword'),
]);
Ora siamo pronti a costruire la dashboard con il generator, dobbiamo partire da composer.json :
"require": {
// Your dependencies
"infyomlabs/laravel-generator": "8.0.x-dev",
"laravelcollective/html": "^6.2",
"infyomlabs/adminlte-templates": "8.0.x-dev",
"doctrine/dbal": "~2.3",
"yajra/laravel-datatables": "^1.5",
"yajra/laravel-datatables-buttons": "^4.10",
"yajra/laravel-datatables-oracle": "~9.0"
},
Con questi package aggiungerai il generator, il generator HTML, adminlte-template per la dashboard, dbal per leggere gli schemi dal database e usarli nella generazione, i package yajra datatables per la generazione delle jQuery datatables e per rendere semplici le interazioni con il server. Se preferisci, puoi passare al template CoreUI usando "infyomlabs/coreui-templates": "8.0.x-dev" (al posto di adminlte). Ora basta un composer update .
Ora pubblica la config con php artisan vendor:publish --provider="InfyOm\Generator\InfyOmGeneratorServiceProvider" e siamo pronti!
Ora modifica config/infyom/laravel_generator.php editando:
path: se vuoi mettere ogni contenuto generato in una cartella specifica, nel mio caso volevo tutto sotto una cartellaadmin, quindi ho aggiunto/admincome cartella dove necessario (views). Questo è particolarmente utile se vuoi separare la roba dell'admin dal codice del tuo sistema.'templates' => 'your_template_here': puoi mettereadminlte-templatesocoreui-templates.'repository_pattern' => falsenella chiave options, il pattern repository non mi piace molto, ma puoi tenerlo se preferisci'prefixes' => [ 'route' => 'admin', 'path' => 'admin', 'views' => '', 'public' => '' ]questo aggiungerà ogni route comeadmin.?nel path/admin.'datatables' => truese vuoi abilitare le datatables, personalmente le adoro.'tests' => falseè un generator e non farò modifiche particolari sui file generati, quindi non ho davvero bisogno dei test (sta a te decidere).
Ultimo ma non meno importante, dobbiamo pubblicare i file di default di infyom per la generazione con php artisan infyom:publish e con php artisan infyom.publish:layout (quest'ultimo comando genererà le views anche per l'autenticazione, se le hai già, chiederà se sovrascriverle). Se vuoi usare le datatables (con server-side rendering), devi anche pubblicare la roba delle datatables eseguendo php artisan vendor:publish --tag='datatables-button'.
Ora siamo pronti!
✏️ Il nostro primo CRUD️
Photo by Galymzhan Abdugalimov on Unsplash
InfyOm è pronto e ora possiamo generare il nostro CRUD via artisan, come? Vediamo quali comandi possiamo eseguire lanciando php artisan:
infyom
infyom:api Create a full CRUD API for given model
infyom:api_scaffold Create a full CRUD API and Scaffold for given model
infyom:migration Create migration command
infyom:model Create model command
infyom:publish Publishes & init api routes, base controller, base test cases traits.
infyom:repository Create repository command
infyom:rollback Rollback a full CRUD API and Scaffold for given model
infyom:scaffold Create a full CRUD views for given model
infyom.api
infyom.api:controller Create an api controller command
infyom.api:requests Create an api request command
infyom.api:tests Create tests command
infyom.publish
infyom.publish:layout Publishes auth files
infyom.publish:templates Publishes api generator templates.
infyom.publish:user Publishes Users CRUD file
infyom.scaffold
infyom.scaffold:controller Create controller command
infyom.scaffold:requests Create a full CRUD views for given model
infyom.scaffold:views Create views file command
Abbiamo tanti comandi che possiamo lanciare, e ogni comando ha tante opzioni. Non mi serve tutto, quindi mi concentrerò sul comando scaffold e approfondiremo le sue opzioni lanciando php artisan infyom:scaffold --help (ometterò le opzioni di default di Laravel come --help o -v|vv|vvv e mi concentrerò solo sulle opzioni del generator)
Description:
Create a full CRUD views for given model
Usage:
infyom:scaffold [options] [--] <model>
Arguments:
model Singular Model name
Options:
--fieldsFile=FIELDSFILE Fields input as json file
--jsonFromGUI=JSONFROMGUI Direct Json string while using GUI interface
--plural=PLURAL Plural Model name
--tableName=TABLENAME Table Name
--fromTable Generate from existing table
--ignoreFields=IGNOREFIELDS Ignore fields while generating from table
--save Save model schema to file
--primary=PRIMARY Custom primary key
--prefix=PREFIX Prefix for all files
--paginate=PAGINATE Pagination for index.blade.php
--skip=SKIP Skip Specific Items to Generate (migration,model,controllers,api_controller,scaffold_controller,repository,requests,api_requests,scaffold_requests,routes,api_routes,scaffold_routes,views,tests,menu,dump-autoload)
--datatables=DATATABLES Override datatables settings
--views=VIEWS Specify only the views you want generated: index,create,edit,show
--relations Specify if you want to pass relationships for fields
--softDelete Soft Delete Option
--forceMigrate Specify if you want to run migration or not
--factory To generate factory
--seeder To generate seeder
--localized Localize files.
--repositoryPattern=REPOSITORYPATTERN Repository Pattern
--connection=CONNECTION Specify connection name
Come puoi vedere, ci sono molte opzioni che puoi regolare e sfruttare per ottenere un CRUD il più velocemente possibile.
Ora devi concentrarti sul tuo database, il nome del mio modello è ProcessingSession (nome tabella: processing_sessions) che ha una relazione one-to-many con ProcessingFile (nome tabella: processing_files). Il comando che ho usato per impostare il primo CRUD è:
php artisan infyom:scaffold --fromTable --tableName=processing_sessions --factory --seeder --skip=model ProcessingSession
Dai un'occhiata a ogni opzione:
--fromTable --tableName=processing_sessionsqueste opzioni servono per ottenere i dati del modello dal database. Usando dbal, questo recupererà la struttura della tabella dal database e userà ogni dettaglio della struttura per la generazione.--factorygenererà una factory per il modello.--seedergenererà un seeder per il modello.--skip=modelquesto serve se hai già la tua implementazione del modello, se non hai nessun modello nel tuo progetto, questo genererà un file Model per la tua tabella.
L'output sarà qualcosa del genere:
Factory created:
ProcessingSessionFactory.php
Seeder created:
ProcessingSessionsTableSeeder.php
Create Request created:
CreateProcessingSessionRequest.php
Update Request created:
UpdateProcessingSessionRequest.php
DataTable created:
ProcessingSessionDataTable.php
Controller created:
ProcessingSessionController.php
Generating Views...
datatables_actions.blade.php created
table.blade.php created
index.blade.php created
field.blade.php created
create.blade.php created
edit.blade.php created
show_fields.blade.php created
show.blade.php created
Views created.
processingSessions routes added.
processingSessions menu added.
Schema File saved:
ProcessingSession.json
Generating autoload files
Cosa è successo dopo questo comando? Guarda le modifiche ai file:
New:
app/Http/Controllers/Admin/ProcessingSessionController.php
app/Http/Requests/Admin/CreateProcessingSessionRequest.php
app/Http/Requests/Admin/UpdateProcessingSessionRequest.php
database/factories/ProcessingSessionFactory.php
database/seeders/ProcessingSessionTableSeeder.php
resources/views/admin/processing_sessions/*.blade.php
Changed:
routes/web.php
InfyOm si limita a pubblicare la roba, non aggiunge il controllo dell'utente, quindi dobbiamo costruire un Middleware php artisan make:middleware AdminMiddleware e aggiungere la logica che preferisci.
Ora apri routes/web.php, sistema il Controller generato (se non funziona) e aggiungi il middleware:
use App\Http\Controllers\Admin\ProcessingSessionController;
Route::group(
[
'prefix' => 'admin',
'as' => 'admin.',
'middleware' => \App\Http\Middleware\AdminMiddleware::class
],
function () {
Route::resource('processingSessions', ProcessingSessionController::class);
}
);
Ci servono ancora due ritocchi, apri il Controller, le Requests e la DataTable e correggi gli import del modello da App\Models\Admin\Model a App\Models\Model o a qualunque sia il namespace del tuo modello. L'altro è aggiungere le regole di validazione nel tuo modello come proprietà statica. Se guardi le tue classi request puoi vedere che nei metodi rules() InfyOm usa la proprietà statica Model::$rules che devi aggiungere al tuo modello.
E siamo pronti, se l'autenticazione funziona, puoi aprire admin/processingSessions ed ecco il CRUD!
CRUD di base costruito con InfyOm, pronto per la personalizzazione
Ogni altro crud sarà più o meno lo stesso. Ogni volta che generi un CRUD avrai i seguenti file:
┌── create.blade.php
├── datatables_actions.blade.php
├── edit.blade.php
├── fields.blade.php
├── index.blade.php
├── show.blade.php
├── show_fields.blade.php
└── table.blade.php
Se vuoi modificare un qualsiasi passo del processo CRUD, dovrai editare il file relativo (se vuoi mostrare le relazioni puoi modificare show.blade.php inserendo i loro modelli iniettandoli dal controller, se usi le relazioni di default di Eloquent puoi farlo facilmente).
Attenzione: il file fields.blade.php è condiviso tra i passi Create e Update, usa la facade Form che inietterà automaticamente il modello. Nel passo Create però il modello non è definito, quindi se modifichi il file fai attenzione a non combinare guai usando l'istanza del modello senza che sia impostata e inizializzata, usando un semplice isset($modelName).
🧱 Costruire una dashboard
Il tuo template adminlte è già configurato, devi solo costruire una view per sfruttarlo. Parti con una view in views/admin/index.php che estende views/layouts/app.blade.php e sovrascrive la sezione content.
Dopodiché, costruisci un Controller per gestirla php artisan make:controller Admin\DashboardController con una funzione index che renderizza la view precedente, da collegare a una route sotto il gruppo che abbiamo creato prima.
use App\Http\Controllers\Admin\DashboardController;
Route::group(
[
'prefix' => 'admin',
'as' => 'admin.',
'middleware' => \App\Http\Middleware\AdminMiddleware::class
],
function () {
Route::get('/', [DashboardController::class, 'index'])->name('index');
// ... your other CRUDs
}
);
Dovresti vedere una dashboard vuota:
Costruire la tua dashboard
Vogliamo modificare un paio di cose, apri views/layouts/app.blade.php, sostituisci il "logo InfyOm" con il tuo e con l'URL base dell'admin
<a href="{!! route('admin.index') !!}" class="logo">
<img src="{!! asset('/img/your_logo.png') !!}" alt="Your Project Dashboard" />
</a>
Scorri fino al footer e modifica la sezione "Copyright"
<footer class="main-footer" style="max-height: 100px;text-align: center">
<strong>Copyright © 2020 <a href="{!! url('/') !!}">Project</a>.</strong> All rights reserved.
</footer>
Tutto ciò che devi fare ora è comporre la tua dashboard usando i componenti AdminLTE dalla documentazione ufficiale, Laravel e i Blade Components.
🧠Vuoi di più?
Dai un'occhiata alle dipendenze di AdminLTE e importa i plugin nel tuo views/layouts/app.blade.php. Vuoi essere ancora più veloce? Puoi dare un'occhiata ad altri package di supporto come questo helper per Chart.js. Tutto ciò che devi fare è sfruttare la potenza di Laravel in combinazione con questo generator!
E questo è tutto! ✌🏻