Blog & Actualités

Ajoutez une section blog et actualités complète à votre site Larapen. Créez des articles avec catégories, tags, images à la une et un système de commentaires imbriqués avec modération : le tout entièrement traduisible.

Éditeur d'articles enrichi

Créez des articles avec des titres, slugs, contenus, extraits et métadonnées SEO traduisibles. Associez des images à la une via la médiathèque.

Catégories & Tags

Organisez le contenu avec des catégories hiérarchiques (utilisant la table unifiée des catégories) et un système de tags flexible.

Commentaires imbriqués

Réponses de commentaires imbriquées avec profondeur configurable, file de modération, approbation automatique pour les commentateurs de confiance et support CAPTCHA.

Multi-langue

Tous les articles, catégories et tags supportent les traductions via Spatie Translatable. URLs front-end localisées avec préfixe de langue.

Notifications par e-mail

Les administrateurs sont notifiés des nouveaux commentaires. Les auteurs de commentaires sont notifiés lorsque quelqu'un répond à leur commentaire.

Temps de lecture & Vues

Calcul automatique du temps de lecture (MPM configurable) et suivi du nombre de vues pour chaque article.

Cas d'utilisation

Blog d'entreprise

Publiez des actualités d'entreprise, des mises à jour produit et des analyses sectorielles. Organisez les articles par catégorie (ex. « Mises à jour produit », « Actualités du secteur », « Tutoriels ») et laissez les visiteurs interagir via les commentaires.

Blog Portfolio

Complétez votre portfolio avec des articles en coulisses, des études de cas et des comptes-rendus de projets. Taguez les articles avec les noms de projets ou technologies pertinents pour faciliter les références croisées.

Hub de contenu multilingue

Publiez des articles en plusieurs langues (anglais, français, etc.) avec des slugs et contenus par langue. Chaque article peut avoir des traductions entièrement indépendantes gérées depuis le panneau d'administration.

Section Actualités

Utilisez le blog comme section presse/actualités. Exploitez la date de publication pour la planification et le workflow « brouillon/publié » pour le contrôle éditorial.

Prérequis

  • Larapen CMS v1.0.0 ou ultérieur
  • PHP 8.3+
  • MySQL 8.0+ (requis pour JSON_SEARCH dans les recherches de slugs traduisibles)
  • La table categories du noyau doit exister (les catégories du blog utilisent la table unifiée categories avec categorizable_type = 'post')
Note : L'add-on blog est autonome et n'a aucune dépendance avec d'autres add-ons. Il s'intègre avec la médiathèque du noyau pour la gestion des images à la une.

Installation

Étape 1 : Placer l'add-on

Copiez ou créez un lien symbolique du dossier blog dans le répertoire « extensions/addons » de votre Larapen :

Étape 2 : Activer l'add-on

Allez dans Admin → Add-ons → Add-ons installés et activez Blog & Actualités.

Étape 3 : Exécuter les migrations

Cela crée 4 tables : blog_posts, blog_post_tags, blog_post_tag (pivot), et blog_comments. Les catégories du blog utilisent la table categories existante du noyau.

Étape 4 : Définir les permissions

L'add-on enregistre 16 permissions (voir Permissions). Attribuez-les aux rôles admin via Admin → Utilisateurs → Rôles & Permissions.

Étape 5 : Configurer

Allez dans Admin → Blog → Paramètres pour configurer le nombre d'articles par page, les règles de modération des commentaires, les notifications et les paramètres de temps de lecture. Voir Paramètres.

Étape 6 : Exécuter le build Vite (si vous utilisez des thèmes)

Nécessaire si de nouveaux fichiers SCSS/JS ont été ajoutés aux répertoires de thèmes pour les pages du blog.

Configuration

L'add-on blog est livré avec un fichier de configuration config/blog.php qui définit les valeurs par défaut. Tous les paramètres peuvent être modifiés depuis le panneau d'administration (stockés dans la table settings, groupe blog).

Paramètre Description Défaut
blog_posts_per_page Nombre d'articles affichés par page sur la liste du blog. 10
blog_related_posts_count Nombre d'articles associés affichés en bas de chaque page de détail d'article. 3
blog_words_per_minute Vitesse de lecture moyenne utilisée pour calculer l'estimation « X min de lecture ». 200
blog_comments_enabled Activer ou désactiver le système de commentaires globalement. true
blog_comments_require_approval Lorsque activé, les commentaires des visiteurs doivent être approuvés par un admin avant d'apparaître. Les commentaires des utilisateurs authentifiés sont approuvés automatiquement. true
blog_allow_guest_comments Autoriser les visiteurs non connectés à laisser des commentaires (nécessite nom et e-mail). false
blog_comments_max_depth Niveau d'imbrication maximum pour les réponses de commentaires (1–5). 2
blog_auto_approve_trusted_commenters Approuver automatiquement les commentaires des utilisateurs qui ont déjà un commentaire approuvé (correspondance par e-mail). false
blog_notify_admin_on_comment Envoyer des notifications par e-mail à tous les administrateurs lorsqu'un nouveau commentaire ou une réponse est posté(e). true
blog_notify_author_on_reply Envoyer des notifications par e-mail aux auteurs de commentaires lorsque quelqu'un répond à leur commentaire. true
blog_captcha_enabled Exiger une vérification CAPTCHA lors de la publication de commentaires (nécessite qu'un fournisseur CAPTCHA soit configuré dans les paramètres du noyau). false

Valeurs par défaut du fichier de configuration

Le fichier config/blog.php inclut également les dimensions des images à la une utilisées lors du traitement des uploads :

Clé Description Défaut
featured_images.width Largeur de l'image à la une (px) 1200
featured_images.height Hauteur de l'image à la une (px) 630
featured_images.thumbnail_width Largeur de la miniature (px) 400
featured_images.thumbnail_height Hauteur de la miniature (px) 250

Admin : Articles

La page Articles (Blog → Tous les articles) est l'interface principale pour gérer le contenu du blog.

Liste des articles

Un tableau trié et paginé (20 par page) affichant :

  • Image à la une en miniature
  • Titre (traduisible)
  • Catégorie
  • Auteur
  • Statut (Brouillon / Publié)
  • Nombre de vues
  • Nombre de commentaires
  • Date de publication

Filtres & Recherche

La liste des articles supporte trois dimensions de filtrage :

  • Recherche : recherche dans les titres des articles (dans toutes les langues traduites via JSON_SEARCH)
  • Statut : filtrer par draft ou published
  • Catégorie : filtrer par une catégorie spécifique

Création & Édition d'articles

Le formulaire d'article comprend les champs suivants, chacun supportant les traductions par langue :

Champs de contenu (par langue)

Champ Validation Notes
title Requis (langue par défaut), max 255 Traduisible. Utilisé pour générer automatiquement le slug.
slug Optionnel, max 255 Traduisible. Généré automatiquement à partir du titre si laissé vide.
content Optionnel Traduisible. Contenu de l'éditeur WYSIWYG.
excerpt Optionnel, max 500 Traduisible. Court résumé pour les pages de liste.
meta_title Optionnel, max 70 Traduisible. Balise titre SEO.
meta_description Optionnel, max 160 Traduisible. Méta description SEO.

Champs non traduisibles

Champ Validation Notes
category_id Optionnel, doit exister dans categories Catégorie du blog (depuis la table unifiée des catégories)
featured_image Optionnel, fichier image Téléchargé via le service média du noyau
status Requis, draft ou published Utilise l'enum PageStatus
published_at Optionnel, date Défini automatiquement à l'heure actuelle lors de la première publication si vide
tags Optionnel, tableau d'IDs de tags Sélection multiple parmi les tags existants
Génération automatique du slug : Si le champ slug est laissé vide pour une langue, il est automatiquement généré à partir du titre en utilisant Str::slug().

Admin : Catégories

Les catégories du blog (Blog → Catégories) utilisent la table unifiée categories du noyau, filtrée par categorizable_type = 'post'. Cela signifie qu'elles partagent la même structure de table que les catégories de portfolio et d'autres add-ons, mais sont isolées via un scope global sur le modèle PostCategory.

Champs de catégorie

Champ Notes
name Traduisible. Requis pour la langue par défaut.
slug Traduisible. Généré automatiquement à partir du nom si vide.
description Traduisible. Optionnel.
parent_id Nullable. Supporte un niveau d'imbrication (parent → enfant).
position Entier pour le tri manuel.
is_active Booléen. Les catégories inactives sont masquées du front-end.
Protection contre la suppression : Une catégorie ne peut pas être supprimée si elle contient des articles. Réassignez ou supprimez d'abord les articles.

Admin : Tags

Les tags (Blog → Tags) sont des étiquettes légères pouvant être associées à n'importe quel article. Contrairement aux catégories, les tags sont plats (pas de hiérarchie) et sont stockés dans la table blog_post_tags.

Champs de tag

Champ Notes
name Traduisible. Le nom d'affichage du tag.
slug Traduisible. Identifiant compatible URL.

La liste des tags affiche chaque tag avec son nombre d'articles associés. Les tags sont recherchables par nom et paginés (20 par page).

Note : Lorsqu'un tag est supprimé, toutes les associations article-tag sont supprimées (via detach()), mais les articles eux-mêmes ne sont pas affectés.

Admin : Commentaires

La page Commentaires (Blog → Commentaires) fournit une interface de modération pour tous les commentaires du blog à travers tous les articles.

Liste des commentaires

Un tableau paginé (20 par page) affichant :

  • Auteur : nom de l'utilisateur (si authentifié) ou nom/e-mail du visiteur
  • Contenu : aperçu du texte du commentaire
  • Article : l'article de blog auquel appartient le commentaire
  • Statut : badge Approuvé / En attente
  • Date

Un badge de compteur en attente est affiché dans l'en-tête pour identifier rapidement les éléments nécessitant une attention.

Modération

Actions par commentaire :

  • Voir : voir le contenu complet du commentaire, les réponses et le contexte de l'article
  • Approuver (PATCH) : marque le commentaire comme approuvé
  • Supprimer : supprime définitivement le commentaire

Filtrer par statut

Utilisez le paramètre de requête status pour filtrer :

  • ?status=pending : afficher uniquement les commentaires en attente (non approuvés)
  • ?status=approved : afficher uniquement les commentaires approuvés

Actions groupées

Sélectionnez plusieurs commentaires à l'aide des cases à cocher et appliquez des actions groupées :

  • Approuver : approuver tous les commentaires sélectionnés en une fois
  • Supprimer : supprimer tous les commentaires sélectionnés

Les actions groupées sont envoyées en POST admin/blog/comments/bulk avec action et les ids séparés par des virgules.

Admin : Paramètres

La page des paramètres (Blog → Paramètres) est organisée en quatre sections :

Affichage des articles

  • Articles par page : nombre d'articles sur la page de liste (1–100)
  • Articles associés : nombre d'articles associés affichés sur les pages de détail (0–12)
  • Mots par minute : vitesse de lecture pour le calcul du temps de lecture (100–500)

Commentaires

  • Activer les commentaires : interrupteur global pour le système de commentaires
  • Approbation requise : si les commentaires des visiteurs nécessitent l'approbation de l'admin (les utilisateurs authentifiés sont toujours approuvés automatiquement)
  • Commentaires des visiteurs : autoriser les visiteurs non connectés à commenter
  • Profondeur des réponses : niveau d'imbrication maximum pour les réponses (1–5)
  • Approbation automatique des commentateurs de confiance : approuver automatiquement les commentaires des e-mails qui ont déjà un commentaire approuvé

Notifications

  • Notification admin : envoyer un e-mail aux admins lorsqu'un nouveau commentaire/réponse est posté(e)
  • Notification de réponse : envoyer un e-mail aux auteurs de commentaires lorsque quelqu'un répond à leur commentaire

Protection CAPTCHA

  • Activer le CAPTCHA pour les commentaires : exiger une vérification CAPTCHA lors de la publication de commentaires

Nécessite qu'un fournisseur CAPTCHA soit configuré dans les paramètres du noyau. Si aucun fournisseur n'est configuré, un avertissement est affiché avec un lien vers la page de configuration.

Front-end : Liste du blog

La page de liste du blog (/{locale}/blog) affiche les articles publiés avec pagination.

Contenu principal

  • Cartes d'articles : chacune affichant : miniature de l'image à la une, titre, extrait, badge de catégorie, nom de l'auteur, date de publication, temps de lecture et nombre de vues
  • Pagination : nombre d'articles par page configurable

Barre latérale

  • Catégories : liste des catégories actives avec le nombre d'articles
  • Articles récents : les 5 articles les plus récemment publiés
  • Articles populaires : les 5 articles les plus vus
  • Tags : tous les tags qui ont au moins un article

Front-end : Détail de l'article

La page de détail de l'article (/{locale}/blog/{slug}) affiche le contenu complet de l'article.

Contenu

  • En-tête : titre, catégorie, auteur, date de publication, temps de lecture, nombre de vues
  • Image à la une : image hero pleine largeur (via relation média polymorphique)
  • Corps du contenu : contenu HTML rendu
  • Tags : badges de tags liés aux pages de filtre par tag
  • Navigation entre articles : liens vers l'article précédent / suivant
  • Articles associés : articles partageant la même catégorie ou les mêmes tags (nombre configurable)
  • Section commentaires : commentaires imbriqués avec formulaire de réponse (voir Commentaires)

Suivi du nombre de vues

À chaque chargement de la page de détail, PostService::incrementViewCount() incrémente la colonne view_count. Cela alimente le widget « Articles populaires » de la barre latérale.

Algorithme des articles associés

Les articles associés sont sélectionnés par correspondance :

  1. Articles dans la même catégorie
  2. Articles partageant les mêmes tags

Les résultats sont triés par date de publication (le plus récent en premier) et limités au nombre configuré.

Front-end : Pages Catégorie & Tag

Page Catégorie

URL : /{locale}/blog/category/{slug}

Affiche tous les articles publiés dans la catégorie spécifiée avec la même pagination, les mêmes widgets de barre latérale et la même mise en page des cartes d'articles que la liste principale. La catégorie est résolue par son slug traduisible (langue actuelle en premier, puis repli sur l'anglais).

Page Tag

URL : /{locale}/blog/tag/{slug}

Affiche tous les articles publiés taggués avec le tag spécifié. Même mise en page que la page catégorie. Le tag est résolu par son slug traduisible.

URL : /{locale}/blog/search?q={query}

Recherche plein texte dans les titres et contenus des articles dans toutes les langues via MySQL JSON_SEARCH. Les résultats sont paginés et affichés avec la mise en page standard du blog.

Front-end : Commentaires

Le système de commentaires apparaît en bas de chaque page de détail d'article (lorsqu'il est activé).

Formulaire de commentaire

  • Utilisateurs authentifiés : n'ont besoin de saisir que le contenu du commentaire. Approuvé automatiquement sauf si des règles de modération s'appliquent.
  • Visiteurs (si activé) : doivent fournir nom, e-mail et contenu. Soumis à la modération d'approbation.
  • Formulaire de réponse : des formulaires de réponse en ligne apparaissent lorsqu'on clique sur « Répondre » sur un commentaire existant, jusqu'à la profondeur maximale configurée.
  • Notification de réponse : case à cocher pour activer/désactiver les notifications de réponse.
  • CAPTCHA : affiché lorsque le CAPTCHA est activé pour les commentaires du blog.

Affichage des commentaires

  • Les commentaires sont affichés en format imbriqué (parent → réponses).
  • Seuls les commentaires approuvés sont visibles par les visiteurs du front-end.
  • Chaque commentaire affiche : nom de l'auteur, date, contenu et nombre de réponses.

Règles de validation

Champ Validation
content Requis, 3–2000 caractères
parent_id Optionnel, doit exister dans blog_comments ; vérification de profondeur appliquée
author_name Requis pour les visiteurs, max 255
author_email Requis pour les visiteurs, e-mail valide, max 255
notify_on_reply Booléen optionnel

Logique d'approbation automatique

  1. Si Approbation requise est désactivée → tous les commentaires sont approuvés automatiquement.
  2. Si le commentateur est authentifié → approuvé automatiquement.
  3. Si Approbation automatique des commentateurs de confiance est activée et que l'e-mail a déjà un commentaire approuvé → approuvé automatiquement.
  4. Sinon → en attente (nécessite l'approbation de l'admin).

Support multilingue

L'add-on blog utilise spatie/laravel-translatable pour tous les champs de contenu. Les traductions sont stockées sous forme de colonnes JSON dans la base de données.

Champs traduisibles par modèle

Modèle Champs traduisibles
Post slug, title, content, excerpt, meta_title, meta_description
PostCategory slug, name, description
PostTag slug, name

Résolution des slugs

Les contrôleurs front-end résolvent les slugs en cherchant d'abord dans la langue actuelle, puis en se repliant sur l'anglais :

Images à la une

Les articles supportent une seule image à la une via une relation polymorphique MorphOne vers le modèle Media du noyau (mediable). Le trait HasMedia est inclus dans le modèle Post.

