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, règles d’approbation automatique et support CAPTCHA.

Publication en direct & auto-modération

Les commentaires, réponses, modifications et suppressions sont envoyés sans recharger la page. Les auteurs connectés peuvent modifier et supprimer leurs propres commentaires.

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 “published at” 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 : Téléverser l’add-on

Dans le panneau d’administration, allez dans Admin → Extensions → Add-ons et cliquez sur le bouton Téléverser un add-on. Sélectionnez le fichier ZIP de l’add-on : le système l’extrait automatiquement et l’add-on apparaît dans la liste des add-ons installés.

Étape 2 : Activer l’add-on

Repérez Blog & Actualités dans la liste et cliquez sur Activer. Ses migrations, ses seeders (le cas échéant) et ses permissions sont mis en place automatiquement.

Étape 3 : Configurer

Naviguez vers Admin → Blog → Paramètres pour composer la page d’accueil et configurer le nombre d’articles par page, la modération des commentaires, les notifications et le temps de lecture. Voir Configuration.

Code d’achat (clé de licence)

Blog & Actualités est vendu comme un produit séparé, il possède donc son propre code d’achat (clé de licence), distinct du code d’achat de l’application principale et de celui de chaque autre add-on. Il vous est demandé lorsque vous activez Blog & Actualités dans Panneau d’administration → Add-ons.

Nos produits sont vendus sur trois plateformes. La façon dont vous recevez un code d’achat dépend de l’endroit où vous avez acheté le produit.

Plateforme / Marketplace Comment obtenir le code d’achat Où le retrouver
Boutique bedigit.com
Achat sur le site (Shop)
Généré automatiquement lorsque la commande est payée, puis envoyé par e-mail, soit dans un e-mail de licence dédié, soit dans l’e-mail de confirmation de commande. Mon compte → Mes licences sur bedigit.com
Gumroad Créé dès que Gumroad nous notifie la vente, puis envoyé dans un e-mail séparé, en plus du reçu Gumroad. L’e-mail de licence, votre Bibliothèque Gumroad et Mon compte → Mes licences sur bedigit.com
Envato Market
CodeCanyon
Délivré par Envato, pas par nous, et jamais envoyé par e-mail : vous le téléchargez vous-même depuis votre compte Envato. Compte Envato → Downloads → License certificate & purchase code
Vérifiez votre dossier de spam. Pour les achats effectués sur la Boutique bedigit.com et sur Gumroad, le code d’achat est envoyé par e-mail. Les e-mails de licence automatiques sont très souvent filtrés : si le message ne se trouve pas dans votre boîte de réception, regardez dans votre dossier spam / courrier indésirable avant de contacter le support, et ajoutez notre adresse d’expédition à vos contacts ou à votre liste d’autorisation.

1. Boutique bedigit.com (achat sur le site)

  • Dès que le statut de paiement de la commande devient Payée, une clé de licence est générée automatiquement pour chaque article sous licence de la commande (une clé par unité achetée : acheter 3 unités donne 3 clés distinctes).
  • Elle est envoyée par e-mail à l’adresse utilisée pour la commande, soit dans un e-mail de licence dédié, soit dans l’e-mail de confirmation de commande. Vérifiez votre boîte de réception et votre dossier spam / courrier indésirable.
  • La clé reste disponible dans votre compte sous Mon compte → Mes licences. Les clés sont masquées dans la liste ; ouvrez la page de détail de la licence pour afficher et copier la clé complète, voir les domaines sur lesquels elle est activée, et désactiver un domaine pour libérer un emplacement d’activation.
  • La facture correspondante se trouve sous Mon compte → Mes commandes.

2. Gumroad

  • Un achat sur Gumroad produit deux e-mails distincts : le reçu Gumroad (envoyé par Gumroad, donnant accès aux fichiers) et un e-mail de clé de licence (envoyé par bedigit.com) qui contient votre code d’achat.
  • L’e-mail de clé de licence est généré dès que Gumroad nous notifie la vente, il arrive donc normalement quelques secondes après le paiement. Ici aussi, vérifiez votre boîte de réception et votre dossier spam / courrier indésirable.
  • Lorsque le produit Gumroad utilise la fonctionnalité de clés de licence propre à Gumroad, la même clé apparaît aussi dans votre reçu Gumroad et sous Bibliothèque → votre achat sur gumroad.com.
  • Utilisez la même adresse e-mail sur bedigit.com que sur Gumroad : vos clés sont alors liées automatiquement à votre compte et listées sous Mon compte → Mes licences, même si vous vous inscrivez après l’achat. Vous pouvez aussi ajouter une clé Gumroad manuellement depuis Mon compte → Mes licences Gumroad.

