Un módulo es la forma correcta de ampliar PrestaShop sin tocar el núcleo. Con una clase que hereda de Module, una carpeta bien organizada y unos hooks ya tienes un módulo funcionando. Esta guía resume, en versión ligera, cómo crear uno para PrestaShop 8 y 9.
Está pensada para PrestaShop 8.x y 9.x y PHP 8.1 o superior.
Resumen rápido
- Un módulo es una carpeta dentro de
modules/con una clase que hereda deModule. - El archivo y la clase deben coincidir:
solusenaviso.php→Solusenaviso. - Se engancha con hooks y se configura con
ConfigurationoHelperForm. - Valida la entrada con
ToolsyValidate, y escapa la salida en Smarty. - Empaqueta en ZIP y pruébalo en staging antes de producción.
1. Qué es un módulo y cuándo crearlo
Un módulo es un paquete de código que se engancha a PrestaShop para añadir o modificar funcionalidad: un bloque en la portada, una integración con una API, un cálculo de precios o una página propia. Vive en modules/ y se carga cuando está instalado y activo.
La regla es sencilla: si la funcionalidad debe sobrevivir a un cambio de tema, va en un módulo. Si es puramente visual, va en el tema. Y si es una modificación del núcleo, casi siempre hay un hook para hacerlo sin tocarlo.
| Necesidad | Dónde va |
|---|---|
| Añadir funcionalidad o una integración | Módulo propio en modules/ |
| Cambiar el diseño | Tema hijo en themes/ |
| Cambiar el núcleo | Hook, nunca editando classes/ o src/ |
| Sustituir una clase | override/, solo si no hay hook |
2. Estructura mínima
Un módulo puede ser un único archivo PHP dentro de modules/. Para algo serio, conviene una carpeta organizada:
modules/solusenaviso/
├── solusenaviso.php
├── controllers/front/aviso.php
├── views/
│ ├── css/aviso.css
│ └── templates/
│ ├── hook/aviso.tpl
│ └── front/aviso.tpl
├── config/
│ ├── services.yml
│ └── routes.yml
├── translations/
├── logo.png
└── readme.md
Convención obligatoria: si el módulo se llama solusenaviso, el archivo debe ser solusenaviso.php y la clase Solusenaviso. Un desajuste impide que PrestaShop lo detecte.
3. El archivo principal
La clase del módulo se declara en el archivo principal y hereda de Module. En el constructor se definen nombre, versión, autor y compatibilidad con las versiones de PrestaShop.
// modules/solusenaviso/solusenaviso.php
if (!defined('_PS_VERSION_')) {
exit;
}
class Solusenaviso extends Module
{
public function __construct()
{
$this->name = 'solusenaviso';
$this->version = '1.0.0';
$this->ps_versions_compliancy = [
'min' => '8.0',
'max' => _PS_VERSION_,
];
parent::__construct();
}
}
La comprobación de _PS_VERSION_ impide que se llame al archivo directamente por URL. Debe estar en todos los archivos PHP del módulo.
4. Instalación y hooks
PrestaShop llama a install() y uninstall() al instalar o desinstalar el módulo. Ahí se registran los hooks y se definen los valores por defecto.
public function install()
{
return parent::install()
&& $this->registerHook('displayHome');
}
public function hookDisplayHome()
{
$this->context->smarty->assign(
'texto',
Configuration::get('SOLUSEN_AVISO_TEXTO')
);
return $this->display(__FILE__, 'views/templates/hook/aviso.tpl');
}
El método del hook lleva el prefijo hook: displayHome → hookDisplayHome(). Solo se ejecuta si antes lo registraste en install().
| Hook | Cuándo se ejecuta |
|---|---|
displayHome | En la portada de la tienda. |
displayHeader | En el <head> del front. |
displayFooter | En el pie de página. |
actionFrontControllerSetMedia | Al encolar CSS y JS. |
actionValidateOrder | Al validar un pedido. |
5. Configuración y back office
El método getContent() es la pantalla de configuración clásica. Con HelperForm generas el formulario, el token de seguridad y el botón de guardado sin escribir HTML a mano. En PrestaShop 8 y 9 también puedes declarar servicios y rutas Symfony en config/services.yml y config/routes.yml para el back office moderno.
Consejo: para un módulo pequeño, getContent() con HelperForm es lo más rápido. Symfony merece la pena cuando necesitas listados, formularios complejos o integración con el núcleo moderno.
6. Datos y tablas propias
Para ajustes pequeños, Configuration es suficiente: Configuration::updateValue() guarda el dato y Configuration::get() lo recupera.
Si necesitas muchos registros o relaciones, crea una tabla propia durante la instalación. Usa siempre el prefijo _DB_PREFIX_ para no romper instalaciones con otro prefijo, y elimina la tabla solo al desinstalar.
Para consultar, usa Db::getInstance() y convierte los enteros con (int) antes de montar la consulta.
7. Seguridad
Un módulo mal escrito es una puerta abierta. Estas cuatro reglas cubren la mayoría de los fallos:
- Valida la entrada con
Tools::getValue()yValidate. - Convierte tipos:
(int)para IDs,(float)para precios,pSQL()para textos en consultas. - Protege los formularios con el token de
HelperForm. - Escapa la salida en Smarty con
|escape:'html':'UTF-8'.
| Dato | Validar / convertir | Al mostrar |
|---|---|---|
| Entero / ID | (int) | (int) |
| Texto plano | pSQL() | |escape:'html' |
Validate::isEmail() | |escape:'html' | |
| Precio | (float) | Tools::displayPrice() |
Nunca confíes en $_GET ni en $_POST: convierte siempre los tipos y escapa la salida. Es la diferencia entre un módulo seguro y una brecha.
8. Publicar y errores comunes
- El ZIP contiene una única carpeta con el nombre del módulo.
- No incluye
.git/,node_modules/ni archivos de desarrollo. - Se instala, configura, desinstala y reinstala sin errores.
- Funciona en las versiones mínimas declaradas.
- Los textos están listos para traducir.
- El formulario valida tipos y usa el token de seguridad.
cd modules
zip -r solusenaviso.zip solusenaviso -x "*.git*" -x "*node_modules*"| Síntoma | Causa probable | Solución |
|---|---|---|
| El módulo no aparece | Archivo o clase no coinciden | Revisa solusenaviso.php y Solusenaviso. |
| Error 500 al instalar | Error PHP o hook inexistente | Activa el modo desarrollo y revisa los logs. |
| El hook no muestra nada | No se registró en install() | Comprueba registerHook(). |
| Los ajustes no se guardan | name del campo incorrecto | Revisa HelperForm. |
| El CSS no se actualiza | Caché | Sube la versión y limpia la caché. |
9. Preguntas frecuentes
¿Cuál es el archivo mínimo para crear un módulo?
Un archivo PHP en modules/ cuyo nombre coincida con la carpeta y que declare una clase que herede de Module.
¿Dónde se guardan los ajustes de un módulo?
Con Configuration::updateValue() se guardan en la tabla de configuración de PrestaShop. Para muchos registros, crea una tabla propia con el prefijo _DB_PREFIX_.
¿Qué diferencia hay entre un hook y un override?
Un hook es un punto de extensión pensado para módulos y no toca el núcleo. Un override sustituye una clase del núcleo y es más frágil frente a actualizaciones.
¿Puedo usar Symfony en PrestaShop 8 o 9?
Sí. Puedes declarar servicios y rutas para el back office moderno, y mantener hooks y Smarty para el front.
¿Cómo pruebo el módulo sin romper la tienda?
Usa un entorno local o de staging con el modo desarrollo activo. Prueba instalación, configuración, uso, desinstalación y reinstalación.
10. Conclusión
Crear un módulo de PrestaShop es más sencillo de lo que parece: una carpeta, una clase que hereda de Module, unos hooks bien puestos y las APIs correctas. La diferencia entre un módulo que aguanta años y uno que se rompe está en los detalles: prefijos, validación, tokens, escaping y un ciclo de instalación limpio.
Si tu tienda necesita una funcionalidad a medida, una integración o mantener un módulo existente, podemos ayudarte.
¿Necesitas un módulo a medida para tu PrestaShop?
Desarrollamos módulos propios, integraciones y mantenimiento para que tu tienda haga exactamente lo que necesitas.
Documentación oficial de PrestaShop:
