Laravel 11

Albums – Les catégories

Dans ce chapitre, nous allons poursuivre le développement de notre galerie de photos en nous concentrant sur la gestion des catégories. Pour organiser efficacement les photos de la galerie, nous les avons classées en catégories. Seul l’administrateur a les droits de créer, modifier ou supprimer une catégorie.

Nous aborderons dans ce chapitre la création d’une catégorie, ce qui implique plusieurs étapes :

  • mise à jour du menu de navigation : il faudra ajouter des options de menu pour l’administration des catégories. Ces options ne seront visibles que pour les utilisateurs connectés ayant le rôle d’administrateur
  • création de formulaires : nous créerons des formulaires simples qui permettront à l’administrateur d’ajouter une nouvelle catégorie en saisissant un nom et un autre pour la modification du nom d’une catégorie existante
  • définition des routes : nous devrons mettre en place des routes pour accéder à la page de gestion des catégories, ainsi que pour soumettre le formulaire de création d’une catégorie
  • création de composants : nous créerons des composants pour gérer la logique de création et de mise à jour des catégories, ainsi que la suppression. Ces composants traiteront les données des formulaires et interagiront avec la base de données pour enregistrer les modifications

En suivant les étapes décrites, nous pourrons créer une interface conviviale et efficace pour la gestion des catégories dans notre galerie de photos.

Un middleware

Pour vérifier qu’on a affaire à un administrateur, le plus simple est de créer un middleware :

php artisan make:middleware Admin

Changez ainsi le code :

...

public function handle(Request $request, Closure $next): Response
{
    $user = $request->user();
    if(!$user || !$user->admin) {
        redirect('home');
    }
    return $next($request);
}

Si c’est un administrateur, on continue, sinon on renvoie sur la page d’accueil.

Pour en profiter facilement dans les vues, on ajoute une directive à Blade dans AppServiceProvider :

public function boot(): void
{
    Blade::if('admin', function () {
        return auth()->check() && auth()->user()->admin;
    });
    
    ...
}

Création d’une catégorie

La première action à prévoir est celle de la création d’une catégorie. On va avoir besoin d’un formulaire pour entrer le nom de notre nouvelle catégorie. Le slug sera généré automatiquement à partir du nom.

On commence par créer un composant Volt pour cette création :

php artisan make:volt categories/create --class

Et on prévoit ce code :

<?php

use Livewire\Volt\Component;

use App\Models\Category;
use Mary\Traits\Toast;
use Illuminate\Support\Str;
use Livewire\Attributes\Rule;

new class extends Component {

    use Toast;
    
    #[Rule('required|string|max:255|unique:categories,name')]
    public string $name = '';

    public function save(): void
    {
        $data = $this->validate();    
        $data['slug'] = Str::of($this->name)->slug('-');        
        Category::create($data);    
        $this->success(__('Category created with success.'), redirectTo: '/categories');
    }
}; ?>

<div>
    <x-card class="h-screen flex items-center justify-center" title="{{__('Create a new category')}}">
 
        <x-form wire:submit="save"> 
            <x-input label="{{__('Name')}}" name="Name" wire:model="name" />     
            <x-slot:actions>
                <x-button label="{{__('Cancel')}}" link="/categories" />
                <x-button label="{{__('Save')}}" icon="o-paper-airplane" spinner="save" type="submit" class="btn-primary" />
            </x-slot:actions>
        </x-form>

    </x-card>
</div>

Et deux traductions :

"Create a new category": "Créer une nouvelle catégorie",
"Category created with success.": "La catégorie a bien été ajoutée"

Et la route :

use App\Http\Middleware\Admin;

Route::middleware(Admin::class)->group(function () {
    Volt::route('categories/create', 'categories.create')->name('categories.create');
});

Attention où vous placez cette route dans votre fichier ! Par exemple si vous la placez après celle-ci :

Volt::route('/{category}/{param?}', 'index')->name('home');

Vous vous rendez compte facilement qu’on va avoir un souci ! Il faut toujours être très attentif à l’ordre des routes !

Vérifier que tout fonctionne correctement.

Gérer les catégories

Maintenant qu’on sait créer des catégories, on va prévoir le code pour les gérer et dans un premier temps en afficher la liste et permettre une suppression. On crée un nouveau composant :

php artisan make:volt categories/index --class

Avec ce code :

<?php

use Livewire\Volt\Component;
use App\Models\Category;

new class extends Component {

    public function headers(): array
    {
        return [
            ['key' => 'name', 'label' => __('Name')],
            ['key' => 'slug', 'label' => 'Slug'],
            ['key' => 'images_count', 'label' => __('Images count')],
        ];
    }

    public function delete($id): void
    {
        Category::destroy($id);
    }

    public function with(): array
    {
        return [
            'categories' => Category::withCount('images')->get(),
            'headers' => $this->headers()
        ];
    }

}; ?>

<div>
    <x-header title="{{__('Categories')}}" separator progress-indicator />
    <x-card>
        <x-table :headers="$headers" :rows="$categories" link="categories/{id}/edit">
            @scope('actions', $category)
                <x-button icon="o-trash" wire:click="delete({{ $category->id }})" wire:confirm="{{__('Are you sure to delete this category?')}}" spinner class="btn-sm" />
            @endscope
        </x-table>
    </x-card>
