Laravel 11

Sillo – la page d’accueil

Après avoir examiné les données et les layouts, considérons à présent la page d’accueil du site. Cette page doit présenter un résumé des derniers articles publiés. Il est important de pouvoir afficher ces articles par catégorie et par série, et d’inclure une fonction de pagination pour une navigation efficace. Toutes ces fonctionnalités nécessitent une gestion des données et une organisation de l’affichage.

Pour organiser l’affichage des articles sur la page d’accueil, nous devons mettre en place les éléments suivants :
  1. Résumé des articles récents : La page d’accueil doit présenter un aperçu des articles récemment publiés, en incluant des informations telles que le titre, la date de publication, l’auteur et une courte description.
  2. Filtres par catégorie et par série : Permettre aux utilisateurs de naviguer entre les catégories et les séries d’articles pour accéder à du contenu plus spécifique et personnalisé.
  3. Pagination : Intégrer une fonction de pagination pour une meilleure navigation sur le site, en divisant les articles en pages plus courtes et plus maniables pour les utilisateurs.
Pour gérer ces exigences, nous utilisons Laravel Eloquent pour interagir avec la base de données et récupérer les articles en fonction des critères souhaités. Ensuite, nous créons des vues Livewire pour afficher les articles de manière structurée et interactive, en intégrant les filtres et la pagination.
En suivant ces étapes, nous obtenons une page d’accueil fonctionnelle et conviviale pour nos utilisateurs. Elle leur permet de trouver facilement les articles qui les intéressent, ce qui favorise l’engagement et la satisfaction des visiteurs du blog.
La page d’accueil est gérée par ce composant :

Les routes

On a ces 4 routes pour afficher la page d’accueil avec ses filtres (catégorie, série, recherche) :

Volt::route('/', 'index');
Volt::route('/category/{slug}', 'index');
Volt::route('/serie/{slug}', 'index');
Volt::route('/search/{param}', 'index')->name('posts.search');
  • Volt::route('/', 'index') :
    • Cette route correspond à la racine de l’application, c’est-à-dire le point d’entrée principal.
    • Lorsque l’utilisateur accède à la racine de l’application, le composant Livewire nommé index sera rendu.
    • Cela correspond à la page d’accueil de l’application.
  • Volt::route('/category/{slug}', 'index') :
    • Cette route correspond à une catégorie spécifique dans l’application.
    • Le paramètre {slug} est un segment d’URL dynamique qui représente le slug de la catégorie.
    • Lorsque l’utilisateur accède à une URL correspondant à cette structure, le composant Livewire index sera rendu, en affichant les articles de cette catégorie.
  • Volt::route('/serie/{slug}', 'index') :
    • Cette route est similaire à la précédente, mais elle correspond à une série spécifique dans l’application.
    • Le paramètre {slug} est un segment d’URL dynamique qui représente le slug de la série.
    • Lorsque l’utilisateur accède à une URL correspondant à cette structure, le composant Livewire index sera rendu, en affichant les séries de cette catégorie.
  • Volt::route('/search/{param}', 'index')->name('posts.search') :
    • Cette route correspond à une fonctionnalité de recherche dans l’application.
    • Le paramètre {param} est un segment d’URL dynamique qui représente le terme de recherche saisi par l’utilisateur.
    • Lorsque l’utilisateur effectue une recherche, le composant Livewire index sera rendu avec le terme de recherche spécifié et donc afficher les articles correspondants.
    • De plus, cette route est nommée posts.search, ce qui signifie qu’elle peut être référencée dans le code pour générer des URL vers cette fonction de recherche.

Le composant index

Les propriétés

Ce composant possède 4 propriétés :

// Propriétés de la classe
public string $slug = ''; // Slug pour identifier une catégorie ou une série
public string $param = ''; // Paramètre de recherche optionnel
public ?Category $category = null; // Catégorie actuelle (ou null si aucune)
public ?Serie $serie = null; // Série actuelle (ou null si aucune)

Voici ce que chacune de ces propriétés représente :

  1. $slug :
    • Cette propriété est une chaîne de caractères qui stocke le slug d’une catégorie ou d’une série.
    • Le slug est utilisé pour identifier de manière unique une entité.
    • Par exemple, dans l’URL /category/ma-categorie, « ma-categorie » est le slug de la catégorie.
  2. $param :
    • Cette propriété est une chaîne de caractères qui stocke un paramètre de recherche optionnel.
    • Elle est utilisée pour stocker un terme de recherche saisi par l’utilisateur lorsqu’il effectue une recherche dans l’application.
    • Ce paramètre est utilisé pour filtrer les résultats de recherche ou pour afficher des contenus pertinents.
  3. $category :
    • Cette propriété est une instance de la classe Category ou null si aucune catégorie n’est actuellement sélectionnée.
    • Elle est utilisée pour stocker la catégorie actuellement sélectionnée si on a utilisé la route pour les catégories.
    • Si une catégorie est sélectionnée, cette propriété contiendra le modèle Category correspondant.
  4. $serie :
    • Cette propriété est une instance de la classe Serie ou null si aucune série n’est actuellement sélectionnée.
    • Elle est utilisée pour stocker la série actuellement sélectionnée si on a utilisé la route pour les séries.
    • Si une série est sélectionnée, cette propriété contiendra le modèle Serie correspondant.

La méthode mount

Ce code est une méthode de montage (mount) d’un composant Volt. La méthode mount est appelée lors de la création du composant et est utilisée pour initialiser les propriétés du composant et effectuer des opérations nécessaires au démarrage du composant.

/**
 * Méthode de montage initiale appelée lors de la création du composant.
 * 
 * @param string $slug Slug pour identifier une catégorie ou une série
 * @param string $param Paramètre de recherche optionnel
 * @return void
 */
public function mount(string $slug = '', string $param = ''): void
{
    $this->slug = $slug;
    $this->param = $param;        

    if (!empty($slug)) {
        // Détermine si le slug correspond à une catégorie ou une série
        $this->category = $this->getCategoryBySlug($slug);
        $this->serie = $this->category ? null : $this->getSerieBySlug($slug);
    }
}

/**
 * Récupère une catégorie en fonction du slug.
 * 
 * @param string $slug Slug pour identifier la catégorie
 * @return Category|null La catégorie correspondante ou null
 */
protected function getCategoryBySlug(string $slug): ?Category
{
    // Vérifie si le premier segment de l'URL est 'category'
    return request()->segment(1) === 'category' ? Category::whereSlug($slug)->firstOrFail() : null;
}

/**
 * Récupère une série en fonction du slug.
 * 
 * @param string $slug Slug pour identifier la série
 * @return Serie|null La série correspondante ou null
 */
protected function getSerieBySlug(string $slug): ?Serie
{
    return Serie::whereSlug($slug)->firstOrFail();
}

Voici une explication du code :

  1. Signature de la méthode :
    • La méthode mount est définie avec deux paramètres typés string : $slug et $param.
    • Le paramètre $slug est utilisé pour identifier une catégorie ou une série.
    • Le paramètre $param est un paramètre de recherche optionnel.
  2. Initialisation des propriétés :
    • Les propriétés $slug et $param du composant sont initialisées avec les valeurs passées en paramètre.
    • Ces valeurs sont assignées aux propriétés du composant, ce qui permet d’accéder à ces données dans d’autres parties du composant.
  3. Détermination de la catégorie ou de la série :
    • Si le $slug n’est pas vide (c’est-à-dire qu’un slug est fourni en paramètre), le code cherche à déterminer s’il correspond à une catégorie ou à une série.
    • La méthode getCategoryBySlug est appelée pour obtenir la catégorie correspondant au slug.
    • Si une catégorie est trouvée, elle est assignée à la propriété $category. Sinon, la méthode getSerieBySlug est appelée pour obtenir la série correspondant au slug, et cette série est assignée à la propriété $serie.
    • Cette logique permet de déterminer si le slug correspond à une catégorie ou à une série, et d’assigner les valeurs appropriées aux propriétés du composant.