3. Envato Market (CodeCanyon)

  • Les codes d’achat Envato sont délivrés et fournis par Envato Market, jamais envoyés par e-mail par nous, il n’y a donc rien à chercher dans votre dossier de spam : vous récupérez le code depuis votre compte Envato.
  • Connectez-vous à votre compte Envato / CodeCanyon, ouvrez la page Downloads, trouvez l’article et choisissez License certificate & purchase code dans le menu déroulant Download. Le code est inscrit dans ce certificat.
  • Un code d’achat Envato ressemble à 12345678-90ab-cdef-1234-567890abcdef (8-4-4-4-12 caractères). Il ne change jamais, et le renouvellement du support de l’article n’en délivre pas de nouveau.
  • Article officiel Envato : Where Is My Purchase Code?
Vous avez perdu votre code d’achat ? Recherchez dans votre messagerie (dossier de spam inclus) “licence” ou “code d’achat”, puis consultez Mon compte → Mes licences sur bedigit.com pour les achats Boutique et Gumroad, ou Downloads → License certificate sur Envato. S’il est toujours introuvable, ouvrez un ticket sur notre Centre d’aide avec votre numéro de commande (Boutique), l’ID de vente Gumroad ou l’e-mail de l’acheteur (Gumroad), ou votre nom d’utilisateur Envato et le nom de l’article (Envato).

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 similaires 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_home_hero_enabled Afficher la bannière hero en haut de la page d’accueil du blog. Le reste du hero est stocké dans les autres paramètres blog_home_hero_* (titre, sous-titre, bouton, hauteur, alignement, couleurs de fond et de texte). false
blog_home_shows_listing Servir la simple liste des articles sur /blog au lieu de l’accueil magazine. /blog/posts redirige alors vers /blog. false
blog_home_trending_enabled Faire défiler les titres les plus lus sur une ligne sous l’en-tête de la page d’accueil du blog. true
blog_home_trending_limit Nombre de titres affichés dans la barre des tendances (1–12). 5
blog_home_sections Les sections de la page d’accueil, au format JSON : une entrée par section avec son type de contenu, sa disposition, son nombre d’articles, son titre / sous-titre par langue et les IDs de catégorie, de tag ou d’articles qu’elle cible. Articles en vedette (article à la une) + Derniers articles (grille) + Les plus lus (pleins feux)
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_auto_approve_replies Approuver automatiquement les réponses à un commentaire existant, afin qu’une discussion continue sans qu’un modérateur approuve chaque réponse. Les commentaires de premier niveau suivent toujours les règles de modération normales. 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 téléversements :

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éversé 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
is_featured Optionnel, interrupteur Place l’article dans la section À la une de la page d’accueil du blog
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.

Les commentaires supprimés par leur auteur vont à la corbeille comme n’importe quel autre commentaire supprimé, avec les réponses supprimées en même temps qu’eux. Vous pouvez les consulter ou les restaurer depuis Blog → Commentaires → Corbeille.

Admin : Paramètres

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

Affichage des articles

  • Articles par page : nombre d’articles sur la page de liste (1–100)
  • Articles similaires : nombre d’articles similaires 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)

Page d’accueil

L’onglet s’ouvre sur Disposition de la page d’accueil, qui décide de ce que sert /blog :

  • Accueil magazine (par défaut) : la page d’accueil composée à partir des cartes ci-dessous. La liste des articles reste sur /blog/posts.
  • Liste des articles : la liste paginée classique des articles. /blog/posts redirige alors vers /blog pour que les deux ne se disputent jamais le même contenu, la liste reprend le titre et le fil d’Ariane propres au blog, et la sous-navigation est retirée (il ne resterait qu’une seule entrée). Les cartes ci-dessous sont masquées mais conservent leurs valeurs : revenir en arrière restaure l’accueil magazine tel qu’il était.

Les trois cartes restantes composent la page d’accueil magazine :

  • Bannière hero : un bandeau optionnel au-dessus de la première section. Le titre, le sous-titre et le libellé du bouton sont par langue ; la hauteur, l’alignement du texte, l’arrière-plan (couleur unie, dégradé ou image avec un voile) et les couleurs du titre / sous-titre / fil d’Ariane reprennent les mêmes réglages que l’onglet En-tête de page. Laissez une couleur vide pour l’hériter du thème.
  • Barre des tendances : fait défiler les titres les plus lus sur une ligne sous l’en-tête, avec un nombre de titres configurable (1–12).
  • Sections de l’accueil : le compositeur de sections. Ajoutez, réordonnez, renommez par langue et désactivez des sections. Chaque section a une source de contenu et une disposition :
    • Contenu : Articles en vedette (les articles cochés dans l’éditeur d’article, complétés par les plus lus), Derniers articles, Les plus lus, D’une catégorie, D’un tag, ou Articles choisis (sélectionnés un par un, affichés dans l’ordre de sélection).
    • Disposition : Article à la une, Grille, Liste, Pleins feux, Titres ou Carrousel.
    Une section qui ne retourne aucun article est ignorée : la page d’accueil n’affiche donc jamais de bande vide.

Toute la liste des sections est stockée au format JSON dans le paramètre blog_home_sections ; le hero et la barre des tendances utilisent les paramètres blog_home_hero_* et blog_home_trending_*.

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 anonymes : autoriser les visiteurs non connectés à commenter
  • Profondeur des réponses : niveau d’imbrication maximum pour les réponses imbriquées (1–5)
  • Approbation auto. des fidèles : approuver automatiquement les commentaires des e-mails qui ont déjà un commentaire approuvé
  • Approuver automatiquement les réponses : approuver automatiquement les réponses à un commentaire existant, sans attendre la modération. Utile pour laisser une discussion se poursuivre tout en modérant les commentaires de premier niveau

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 : Accueil du blog

La page d’accueil du blog (/{locale}/blog) est une page magazine composée depuis l’onglet Blog → Paramètres → Page d’accueil. De haut en bas, elle affiche :

  • Bannière hero (optionnelle), via le composant d’en-tête de page partagé
  • Sous-navigation : Blog et Tous les articles (masquée lorsque la liste est la page principale)
  • Barre des tendances (optionnelle) : les titres les plus lus sur une ligne défilante
  • Sections de contenu : dans l’ordre défini dans l’admin, chacune dans la disposition choisie
  • Rail des thèmes : toutes les catégories ayant au moins un article, avec leur nombre d’articles

Dispositions des sections

  • Article à la une : un article dominant dont le bloc de titre dépasse le bord inférieur de son image, à côté d’une pile d’articles secondaires
  • Grille : une grille de cartes régulière, trois par ligne sur ordinateur
  • Liste : des lignes pleine largeur, miniature à gauche, article à droite
  • Pleins feux : un article mis en avant à côté d’un panneau compact regroupant les autres
  • Titres : une liste de titres dense et sans image, sur trois colonnes au maximum
  • Carrousel : un rail horizontal de cartes avec des boutons de défilement

Les sections Les plus lus sont numérotées dans les dispositions Pleins feux et Titres, car la position y porte une véritable information. Toutes les autres sources de contenu abandonnent les numéros.

Articles en vedette

La source de contenu Articles en vedette lit l’interrupteur Article en vedette de la carte Publication de l’éditeur d’article (blog_posts.is_featured), du plus récent au plus ancien. Si moins d’articles sont cochés que la section n’en demande, elle est complétée par les articles les plus vus.

Styles

Chaque page de blog en front-end charge une feuille de style partagée (blog::front.partials.styles), afin que la page d’accueil, les archives et la page d’article se lisent comme une seule publication. Elle dérive toutes ses couleurs des tokens Bootstrap du thème actif et hérite de la police de titres du thème au lieu d’en déclarer une, de sorte que le blog suit le thème et son mode sombre.

Front-end : Liste du blog

La page de liste du blog (/{locale}/blog/posts) 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

Les pages catégorie, tag, auteur et recherche partagent cette même mise en page.

Barre latérale

  • Catégories : les catégories actives ayant au moins un article, 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.

Les articles ayant une image à la une s’ouvrent sur un bandeau pleine largeur portant un fil d’Ariane (Accueil / Blog / Catégorie / article), le libellé de la catégorie, le titre et la signature. Le titre définit sa propre couleur par-dessus la photo, car les thèmes colorent explicitement h1–h6 et cela l’emporterait sinon sur le texte blanc du hero. Les articles sans image à la une reçoivent le même en-tête, mais sur l’arrière-plan du thème.

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 similaires : 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 similaires

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

  1. Articles dans la même catégorie
  2. Articles partageant l’un des 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.

Front-end : Recherche

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 de la liste 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 : apparaît sous un commentaire lorsqu’on clique sur “Répondre”, jusqu’à la profondeur maximale configurée. Un seul formulaire de réponse est partagé par toute la page et déplacé vers le commentaire auquel on répond.
  • 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, et rafraîchi après chaque envoi.

Publier sans recharger la page

Les commentaires, réponses, modifications et suppressions sont tous envoyés en arrière-plan : la page n’est jamais rechargée et le visiteur reste là où il en était dans la discussion.

  • Pendant l’envoi d’une requête, le formulaire est estompé, ses boutons sont désactivés et le bouton d’envoi affiche un indicateur de chargement. Cela évite les doubles envois et rend l’attente visible.
  • En cas de succès, un commentaire approuvé est inséré directement dans la liste (une réponse se place sous son parent), le compteur de commentaires est mis à jour et un message de confirmation est affiché au-dessus du formulaire.
  • Si le commentaire doit encore être modéré, la confirmation le précise et rien n’est ajouté à la liste : le commentaire apparaît dès qu’un admin l’approuve.
  • Les erreurs de validation sont affichées sous le champ concerné, sans perdre ce qui a été saisi.
  • Si JavaScript n’est pas disponible, les formulaires basculent sur un envoi classique avec rechargement de la page : rien n’est perdu.

Modifier & supprimer vos propres commentaires

Les visiteurs connectés disposent des actions Modifier et Supprimer sur les commentaires qu’ils ont écrits. Les deux fonctionnent en arrière-plan, comme la publication.

  • Modifier ouvre le texte du commentaire sur place. L’enregistrement remplace le texte immédiatement et marque le commentaire comme “Modifié” à côté de sa date.
  • La modification se ferme dès que quelqu’un répond. L’action Modifier disparaît dès que le commentaire a une réponse, pour que les réponses en dessous ne perdent pas le contexte pour lequel elles ont été écrites. Elle revient si toutes les réponses sont supprimées. Les réponses en attente comptent aussi, même si elles ne sont pas encore affichées.
  • Supprimer demande d’abord une confirmation, puis retire le commentaire ainsi que toutes ses réponses. Les commentaires supprimés sont conservés dans la corbeille au lieu d’être détruits, afin qu’un admin puisse encore les consulter.
  • Ces actions n’apparaissent jamais sur le commentaire de quelqu’un d’autre, et sont refusées par le serveur en plus d’être masquées dans la page. Elles ne sont pas disponibles sur les commentaires anonymes, qui ne portent aucune identité fiable.
  • Désactiver Activer les commentaires désactive aussi la modification et la suppression.

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 : une réponse en attente de modération reste masquée jusqu’à son approbation.
  • Chaque commentaire affiche : le nom d’affichage de l’auteur, la date, une mention “Modifié” si son auteur l’a modifié, et le contenu.
  • Le compteur de commentaires à côté du titre de la section compte les commentaires et réponses approuvés.

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 le commentaire est une réponse et que Approuver automatiquement les réponses est activé → approuvé automatiquement.
  4. Si Approbation auto. des fidèles est activée et que l’e-mail a déjà un commentaire approuvé → approuvé automatiquement.
  5. 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éversement

  1. L’admin téléverse 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éversement 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

Il existe deux manières de mettre à jour cet add-on : via le panneau d’administration (recommandé) ou en remplaçant manuellement les fichiers.

Méthode 1 : Téléchargement via le panneau d’administration (Recommandé)

  1. Téléchargez le dernier fichier .zip de cet add-on.
  2. Allez dans Panneau d’administration → Add-ons et cliquez sur le bouton Télécharger.
  3. Sélectionnez ou glissez le fichier .zip dans la zone de téléchargement.
  4. Une invite de confirmation affichera les numéros de version actuel et nouveau. Cliquez sur Remplacer pour continuer.
  5. Allez dans Panneau d’administration → Mise à jour système (/admin/update) pour appliquer les migrations de base de données en attente.

Méthode 2 : Remplacement manuel des fichiers

Étape 1 : Remplacer les fichiers

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

Étape 2 : Exécuter les migrations

php artisan migrate

Les migrations en attente ne s’exécutent qu’une seule fois : la commande peut être relancée sans risque.

Étape 3 : Vider les caches

php artisan config:clear
php artisan route:clear
php artisan view:clear

Étape 4 : Reconstruire 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ésinstallation

Éteindre un add-on sans rien perdre, c’est le désactiver : allez dans Panneau d’administration → Add-ons, trouvez Blog & News et cliquez sur Désactiver.

  • Ses routes, ses vues, ses entrées de menu d’administration et ses permissions cessent d’être enregistrées, et ses pages publiques ne répondent plus.
  • Ses tables de base de données et toutes les données qu’elles contiennent sont conservées, et ses fichiers restent dans extensions/addons/blog/. Rien n’est supprimé.
  • Le code d’achat enregistré lors de l’activation est conservé lui aussi : réactiver l’add-on ne le redemande pas.
  • La désactivation est refusée tant qu’un autre add-on actif dépend de celui-ci : désactivez d’abord cet add-on.

Cliquez sur Activer sur la même carte pour le rallumer. Les migrations en attente sont rejouées, les assets republiés, et l’add-on reprend exactement là où il s’était arrêté.

Suppression

La suppression est définitive et détruit les données de l’add-on. Le bouton Supprimer n’apparaît que sur un add-on désactivé : la suppression se fait donc toujours en deux temps :

  1. Désactivez Blog & News (voir Désinstallation).
  2. Cliquez sur Supprimer sur sa carte et confirmez la demande.

Le panneau d’administration, en une seule passe :

  • exécute le hook de désinstallation de l’add-on, s’il en fournit un, tant que son code est encore sur le disque ;
  • révoque les permissions déclarées dans son addon.json ;
  • annule ses migrations, ce qui supprime ses tables de base de données et toutes les lignes qu’elles contiennent, et purge ses entrées de la table migrations, afin qu’une réinstallation ultérieure reparte de zéro ;
  • supprime ses assets publiés : public/addons/blog/, public/vendor/blog/ et storage/app/public/addons/blog/ ;
  • supprime le dossier de l’add-on extensions/addons/blog/ ;
  • supprime sa ligne dans la table addons (le code d’achat enregistré disparaît avec elle) et vide le cache de l’application.
Cette action est irréversible. Sauvegardez votre base de données avant de supprimer un add-on dont les données peuvent encore vous servir : le réinstaller plus tard crée des tables vides, pas votre ancien contenu.

La suppression est refusée, avec un message explicatif et avant toute destruction, lorsque l’add-on est encore actif, lorsqu’un autre add-on actif en dépend, ou lorsque l’utilisateur du serveur web (PHP) ne peut pas supprimer extensions/addons/blog/. Dans ce dernier cas, donnez à cet utilisateur le droit d’écriture sur le dossier et sur son parent, puis réessayez.

Supprimer le dossier en FTP ou en SSH n’est pas équivalent : les tables de l’add-on, ses entrées dans la table migrations et sa ligne addons restent en place, et sa carte reste dans la liste. Utilisez plutôt Supprimer dans le panneau d’administration.

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é.

L’action “Modifier” a disparu sur mon propre commentaire

  • Un commentaire ne peut plus être modifié dès que quelqu’un y a répondu. Supprimez les réponses (ou demandez-le à un admin) et l’action Modifier revient.
  • Une réponse en attente de modération bloque aussi la modification, même si elle n’est pas encore affichée. Vérifiez Blog → Commentaires filtré sur ?status=pending.
  • La modification et la suppression ne sont proposées qu’aux auteurs connectés. Les commentaires publiés de façon anonyme ne peuvent pas être modifiés, car il n’existe aucun moyen fiable de prouver qui les a écrits.
  • Les deux actions sont masquées lorsque Activer les commentaires est désactivé.

Une réponse a été publiée mais n’apparaît pas

  • Si Approbation requise est activée et que la réponse vient d’un visiteur, elle est en attente : seules les réponses approuvées sont affichées. Approuvez-la depuis Blog → Commentaires.
  • Pour laisser passer les réponses sans en modérer chacune, activez Approuver automatiquement les réponses dans Blog → Paramètres.

Publier un commentaire recharge toute la page

  • C’est le comportement de repli utilisé lorsque le JavaScript de la page ne s’est pas exécuté. Le commentaire est tout de même enregistré correctement : seul le fonctionnement sans rechargement est perdu.
  • Vérifiez la console du navigateur à la recherche d’une erreur de script sur la page de l’article, et assurez-vous que les assets du thème sont compilés et chargés.

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éversé 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).

Blog & Actualités v1.0.1 : fait partie de la plateforme CMS Larapen.

© BeDigit. Tous droits réservés.

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

Guides des Modules

avr. 07, 2026