Front Controllers en modulos

Actualizado: 2024-12-01

Los FrontControllers de modulos son paginas publicas accesibles en el Front Office. Cada archivo PHP en controllers/front/ crea una nueva URL. Son la base de paginas de cuenta de usuario, resultados personalizados, landings de modulos y endpoints AJAX.

#Crear un FrontController

controllers/front/listing.php — FrontController de listado
php
<?php

if (!defined('_PS_VERSION_')) { exit; }

/**
 * Clase: {ModuleName}{ControllerName}ModuleFrontController
 * Archivo: controllers/front/{controllername}.php
 */
class MyModuleListingModuleFrontController extends ModuleFrontController
{
    public $display_column_left  = false;
    public $display_column_right = false;
    public $template = 'module:mymodule/views/templates/front/listing.tpl';

    public function setMedia(): bool
    {
        parent::setMedia();
        $this->registerStylesheet('mymodule-listing', 'modules/mymodule/views/css/listing.css');
        $this->registerJavascript('mymodule-listing', 'modules/mymodule/views/js/listing.js', ['position'=>'bottom']);
        return true;
    }

    public function initContent(): void
    {
        parent::initContent();

        $page    = max(1, (int) Tools::getValue('page', 1));
        $perPage = 12;
        $offset  = ($page - 1) * $perPage;

        $items = Db::getInstance()->executeS(
            'SELECT * FROM `' . _DB_PREFIX_ . 'mymodule_items`
             WHERE active = 1
             ORDER BY sort_order ASC
             LIMIT ' . (int) $offset . ', ' . (int) $perPage
        );

        $total = (int) Db::getInstance()->getValue(
            'SELECT COUNT(*) FROM `' . _DB_PREFIX_ . 'mymodule_items` WHERE active = 1'
        );

        $this->context->smarty->assign([
            'items'        => $items ?: [],
            'total'        => $total,
            'current_page' => $page,
            'per_page'     => $perPage,
            'total_pages'  => ceil($total / $perPage),
            'module_url'   => $this->context->link->getModuleLink($this->module->name, 'listing'),
        ]);
    }
}

#URL de acceso

URLs de acceso a FrontControllers
php
<?php

// Sin URLs amigables (siempre funciona):
// /index.php?fc=module&module=mymodule&controller=listing

// Con URLs amigables activadas (rewrite):
// /module/mymodule/listing

// Desde PHP — usar Link para generar la URL correcta
$url = $this->context->link->getModuleLink(
    'mymodule',   // nombre del modulo
    'listing',    // nombre del controlador (sin ModuleFrontController)
    ['page' => 2] // parametros GET opcionales
);
// Resultado: https://tienda.com/module/mymodule/listing?page=2
// (o con hookModuleRoutes: https://tienda.com/mi-listado?page=2)

#Pretty URLs con hookModuleRoutes

Registrar URL amigable para el FrontController
php
<?php

public function install(): bool
{
    return parent::install()
        && $this->registerHook('moduleRoutes');
}

/**
 * Define URLs amigables para los FrontControllers del modulo.
 * La clave del array es el ID de la ruta (unico en todo PS).
 */
public function hookModuleRoutes(): array
{
    return [
        'module-mymodule-listing' => [
            'controller' => 'listing',
            'rule'       => 'mi-listado{/:page}',
            'keywords'   => [
                'page' => ['regexp' => '[0-9]+', 'param' => 'page'],
            ],
            'params' => [
                'fc'     => 'module',
                'module' => $this->name,
            ],
        ],
    ];
    // URL resultante: /mi-listado/2 -> controller=listing&page=2
}

#Multiples paginas en un modulo

ArchivoClaseURL (con rewrite)
controllers/front/index.phpMyModuleIndexModuleFrontController/module/mymodule/index
controllers/front/listing.phpMyModuleListingModuleFrontController/module/mymodule/listing
controllers/front/detail.phpMyModuleDetailModuleFrontController/module/mymodule/detail
controllers/front/ajax.phpMyModuleAjaxModuleFrontController/module/mymodule/ajax
controllers/front/webhook.phpMyModuleWebhookModuleFrontController/module/mymodule/webhook
Descargar en Markdown Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.