En résumé, cette méthode de montage est utilisée pour initialiser les propriétés du composant avec les valeurs passées en paramètre, et pour déterminer si un slug correspond à une catégorie ou à une série, en assignant les valeurs appropriées aux propriétés du composant.

La méthode getPosts

Cette méthode est utilisée pour récupérer les posts en fonction de la catégorie, de la série ou du paramètre de recherche :

/**
 * Récupère les posts en fonction de la catégorie, de la série ou du paramètre de recherche.
 * 
 * @return LengthAwarePaginator Les posts paginés
 */
public function getPosts(): LengthAwarePaginator
{     
    $postRepository = new PostRepository;

    // Recherche les posts si un paramètre de recherche est présent
    if (!empty($this->param)) {
        return $postRepository->search($this->param);
    }

    // Récupère les posts paginés en fonction de la catégorie ou de la série
    return $postRepository->getPostsPaginate($this->category, $this->serie);
}

Voici une explication du code :

  1. Signature de la méthode :
    • La méthode getPosts ne prend pas de paramètres.
    • Elle retourne un objet de type LengthAwarePaginator, qui est une pagination des posts.
  2. Création de l’objet PostRepository :
    • Un nouvel objet de la classe PostRepository est créé. Pour alléger le code du composant j’ai pensé préférable de déléguer la majorité du traitement des données pour les article à un repository.
  3. Vérification du paramètre de recherche :
    • La méthode vérifie si le paramètre de recherche ($this->param) n’est pas vide. Si c’est le cas, cela signifie qu’un utilisateur a effectué une recherche.
    • Si un paramètre de recherche est présent, la méthode appelle la méthode search de l’objet PostRepository, en passant le paramètre de recherche, et retourne les résultats de la recherche.
  4. Récupération des posts en fonction de la catégorie ou de la série :
    • Si aucun paramètre de recherche n’est présent, cela signifie que l’utilisateur n’a pas effectué de recherche et souhaite simplement afficher les posts d’une catégorie ou d’une série spécifique.
    • La méthode appelle alors la méthode getPostsPaginate de l’objet PostRepository, en passant la catégorie ($this->category) et la série ($this->serie) en tant qu’arguments.
    • Cette méthode retourne une pagination des posts en fonction de la catégorie ou de la série spécifiée.
  5. Retour des résultats :
    • La méthode retourne les résultats sous forme de pagination des posts.

En résumé, cette méthode getPosts récupère les posts en fonction de la catégorie, de la série ou du paramètre de recherche, en utilisant un objet PostRepository pour interagir avec les données des posts. Elle retourne ensuite les résultats sous forme de pagination des posts, qui peuvent être affichés dans l’interface utilisateur.

Pour terminer on envoie les données au HTML :

public function with(): array
{
    return [
        'posts' => $this->getPosts(),
    ];
}

La partie HTML

Voici la partie HTML du composant :

