Laravel

Un framework qui rend heureux

Voir cette catégorie
Vers le bas
Albums – Les catégories
Dimanche 7 avril 2024 18:04

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.


Par bestmomo

Nombre de commentaires : 2