🛍️ Todos los hooks de la pagina de producto — mapa completo
Actualizado: 2025-01-15
#Mapa visual de hooks en producto
Layout de la pagina de producto con posiciones de hooks
text
┌─────────────────────────────────────────────────────────┐
│ displayHeader │
│ displayBanner │
├─────────────────────────────────────────────────────────┤
│ Breadcrumb │
├──────────────────────┬──────────────────────────────────┤
│ │ Nombre producto │
│ Imagenes │ ─────────────── │
│ │ displayProductAdditionalInfo │
│ displayAfterProduct │ Precio · Descuento │
│ Thumbs │ ─────────────── │
│ │ displayProductPriceBlock │
│ │ ─────────────── │
│ │ Cantidad [+][-] │
│ │ displayProductButtons │
│ │ [Anadir al carrito] │
│ │ displayProductActions │
│ │ ─────────────── │
│ │ Envio, devolucion, etc. │
│ │ displayReassurance │
├──────────────────────┴──────────────────────────────────┤
│ Tabs: │
│ [Descripcion] [Detalles] [Tab custom...] │
│ displayProductExtraContent ← aqui se anaden tabs │
│ │
│ Contenido del tab activo │
├─────────────────────────────────────────────────────────┤
│ displayProductFooter │
│ Productos relacionados / accesorios │
├─────────────────────────────────────────────────────────┤
│ displayFooterProduct │
│ displayFooter │
└─────────────────────────────────────────────────────────┘
#displayProductAdditionalInfo
Se muestra justo debajo del nombre del producto y encima del precio. Ideal para: referencias, stock badges, seller info, valoraciones.
Mostrar referencia y stock badge
php
<?php
public function hookDisplayProductAdditionalInfo($params)
{
$product = $params['product'];
// Acceder a datos del producto
$reference = $product['reference'] ?? $product->reference ?? '';
$quantity = StockAvailable::getQuantityAvailableByProduct(
(int) ($product['id_product'] ?? $product->id)
);
$this->context->smarty->assign([
'reference' => $reference,
'stock_qty' => $quantity,
'stock_class' => $quantity > 10 ? 'in-stock' : ($quantity > 0 ? 'low-stock' : 'out-of-stock'),
]);
return $this->display(__FILE__, 'views/templates/hook/product-info.tpl');
}
#displayProductButtons
Se ejecuta junto al selector de cantidad y boton de carrito. Perfecto para: wishlist, comparar, compartir, preguntar sobre producto.
Boton 'Anadir a favoritos'
php
<?php
public function hookDisplayProductButtons($params)
{
$idProduct = (int) ($params['product']['id_product'] ?? $params['product']->id);
$isLogged = $this->context->customer->isLogged();
$inWishlist = false;
if ($isLogged) {
$inWishlist = Db::getInstance()->getValue(
'SELECT COUNT(*) FROM `' . _DB_PREFIX_ . 'ecom_wishlist`
WHERE id_customer = ' . (int) $this->context->customer->id . '
AND id_product = ' . $idProduct
) > 0;
}
$this->context->smarty->assign([
'id_product' => $idProduct,
'in_wishlist' => $inWishlist,
'is_logged' => $isLogged,
'ajax_url' => $this->context->link->getModuleLink($this->name, 'ajax'),
]);
return $this->display(__FILE__, 'views/templates/hook/product-buttons.tpl');
}
#displayProductExtraContent
Este hook es especial: NO devuelve HTML directo. Devuelve un array de objetos PrestaShop\PrestaShop\Core\Product\ProductExtraContent. Cada objeto genera un tab automaticamente.
Anadir tabs personalizados a la ficha de producto
php
<?php
use PrestaShop\PrestaShop\Core\Product\ProductExtraContent;
public function hookDisplayProductExtraContent($params)
{
$idProduct = (int) $params['product']->id;
$tabs = [];
// Tab 1: Guia de tallas
$sizeGuide = new ProductExtraContent();
$sizeGuide->setTitle('Guia de tallas');
$this->context->smarty->assign(['id_product' => $idProduct]);
$sizeGuide->setContent(
$this->display(__FILE__, 'views/templates/hook/size-guide.tpl')
);
$tabs[] = $sizeGuide;
// Tab 2: Reviews (si hay)
$reviews = $this->getProductReviews($idProduct);
if (!empty($reviews)) {
$reviewTab = new ProductExtraContent();
$reviewTab->setTitle('Opiniones (' . count($reviews) . ')');
$this->context->smarty->assign(['reviews' => $reviews]);
$reviewTab->setContent(
$this->display(__FILE__, 'views/templates/hook/reviews.tpl')
);
$tabs[] = $reviewTab;
}
// Tab 3: Documentacion tecnica (si el producto tiene archivos adjuntos)
$attachments = Product::getAttachmentsStatic(
$this->context->language->id, $idProduct
);
if (!empty($attachments)) {
$docsTab = new ProductExtraContent();
$docsTab->setTitle('Documentacion');
$this->context->smarty->assign(['attachments' => $attachments]);
$docsTab->setContent(
$this->display(__FILE__, 'views/templates/hook/docs.tpl')
);
$tabs[] = $docsTab;
}
return $tabs;
}
#displayAfterProductThumbs
Se muestra debajo de las miniaturas de imagen del producto. Ideal para: video del producto, vista 360, imagen de garantia.
Incrustar video de YouTube del producto
php
<?php
public function hookDisplayAfterProductThumbs($params)
{
$idProduct = (int) $params['product']->id;
// Obtener URL de video guardada como feature del producto
$videoUrl = Db::getInstance()->getValue(
'SELECT fvl.value
FROM `' . _DB_PREFIX_ . 'feature_product` fp
JOIN `' . _DB_PREFIX_ . 'feature_value_lang` fvl
ON fp.id_feature_value = fvl.id_feature_value
AND fvl.id_lang = ' . (int) $this->context->language->id . '
JOIN `' . _DB_PREFIX_ . 'feature_lang` fl
ON fp.id_feature = fl.id_feature AND fl.id_lang = fvl.id_lang
WHERE fp.id_product = ' . $idProduct . '
AND fl.name = "Video"'
);
if (empty($videoUrl)) {
return '';
}
// Extraer ID de YouTube
preg_match('/(?:youtu\.be\/|youtube\.com\/(?:watch\?v=|embed\/))([\w-]+)/', $videoUrl, $m);
$youtubeId = $m[1] ?? '';
if (empty($youtubeId)) {
return '';
}
$this->context->smarty->assign(['youtube_id' => $youtubeId]);
return $this->display(__FILE__, 'views/templates/hook/product-video.tpl');
}
#displayProductActions
Se muestra justo despues del boton 'Anadir al carrito'. Usos comunes: compartir en redes, anadir a lista, notificar cuando haya stock.
#Ejemplo completo: tabs personalizados
views/templates/hook/size-guide.tpl
smarty
<div class="ecom-size-guide">
<h4>{l s='Guia de tallas' mod='ecom_productplus'}</h4>
<table class="table table-striped">
<thead>
<tr>
<th>{l s='Talla' mod='ecom_productplus'}</th>
<th>{l s='Pecho (cm)' mod='ecom_productplus'}</th>
<th>{l s='Cintura (cm)' mod='ecom_productplus'}</th>
<th>{l s='Cadera (cm)' mod='ecom_productplus'}</th>
</tr>
</thead>
<tbody>
<tr><td>S</td><td>86-91</td><td>71-76</td><td>91-97</td></tr>
<tr><td>M</td><td>97-102</td><td>81-86</td><td>102-107</td></tr>
<tr><td>L</td><td>107-112</td><td>91-97</td><td>107-112</td></tr>
<tr><td>XL</td><td>117-122</td><td>102-107</td><td>117-122</td></tr>
</tbody>
</table>
</div>
#Ejemplo: badge de producto
Mostrar badges: nuevo, mas vendido, descuento
php
<?php
public function hookDisplayProductAdditionalInfo($params)
{
$product = $params['product'];
$badges = [];
// Badge "Nuevo" — productos de los ultimos 20 dias
$nbDaysNew = (int) Configuration::get('PS_NB_DAYS_NEW_PRODUCT') ?: 20;
$dateNew = date('Y-m-d', strtotime("-{$nbDaysNew} days"));
if (isset($product['date_add']) && $product['date_add'] > $dateNew) {
$badges[] = ['label' => 'Nuevo', 'class' => 'badge-new'];
}
// Badge "Descuento"
$hasDiscount = isset($product['has_discount']) && $product['has_discount'];
if ($hasDiscount) {
$pct = $product['discount_percentage'] ?? '';
$badges[] = ['label' => $pct ? "-{$pct}" : 'Oferta', 'class' => 'badge-sale'];
}
// Badge "Mas vendido" — top 10 de su categoria
$idProduct = (int) ($product['id_product'] ?? $product->id);
$isBestseller = Db::getInstance()->getValue(
'SELECT COUNT(*) FROM (
SELECT ps.id_product
FROM `' . _DB_PREFIX_ . 'product_sale` ps
ORDER BY ps.quantity DESC LIMIT 10
) top WHERE top.id_product = ' . $idProduct
);
if ($isBestseller) {
$badges[] = ['label' => 'Top ventas', 'class' => 'badge-best'];
}
if (empty($badges)) {
return '';
}
$this->context->smarty->assign(['badges' => $badges]);
return $this->display(__FILE__, 'views/templates/hook/product-badges.tpl');
}
Descargar en Markdown
Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.