</div>

Il ne reste plus qu’à ajouter la route :

Route::middleware(Admin::class)->group(function () {
    Volt::route('categories', 'categories.index')->name('categories.index');
    ...
});

Et ajouter deux traductions :

"Are you sure to delete this category?": "Voulez-vous vraiment supprimer cette catégorie ?",
"Images count": "Nombre d'images"

J’ai prévu l’information du nombre d’images par catégorie qui peut être pertinente.

J’apprécie particulièrement la facilité pour créer des tableaux avec MaryUi.

Le menu

Il ne nous manque plus que les liens dans le menu :

@if($user = auth()->user())
    <x-menu-separator />
        ...
        @admin
            <x-menu-sub title="{{__('Administration')}}" icon="o-cog-6-tooth">
                <x-menu-item title="{{__('Manage categories')}}" icon="o-tag" link="{{ route('categories.index') }}" />
                <x-menu-item title="{{__('Add a category')}}" icon="o-plus-circle" link="{{ route('categories.create') }}" />
            </x-menu-sub>            
        @endadmin
    <x-menu-separator />
@else

Deux traductions :

"Manage categories": "Gestion des catégories",
"Add a category": "Ajouter une catégorie"

Et c’est bon :

Modifier une catégorie

La dernière action à prévoir est la modification d’une catégorie, en fait la modification de son nom. On crée un nouveau composant :

php artisan make:volt categories/edit --class

On ajoute le code :

<?php

use Livewire\Volt\Component;

use App\Models\Category;
use Illuminate\Validation\Rule;
use Mary\Traits\Toast;

new class extends Component 
{
    use Toast;
    
    Public Category $category;
    public string $name = '';

    public function mount(): void
    {
        $this->fill($this->category);
    }

    public function save(): void
    {
        $data = $this->validate([
            'name' => [
                'required','string', 'max:255',
                Rule::unique('categories')->ignore($this->category->id),
            ]
        ]);

        $data['slug'] = Str::of($this->name)->slug('-');
    
        $this->category->update($data);
    
        $this->success(__('Category updated with success.'), redirectTo: '/categories');
    }

}; ?>

<div>
    <x-card class="h-screen flex items-center justify-center" title="{{__('Update')}} {{ $category->name }}">
        <x-form wire:submit="save"> 
            <x-input label="{{__('Name')}}" name="Name" wire:model="name" /> 
            <x-slot:actions>
                <x-button label="{{__('Cancel')}}" link="/categories" />
                <x-button label="{{__('Save')}}" icon="o-paper-airplane" spinner="save" type="submit" class="btn-primary" />
            </x-slot:actions>
        </x-form>
    </x-card>
</div>

Et la route :

Route::middleware(Admin::class)->group(function () {
    ..
    Volt::route('categories/{category}/edit', 'categories.edit')->name('categories.edit');
});

Le formulaire est accessible avec un clic dans le tableau des catégories :

On ajoute une traduction :

"Category updated with success.": "La catégorie a bien été modifiée"

Et ça devrait fonctionner…

Conclusions

Dans cet article, nous avons :

  • créé un middleware pour filtrer les administrateurs et ajouté une directive Blade
  • créé un composant, un formulaire, un lien dans le menu et le traitement de l’ajout d’une catégorie
  • créé un composant pour l’affichage du tableau des catégories avec un lien dans le menu
  • créé un composant, un formulaire et le traitement de la modification d’une catégorie

Pour vous simplifier la vie, vous pouvez charger le projet dans son état à l’issue de ce chapitre.

Print Friendly, PDF & Email

2 commentaires

  • GrCOTE7

    Bonjour,

    Je relève une erreur…:

    « J’apprécie particulièrement la facilité pour créer des tableaux avec MaryUi. »

    À moins que cela ne soit une figure de style appelée ‘litote’… 😉 … ?

    En si peu de code, une fois les bonnes bases posées (Relations entre les ‘models’, les quelques fichiers ‘anciens contrôleur + vues’, et au final le « si peu de code » pour un tel rendu qui s’avère esthétique, réactif et dynamique….

    C’est Géant ! Encore merci pour cette énième leçon sur Laravel et maintenant, « accouplé » à Livewire – Mary-ui et DaisyUI, qui permet de vraiment comprendre qu’il y a là, matière à générer aisément une app multilingue, dynamique, agréable visuellement, et également aussi point de vue UX (User experiment – Expérience utilisateur)…

    Donc, merci encore BestMomo, et ayant tout hâte de découvrir la suite :-)…

    @++

    • bestmomo

      Salut !

      Je prends souvent des raccourcis pour économiser mon clavier. J’aurais pu écrire « J’apprécie particulièrement la facilité avec laquelle il est possible de créer des tableaux avec MaryUI ». Mais c’est plus joli en version brève ????

      Je suis d’accord pour l’intérêt de cette nouvelle façon de coder avec Laravel, je n’en suis qu’à mes débuts dans cette exploration.

      Pour la suite je ne sais pas encore…

      @++

Laisser un commentaire