Flux de téléchargement

  1. L'admin télécharge un fichier image via le formulaire de création/édition d'article.
  2. Le PostService délègue à MediaService::uploadFor().
  3. L'image est stockée dans le sous-répertoire posts du disque média.
  4. Les miniatures sont générées selon les dimensions de configuration (featured_images.thumbnail_width/height).

Suppression d'image

Le formulaire d'édition inclut une case à cocher « Supprimer l'image à la une ». Lorsqu'elle est cochée, l'enregistrement média existant et les fichiers sont supprimés via MediaService::delete(). Le téléchargement d'une nouvelle image remplace automatiquement l'ancienne.

Notifications par e-mail

L'add-on blog envoie deux types de notifications par e-mail :

Notification de nouveau commentaire

Envoyée à tous les administrateurs (is_admin = true) lorsqu'un nouveau commentaire ou une réponse est posté(e).

  • Objet : « Nouveau commentaire sur {titre de l'article} » ou « Nouvelle réponse sur {titre de l'article} »
  • Corps : Nom de l'auteur, titre de l'article, aperçu du contenu (200 caractères)
  • Action : Lien « Modérer les commentaires » (si en attente) ou lien « Voir le commentaire » (si approuvé)

Contrôlé par : le paramètre blog_notify_admin_on_comment.

Notification de réponse à un commentaire

