Vue d'ensemble
Le système de modules de Larapen vous permet d'étendre la plateforme avec des fonctionnalités personnalisées: un blog, une boutique, un système de réservation ou toute fonctionnalité que vous pouvez imaginer. Chaque add-on est un package Laravel autonome avec ses propres modèles, services, contrôleurs, routes, vues, traductions et migrations. Ce guide vous accompagne dans la création d'un add-on de zéro.
Add-ons disponibles
Larapen est livré avec 26 add-ons que vous pouvez utiliser comme références pour construire le vôtre :
blog, shop, forum, helpdesk, careers, events, faq, partners, portfolio, pricing, team, newsletter, billing, classified, booking, envato, licenses, glossary, gdpr, stats, webmail, stripe, paypal, paddle, momo, adsblockerdetector.
Parcourez n'importe quel add-on installé sous extensions/addons/ pour voir des exemples concrets des patterns décrits ci-dessous.
Prérequis
- PHP 8.3+ avec une installation fonctionnelle de Larapen.
- Bonne connaissance de Laravel (Eloquent, contrôleurs, service providers, migrations, Blade).
- Compréhension du pattern service layer (Contrôleurs → Services → Modèles).
- Familiarité avec spatie/laravel-translatable (pour le contenu multilingue).
Étape 1 : Créer le répertoire du module
Tous les modules se trouvent sous extensions/addons/. Créez un répertoire en utilisant un nom en minuscules, sans tirets :
extensions/addons/testimonials/
Étape 2 : Créer le manifeste (addon.json)
Créez extensions/addons/testimonials/addon.json. Ce fichier définit les métadonnées de votre add-on, les permissions, les menus d'administration et les liens de navigation :
{
"name": "testimonials",
"display_name": "Témoignages",
"version": "1.0.0",
"description": "Collectez et affichez les témoignages clients sur votre site",
"author": "Votre Nom",
"requires_core": ">=1.0.0",
"license_type": "free",
"dependencies": [],
"needs_user_account": false,
"provides": {
"permissions": [
"testimonials.view",
"testimonials.create",
"testimonials.edit",
"testimonials.delete"
],
"admin_menu": [
{
"label": "Témoignages",
"icon": "bi-chat-quote",
"route": "admin.testimonials.items.index",
"permission": "testimonials.view",
"children": [
{ "label": "Tous les témoignages", "route": "admin.testimonials.items.index" },
{ "label": "Ajouter", "route": "admin.testimonials.items.create" }
]
}
],
"front_menu": {
"route": "front.testimonials.index",
"label": "Témoignages"
}
},
"sku": "",
"item_id": "",
"marketplace_item_ids": {
"envato": "",
"gumroad": "",
"shop": ""
}
}
Référence des champs du manifeste
| Champ | Type | Description |
|---|---|---|
name | string | Obligatoire. Identifiant unique: doit correspondre au nom du répertoire. |
display_name | string | Obligatoire. Nom lisible affiché dans l'administration. |
version | string | Version sémantique. |
license_type | string | "free" ou "paid". Contrôle le regroupement dans la barre latérale. |
dependencies | array | Autres modules qui doivent être actifs (logique ET). |
dependencies_any | array | Au moins un add-on doit être actif (logique OU). |
needs_user_account | bool | Quand true, active l'interface de compte utilisateur côté public. |
provides.permissions | array | Permissions Spatie: auto-enregistrées à l'activation. |
provides.admin_menu | array | Éléments de menu injectés dans la barre latérale admin. |
provides.front_menu | object | Lien { route, label } pour la navigation publique. |
sku | string | SKU du produit de licence correspondant sur l'API de licences (ex. larapen-testimonials) : l'identifiant envoyé en premier lors de la vérification d'un code d'achat. Laisser vide pour les modules non vendus. |
marketplace_item_ids | object | Identifiant du module sur chaque plateforme de vente : envato (ID d'article Envato Market), gumroad (ID de produit Gumroad, ou son permalien court comme abcde ou son permalien personnalisé) et shop (SKU du produit dans la boutique). Un module qui déclare au moins un identifiant exige un code d'achat valide, acheté sur l'une de ces plateformes, pour être activé. Laisser tout vide pour les modules non vendus. |
item_id | string | Ancien ID d'article Envato à plat, conservé pour les anciennes versions du cœur. Le garder identique à marketplace_item_ids.envato. |
Étape 3 : Créer la structure complète
extensions/addons/testimonials/
├── addon.json
├── config/
│ └── testimonials.php
├── database/
│ └── migrations/
│ └── 2026_01_01_000001_create_testimonials_table.php
├── resources/
│ ├── lang/
│ │ ├── en/testimonials.php
│ │ └── fr/testimonials.php
│ └── views/
│ └── admin/
│ ├── items/
│ │ ├── index.blade.php
│ │ ├── create.blade.php
│ │ └── edit.blade.php
│ └── settings.blade.php
└── src/
├── TestimonialsServiceProvider.php
├── Http/
│ ├── Controllers/
│ │ ├── Admin/TestimonialController.php
│ │ └── Front/TestimonialController.php
│ └── Requests/
│ ├── StoreTestimonialRequest.php
│ └── UpdateTestimonialRequest.php
├── Models/Testimonial.php
├── Routes/
│ ├── admin.php
│ └── web.php
└── Services/TestimonialService.php
Étape 4 : Créer le Service Provider
Le Service Provider est le point d'entrée de votre add-on. Le namespace Addons\Testimonials\ correspond automatiquement à extensions/addons/testimonials/src/. Il enregistre les routes, vues, traductions, migrations et la configuration.
{NomStudly}ServiceProvider (ex. TestimonialsServiceProvider). Le AddonManager la découvre automatiquement.
Étape 5 : Créer la migration
Créez les tables de base de données dans database/migrations/. Les champs traduisibles doivent utiliser le type json.
testimonials_, blog_posts, shop_orders) pour éviter les collisions de noms.
Étape 6 : Créer le Modèle
Utilisez le trait HasTranslations de Spatie, définissez protected $table explicitement, et ajoutez des scopes Eloquent (scopeActive, scopeOrdered).
Étape 7 : Créer le Service
Toute la logique métier va dans les classes Service: jamais dans les contrôleurs. Les contrôleurs ne gèrent que les préoccupations HTTP.
Étape 8 : Créer les FormRequest
Toute la validation doit être dans des classes FormRequest. Pour les champs traduisibles, rendez obligatoire uniquement la locale par défaut.
Étape 9 : Créer les Contrôleurs
- Contrôleurs admin : Utilisent
view('testimonials::admin.items.index')(vue avec namespace). - Contrôleurs front-end : Utilisent
$this->themeService->view('pages.testimonials.index')pour la résolution de vues compatible avec les thèmes.
Étape 10 : Créer les Routes
- Routes admin : Préfixées avec
admin/{addon}, middlewareweb, auth, admin.access. - Routes front-end : Définies en double: une fois avec préfixe
{locale}(langues non-par défaut) et une fois sans (langue par défaut).
Étape 11 : Créer les traductions
Fichiers dans resources/lang/en/ et resources/lang/fr/. Accédés via __('testimonials::testimonials.admin.title').
Étape 12 : Créer les vues admin
Les vues admin étendent le layout principal : @extends('admin.layouts.master').
Étape 13 : Créer les vues de thème
Placez les vues front-end dans chaque thème actif :
extensions/themes/default/views/pages/testimonials/index.blade.php
Étape 14 : Activer et tester
- Allez dans Add-ons dans le panneau d'administration.
- Cliquez sur « Synchroniser » pour découvrir votre nouvel add-on.
- Cliquez sur « Activer »: cela va :
- Exécuter vos migrations automatiquement.
- Enregistrer vos permissions Spatie.
- Enregistrer votre Service Provider.
- Ajouter vos éléments de menu à la barre latérale admin.
Règles d'architecture
- JAMAIS de logique métier dans les contrôleurs: toujours déléguer à un Service.
- TOUJOURS des classes FormRequest pour la validation.
- TOUJOURS définir
protected $tableexplicitement sur chaque modèle. - Utiliser
spatie/laravel-translatablepour tous les champs texte publics. - Préfixer les tables avec le nom du module.
- Utiliser
__('namespace::fichier.clé')pour toutes les chaînes. - PHP 8.3+ : types, enums, readonly, arguments nommés.
declare(strict_types=1)dans tous les fichiers PHP.
Add-ons de passerelle de paiement
Pour créer un add-on de passerelle de paiement (ex. PayPal, Mollie), votre add-on doit implémenter l'interface App\Contracts\PaymentGatewayInterface. L'add-on Boutique découvre automatiquement les passerelles de paiement des modules installés et actifs qui implémentent cette interface.
Checklist complète
| Élément | |
|---|---|
addon.json avec permissions, admin_menu, front_menu | |
config/{nom}.php avec valeurs par défaut | |
| Service Provider (config, routes, vues, traductions, migrations) | |
| Migrations (tables préfixées, colonnes JSON pour les champs traduisibles) | |
Modèles (HasTranslations, $table explicite, scopes, casts) | |
| Services (toute la logique métier) | |
| Classes de validation FormRequest | |
| Contrôleurs admin + routes (préfixées, avec middleware auth/admin.access) | |
| Contrôleurs front + routes (variantes localisées + non-localisées) | |
Traductions en en/ et fr/ | |
Vues admin (étendant admin.layouts.master) | |
Vues de thème dans views/pages/ de chaque thème actif | |
SCSS de thème dans assets/scss/pages/ de chaque thème actif | |
Exécuter npx vite build après ajout de SCSS/JS | |
| Activer le module et tester toutes les routes |