L'essentiel en 4 points
- Le nom technique du module est le nom du dossier, du fichier principal et de la classe. Choisis-le une fois pour toutes, en minuscules.
- Le constructeur remplit la carte du gestionnaire de modules (nom, version, auteur, description) et annonce les versions de PrestaShop acceptées.
- install() enregistre les crochets et pose les réglages par défaut ; uninstall() doit tout retirer.
- Chaque fichier PHP commence par vérifier que PrestaShop est chargé, et chaque dossier a son index.php qui renvoie au dossier parent.
2.1Les fichiers du module
Combien de fichiers faut-il pour un module ? Un seul : le fichier PHP principal ! Le reste, tu l'ajoutes quand tu en as besoin, pas avant.
Markdown Twin en compte dix-sept, dont cinq index.php de garde. Je te donne l'arbre complet, tel qu'il part dans le zip.
markdowntwin/
├── markdowntwin.php la classe principale : identité, crochets, réglages
├── logo.png l'icône du gestionnaire de modules, 64 × 64
├── LICENSE.md la licence d'utilisation
├── README.md ce que fait le module, en anglais
├── index.php garde-fou (un par dossier)
├── classes/
│ ├── Renderer.php construit le jumeau d'une page
│ ├── Converter.php HTML → Markdown
│ ├── Yaml.php l'en-tête YAML du jumeau
│ ├── ProductFacts.php prix, disponibilité, référence d'un produit
│ ├── LlmsTxt.php le sommaire /llms.txt
│ ├── Settings.php les réglages et leurs valeurs par défaut
│ └── index.php
├── controllers/
│ ├── index.php
│ └── front/
│ ├── llms.php le contrôleur qui sert /llms.txt
│ └── index.php
└── translations/
├── fr.php la traduction française de l'administration
└── index.phpLe nom technique, markdowntwin, est partout. C'est le nom du dossier, du fichier principal, et de la classe, que le tutoriel de PrestaShop veut identique : « That main class must bear the same name as the module and its folder, in PascalCase. » Choisis-le avant d'écrire la première ligne, et ne le change plus jamais.
Pourquoi j'insiste ? Parce qu'il est enregistré en base à l'installation, qu'il apparaît dans les adresses et dans les clés de traduction. Le renommer après coup, ce n'est pas renommer ton module, mais en livrer un autre.
Tu veux partir d'une base toute prête ? La documentation de PrestaShop propose un générateur : « If you want to get started quickly with a ready-to-use module template, you can use PrestaShop Validator’s Module Generator. » Pour ce module, on est parti de la version WordPress de Markdown Twin, et on a tout réécrit à la main, à la façon de PrestaShop.
2.2La classe principale et son constructeur
Tout commence dans markdowntwin.php, avec une classe qui hérite de Module et un constructeur qui dit qui elle est.
class MarkdownTwin extends Module
{
const VERSION = '1.0.0';
public function __construct()
{
$this->name = 'markdowntwin';
$this->tab = 'seo';
$this->version = self::VERSION;
$this->author = 'Kōeki';
$this->need_instance = 0;
$this->ps_versions_compliancy = ['min' => '1.7.6.0', 'max' => _PS_VERSION_];
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Markdown Twin');
$this->description = $this->l('A Markdown twin of every page for AI assistants and agents: the same content without the interface, with the page facts and structured data. The HTML page stays the one search engines index.');
}
}Je te la fais ligne par ligne, ou presque.
nameest le nom technique. Il doit être identique au nom du dossier.tabrange le module dans une section du gestionnaire de modules, ici le SEO.versionest comparée à celle qui est enregistrée en base. Quand le fichier annonce une version plus récente, PrestaShop propose une mise à jour, et ça, on le voit juste en dessous.need_instanceà 0, et PrestaShop ne charge pas la classe pour afficher la page des modules. Le tutoriel le résume, « the module will not be loaded, and therefore will spend less resources to generate the “Modules” page ».ps_versions_compliancyannonce les versions de PrestaShop acceptées. En dehors, l'installation s'arrête avec ce message, lu dans le code de la 9.2.0 : « The version of your module is not compliant with your PrestaShop version. »bootstrapàtruedit que les gabarits du module suivent les outils de mise en page de l'administration.displayNameetdescriptionpassent par$this->l(), pour être traduits. J'y reviens au chapitre sur les réglages et les traductions.
Le code est en anglais, la description aussi. C'est voulu ! Un module s'écrit dans une langue, puis se traduit, et cette langue de départ, c'est l'anglais, comme pour les modules de PrestaShop.
2.3La carte du module dans le gestionnaire
Ce constructeur, tu le retrouves tel quel dans Modules › Gestionnaire de modules. Regarde !

Le carré vert : c'est logo.png, à la racine du dossier. Le nom, la version, l'auteur et la description sortent du constructeur, la description étant déjà traduite en français.
Petit aveu sur ce logo, et je te le fais volontiers ;) Le tutoriel de PrestaShop le demande en « PNG format, 32 by 32 pixels in size », et le nôtre fait 64 × 64. Le gestionnaire de la 9.2.0 l'affiche sans broncher, mais si tu vises la place de marché, colle à la consigne.
Et la pastille verte « Mise à jour disponible » ?
Au moment de la capture, la base du labo enregistrait encore le module en 0.9.0, la version installée au début. Le fichier, lui, annonçait 1.0.0. PrestaShop compare les deux, et propose de mettre à jour.
Ce mécanisme mérite qu'on s'y arrête, parce qu'il ne fait pas ce que tu crois. Je le détaille au dernier chapitre.
2.4install() et uninstall()
Que doit faire l'installation ? Ici, trois choses. Elle laisse PrestaShop enregistrer le module, elle pose les réglages par défaut, elle branche les crochets.
public function install()
{
return parent::install()
&& Settings::install()
&& $this->registerHook('moduleRoutes')
&& $this->registerHook('actionDispatcherBefore')
&& $this->registerHook('actionOutputHTMLBefore')
&& $this->registerHook('displayHeader');
}
public function uninstall()
{
return Settings::uninstall() && parent::uninstall();
}Je te le précise : les && ne sont pas là pour faire joli. Si une étape échoue, la suivante n'est pas tentée, et la méthode renvoie false. Le tutoriel de PrestaShop le dit ainsi : « If any of the lines in the testing block fails, the method returns false and the installation is aborted. »
Un crochet que tu n'enregistres pas n'existe pas pour PrestaShop, même si ta méthode est dans ta classe. La documentation le dit sans détour, « Remember, in order for a module to respond to a hook call, it must be registered within PrestaShop. » Et retiens bien le moment où c'est fait : à l'installation, et seulement à l'installation. Ajoute un crochet dans une version suivante, et les boutiques qui ont déjà le module ne l'auront pas. C'est le rôle du dossier upgrade/, que je te montre dans le chapitre sur les tests et la livraison.
Côté réglages, je te résume : chaque valeur est une ligne de la configuration de PrestaShop, avec un préfixe propre au module, MDTWIN_. La désinstallation les efface toutes. C'est ce que le tutoriel demande, défaire à la désinstallation ce que l'installation a écrit en base. Pour moi, c'est une question de politesse. Quand tu retires un module, il ne doit rien laisser derrière lui.
Tu préfères la ligne de commande ? Elle marche aussi. Les deux versions du labo acceptent php bin/console prestashop:module install markdowntwin. Au labo, ça a pris 191 secondes en 9.2.0 et 213 en 1.7.8.11. Pas de quoi s'inquiéter, donc, si rien ne bouge pendant trois minutes.
2.5Le garde-fou de chaque fichier
Je te conseille de commencer chaque fichier PHP par les mêmes trois lignes, comme dans Markdown Twin.
if (!defined('_PS_VERSION_')) {
exit;
}Sans elles, quelqu'un qui appelle directement /modules/markdowntwin/classes/Renderer.php dans son navigateur ferait exécuter le fichier hors de PrestaShop. Avec elles, le fichier s'arrête net. Le tutoriel donne la raison en une phrase : « The sole purpose of this is to prevent malicious visitors to load this file directly. »
Les index.php de chaque dossier font le reste, et je ne m'en passe jamais. Si un serveur mal réglé liste le contenu des dossiers, ils renvoient le visiteur au dossier parent à la place. Le nôtre est, mot pour mot, celui que propose le tutoriel de PrestaShop, et je ne vois aucune raison d'en écrire un autre ;)
Le squelette est en place, il s'installe… et il ne fait encore rien :D Pour qu'il agisse sur ta boutique, il faut le brancher, et c'est le rôle des crochets. Tout est dans le chapitre sur les crochets.
Sources
Historique de ce chapitre
- 19 octobre 2026 : première version, squelette de Markdown Twin 1.0.0.

Co-fondateur de Kōeki · Consultant SEO et IA
Sébastien Grillot
Consultant SEO depuis 2009 : c'est ici, sur Inside da WeB, qu'il a monté sa première agence, spécialisée dans l'e-commerce. Il construit aujourd'hui ses propres outils avec l'IA, modules PrestaShop compris.