<div class="relative grid items-center w-full px-5 py-5 mx-auto md:px-12 max-w-7xl">

    <!-- Affichage du titre en fonction de la catégorie, de la série ou du paramètre de recherche -->
    @if($category)
        <x-header title="{{ __('Posts for category ') }} {{ $category->title }}" separator />
    @elseif($serie)
        <x-header title="{{ __('Posts for serie ') }} {{ $serie->title }}" separator />
    @elseif($param !== '')
        <x-header title="{{ __('Posts for search ') }} '{{ $param }}'" separator />
    @endif

    <!-- Pagination supérieure -->
    <div class="mb-4">
        {{ $posts->links() }}
    </div>

    <!-- Liste des posts -->
    <div class="grid w-full grid-cols-1 gap-6 mx-auto sm:grid-cols-2 lg:grid-cols-3 gallery">
        @foreach($posts as $post)
            <x-card title="{{ $post->title }}">
                <div>{{ $post->excerpt }}</div>
                <br><hr>
                <div class="flex justify-between">
                    <p wire:click="" class="text-left cursor-pointer">{{ $post->user->name }}</p>
                    <p class="text-right"><em>{{ $post->created_at->isoFormat('LL') }}</em></p>
                </div>
                <x-slot:figure>
                    <a href="{{ url('/posts/' . $post->slug) }}">
                        <img src="{{ asset('storage/photos/' . $post->image) }}" alt="{{ $post->title }}" />
                    </a>
                </x-slot:figure>
                <x-slot:actions>
                    <x-button label="{{ $post->category->title }}" link="{{ url('/category/' . $post->category->slug) }}" class="btn-outline btn-sm" />
                    @if($post->serie)
                        <x-button label="{{ $post->serie->title }}" link="{{ url('/serie/' . $post->serie->slug) }}" class="btn-outline btn-sm" />
                    @endif
                    <x-button label="{{ __('Read') }}" link="{{ url('/posts/' . $post->slug) }}" class="btn-outline btn-sm" />
                </x-slot:actions>
            </x-card>
        @endforeach
    </div>

    <!-- Pagination inférieure -->
    <div class="mb-4">
        {{ $posts->links() }}
    </div>
</div>

Cette partie HTML est une vue qui affiche une liste d’articles en fonction de la catégorie, de la série ou du paramètre de recherche, avec une pagination supérieure et inférieure. Voici une explication des élément :

  1. Titre en fonction de la catégorie, de la série ou du paramètre de recherche :
    • La première partie conditionnelle (@if) affiche un titre dynamique en fonction de la catégorie, de la série ou du paramètre de recherche.
    • Si une catégorie est spécifiée, le titre indique « Posts for category » (ou sa traduction) suivi du titre de la catégorie.
    • Si une série est spécifiée, le titre indique « Posts for serie » (ou sa traduction) suivi du titre de la série.
    • Si un paramètre de recherche est spécifié, le titre indique « Posts for search » (ou sa traduction) suivi du paramètre de recherche.
  2. Pagination supérieure :
    • La pagination supérieure est affichée à l’aide de la directive {{ $posts->links() }}.
    • Cela affiche les liens de pagination pour naviguer entre les pages de résultats de articles.
  3. Liste des articles :
    • Une grille est utilisée pour afficher les posts dans des cartes.
    • Une boucle @foreach itère sur chaque article dans la variable $posts.
    • Pour chaque post, une carte (<x-card>) est affichée avec le titre du post, son extrait, le nom de l’auteur, la date de création, une image, et des boutons d’action pour afficher la catégorie, la série et lire l’article.
    • L’image est liée à l’URL du post, et les boutons d’action sont liés aux URL des catégories, des séries et des posts correspondants.
  4. Pagination inférieure :
    • La pagination inférieure est affichée à nouveau à la fin de la liste des posts, utilisant la même directive {{ $posts->links() }}.
    • Cela permet à l’utilisateur de naviguer facilement entre les différentes pages de résultats de posts.

En résumé, cette vue HTML fournit une interface utilisateur pour afficher une liste de posts avec une pagination, en fonction de la catégorie, de la série ou du paramètre de recherche spécifiés, permettant ainsi à l’utilisateur de naviguer et d’explorer les posts de manière conviviale.

Conclusion

La page d’accueil semble bien établie et fonctionnelle. Elle s’adapte bien aux différentes largeurs d’écran. Les cadres résument bien les articles. On a un bon filtrage selon les catégories, les séries et une recherche quelconque.

 

 

Print Friendly, PDF & Email

Laisser un commentaire