Estructura de un módulo moderno para PrestaShop 8 y 9
Un módulo de 2026 no es un fichero PHP gigante. Te enseñamos la estructura que usamos para que sea mantenible, pase el validador de Addons y sobreviva a las actualizaciones.
Muchos módulos siguen escritos como en PrestaShop 1.6: un fichero principal de miles de líneas, SQL a mano y formularios de HelperForm. Funcionan, pero cuestan mucho de mantener. Esta es la estructura que seguimos en nuestros módulos para PrestaShop 8 y 9.
El árbol de carpetas
mimodulo/
├── mimodulo.php # clase principal: instalación, hooks, poco más
├── composer.json # autoload PSR-4 del espacio de nombres
├── config/
│ ├── services.yml # servicios de Symfony
│ └── routes.yml # rutas del back office
├── src/
│ ├── Controller/Admin/ # controladores Symfony
│ ├── Entity/ o Repository/
│ └── Service/ # lógica de negocio, testeable
├── views/
│ ├── templates/hook/ # plantillas Smarty del front
│ ├── templates/admin/ # plantillas Twig del back office
│ ├── css/ js/ img/
├── upgrade/ # upgrade-1.1.0.php, upgrade-1.2.0.php…
├── translations/
└── logo.png
La clase principal, delgada
El fichero mimodulo.php debería limitarse a declarar el módulo, instalarlo y delegar. La lógica real va en clases de src/ que se pueden probar por separado:
public function hookActionValidateOrder(array $params)
{
$this->get('mimodulo.order_notifier')->notify($params['order']);
}
Composer y espacio de nombres
{
"name": "rekire/mimodulo",
"autoload": { "psr-4": { "Rekire\\MiModulo\\": "src/" } },
"config": { "prepend-autoloader": false },
"type": "prestashop-module"
}
La opción prepend-autoloader: false evita que tu autocargador se ponga por delante del de PrestaShop, lo que puede provocar conflictos de versiones con librerías que el núcleo ya trae.
Back office con Symfony
En PrestaShop 8 y 9 las pantallas de configuración pueden ser controladores de Symfony con formularios de Symfony y plantillas Twig, declarados en config/routes.yml. Así se integran con el menú, los permisos y los tokens CSRF del back office sin reinventarlos.
Upgrades desde el primer día
Cada versión que cambia la base de datos, registra hooks nuevos o crea pestañas lleva su upgrade/upgrade-X.Y.Z.php. Y ese script tiene que ser idempotente: si se ejecuta dos veces, no duplica nada. Es lo que evita pestañas duplicadas en el menú o columnas que fallan al crearse.
Validación antes de publicar
- Cabecera de licencia en todos los ficheros.
- Escapado de variables en Smarty (
|escape:'html':'UTF-8'). - Nada de funciones prohibidas por el validador de Addons.
index.phpen cada carpeta.- Pruebas en al menos dos versiones de PrestaShop y con el modo depuración activo: los avisos que en producción no se ven, en el informe de compatibilidad sí cuentan.
Con esta estructura, un módulo puede crecer durante años sin convertirse en un fichero que nadie se atreve a tocar.