Envoyée à l'auteur du commentaire parent lorsque quelqu'un répond à son commentaire.

  • Objet : « Nouvelle réponse à votre commentaire sur {titre de l'article} »
  • Corps : Nom de l'auteur de la réponse, titre de l'article, aperçu du contenu
  • Action : Lien « Voir la réponse »

Contrôlé par : le paramètre blog_notify_author_on_reply.

Les notifications de réponse respectent la préférence notify_on_reply du commentateur et ne sont pas envoyées lorsque quelqu'un répond à son propre commentaire.

Protection CAPTCHA

Lorsque blog_captcha_enabled est défini à true, le formulaire de commentaire inclut un défi CAPTCHA. L'add-on blog s'intègre avec le CaptchaService du noyau :

  • Le service vérifie si le CAPTCHA est activé pour le contexte blog.
  • Le nom de champ CAPTCHA approprié est résolu via CaptchaService::getResponseFieldName().
  • La validation utilise la classe CaptchaRule du noyau.

Un fournisseur CAPTCHA (ex. reCAPTCHA, hCaptcha) doit être configuré dans les paramètres du noyau pour que cette fonctionnalité fonctionne.

Mise à jour

Étape 1 : Remplacer les fichiers

Remplacez le répertoire de l'add-on par la nouvelle version.

Étape 2 : Exécuter les migrations

Étape 3 : Vider les caches

Étape 4 : Recompiler les assets

Nécessaire uniquement si la mise à jour inclut des fichiers SCSS/JS de thème nouveaux ou modifiés.

Étape 5 : Vérifier

Visitez Blog → Paramètres pour confirmer que la page des paramètres se charge correctement, puis vérifiez la page de liste du blog en front-end.

Sauvegardez d'abord : Sauvegardez toujours votre base de données avant d'exécuter des migrations sur un système de production.

Dépannage

Les pages du blog retournent une erreur 404

  • Assurez-vous que l'add-on Blog est activé dans Admin → Add-ons.
  • Exécutez php artisan route:clear pour vider le cache des routes.
  • Vérifiez que le BlogServiceProvider est bien enregistré (vérifiez l'autoloader AddonServiceProvider).

Un article affiche « Non trouvé » bien qu'il soit publié

  • Vérifiez que le statut de l'article est published (et non draft).
  • Assurez-vous que published_at est défini et dans le passé (les articles datés dans le futur ne sont pas visibles).
  • Vérifiez que le slug correspond à l'URL : les slugs sont spécifiques à la langue. Le système essaie d'abord la langue actuelle, puis l'anglais.

La page catégorie retourne une erreur 404

  • Assurez-vous que la catégorie est active (is_active = true).
  • Vérifiez que le categorizable_type de la catégorie est post.
  • Vérifiez que le slug dans l'URL correspond au slug traduisible de la catégorie pour la langue actuelle.

Les commentaires n'apparaissent pas sur les articles

  • Vérifiez que blog_comments_enabled est défini à true dans les paramètres.
  • Si vous utilisez la modération, les commentaires doivent d'abord être approuvés. Vérifiez la page des commentaires admin pour les éléments en attente.
  • Les commentaires des visiteurs nécessitent que blog_allow_guest_comments soit activé.

Le formulaire de commentaire ne s'affiche pas pour les visiteurs

  • Activez blog_allow_guest_comments dans Blog → Paramètres.
  • Le StoreCommentRequest vérifie l'autorisation : si les commentaires des visiteurs sont désactivés, la soumission du formulaire retourne une erreur 403.

Le CAPTCHA n'apparaît pas sur le formulaire de commentaire

  • Assurez-vous que blog_captcha_enabled est défini à true dans les paramètres du blog.
  • Un fournisseur CAPTCHA doit être configuré dans Admin → Paramètres → CAPTCHA.
  • La vérification CaptchaService::isEnabledFor('blog') doit retourner true.

Les notifications par e-mail ne sont pas envoyées

  • Vérifiez que la messagerie est configurée correctement dans Admin → Paramètres → Mail.
  • Vérifiez que les interrupteurs de notification sont activés : blog_notify_admin_on_comment et/ou blog_notify_author_on_reply.
  • Les notifications de réponse nécessitent que l'auteur du commentaire parent ait notify_on_reply = true.
  • Les auto-réponses ne déclenchent pas de notifications (par conception).

Impossible de supprimer une catégorie : « Impossible de supprimer une catégorie contenant des articles »

L'add-on empêche la suppression des catégories qui ont des articles assignés. Réassignez les articles à une autre catégorie ou supprimez-les d'abord.

L'image à la une ne s'affiche pas

  • Vérifiez que le fichier média a été téléchargé avec succès (cherchez dans la table media un mediable_type correspondant à l'article).
  • Vérifiez que le lien symbolique de stockage existe : php artisan storage:link.
  • Vérifiez les permissions des fichiers sur le répertoire de stockage.

La recherche ne retourne aucun résultat malgré des articles correspondants

  • La recherche utilise MySQL JSON_SEARCH qui nécessite MySQL 8.0+.
  • La recherche est par correspondance de motif (contient), donc les correspondances partielles devraient fonctionner.
  • Seuls les articles publiés (avec published_at dans le passé) sont inclus dans les résultats de recherche.

Le temps de lecture affiche « 1 min » pour tous les articles

  • Assurez-vous que l'article a du contenu (le temps de lecture est calculé à partir de strip_tags(content)).
  • Vérifiez le paramètre blog_words_per_minute : la valeur par défaut est 200 MPM.
  • Les articles très courts afficheront toujours 1 minute (le minimum).

Cet article vous a-t-il été utile ?

Merci pour votre retour !

Besoin d'aide ? Créez un ticket de support

Créer un Ticket