---
title: Templates de email personalizados — crear desde cero
section: email
slug: custom-templates
description: "Como crear templates de email completamente personalizados en modulos PrestaShop: estructura HTML+TXT, variables dinamicas, multiidioma y envio con Mail::Send()."
keywords: "prestashop email template personalizado HTML TXT multiidioma variables Mail::Send modulo custom"
last_updated: 2024-12-01
source_url: "https://ayudaprestashop.es/email/custom-templates"
---

# Templates de email personalizados — crear desde cero

> Como crear templates de email completamente personalizados en modulos PrestaShop: estructura HTML+TXT, variables dinamicas, multiidioma y envio con Mail::Send().

Crear templates de email personalizados en un modulo requiere seguir la convencion de directorios de PrestaShop. Cada template debe tener una version HTML y una version TXT. Las variables se definen como `{variable}` en el template.

## Estructura de templates de email

*Estructura de directorios para templates de email*

```text
modules/mymodule/
└── mails/
    ├── es/
    │   ├── my_notification.html   ← Template HTML en español
    │   ├── my_notification.txt    ← Template texto plano en español
    │   └── subject.tpl            ← (Opcional) Asunto multiidioma
    ├── en/
    │   ├── my_notification.html   ← Template HTML en ingles
    │   └── my_notification.txt
    ├── fr/
    │   ├── my_notification.html
    │   └── my_notification.txt
    └── de/
        ├── my_notification.html
        └── my_notification.txt

# IMPORTANTE:
# - El nombre del archivo = nombre del template (sin extension)
# - El directorio = ISO del idioma (es, en, fr, de, it, pt...)
# - PrestaShop usa el idioma del cliente para elegir el directorio
# - Si no existe el idioma, usa 'en' como fallback
```

## Template HTML base

*mails/es/my_notification.html — template HTML*

```html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="es">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>{subject}</title>
  <style type="text/css">
    body { font-family: Arial, sans-serif; font-size: 14px; color: #333333; }
    .container { max-width: 600px; margin: 0 auto; }
    .header { background-color: #205fac; padding: 20px; text-align: center; }
    .header img { max-width: 200px; }
    .content { padding: 30px 20px; background: #ffffff; }
    .footer { padding: 15px; background: #f5f5f5; text-align: center; font-size: 12px; color: #888888; }
    .button { display: inline-block; padding: 12px 30px; background: #205fac;
              color: #ffffff; text-decoration: none; border-radius: 4px; }
  </style>
</head>
<body>
<div class="container">
  <!-- Cabecera con logo de la tienda -->
  <div class="header">
    <img src="{shop_logo}" alt="{shop_name}">
  </div>

  <!-- Contenido principal -->
  <div class="content">
    <p>Hola {firstname} {lastname},</p>
    <p>Nos complace informarte de que tu solicitud ha sido procesada correctamente.</p>

    <h2 style="color: #205fac;">Detalles de tu notificacion</h2>

    <table style="width:100%; border-collapse:collapse;">
      <tr>
        <td style="padding:8px; border-bottom:1px solid #eee; font-weight:bold;">Referencia:</td>
        <td style="padding:8px; border-bottom:1px solid #eee;">{reference}</td>
      </tr>
      <tr>
        <td style="padding:8px; border-bottom:1px solid #eee; font-weight:bold;">Fecha:</td>
        <td style="padding:8px; border-bottom:1px solid #eee;">{date}</td>
      </tr>
      <tr>
        <td style="padding:8px; font-weight:bold;">Estado:</td>
        <td style="padding:8px;">{status}</td>
      </tr>
    </table>

    <p style="margin-top: 25px;">
      <a href="{customer_url}" class="button">Ver mi cuenta</a>
    </p>

    <p>Si tienes alguna pregunta, no dudes en contactarnos.</p>
    <p>Un saludo,<br><strong>{shop_name}</strong></p>
  </div>

  <!-- Pie de pagina -->
  <div class="footer">
    {shop_name} &mdash; {shop_url}<br>
    <a href="{shop_url}">Visitar la tienda</a>
  </div>
</div>
</body>
</html>
```

## Template TXT (version texto plano)

*mails/es/my_notification.txt — version texto plano*

```text
Hola {firstname} {lastname},

Nos complace informarte de que tu solicitud ha sido procesada correctamente.

Detalles de tu notificacion:
- Referencia: {reference}
- Fecha: {date}
- Estado: {status}

Puedes ver los detalles en tu cuenta:
{customer_url}

Si tienes alguna pregunta, no dudes en contactarnos.

Un saludo,
{shop_name}
{shop_url}
```

## Variables disponibles y personalizadas

| Variable | Valor | Siempre disponible |
| --- | --- | --- |
| {shop_name} | Nombre de la tienda (Configuration::PS_SHOP_NAME) | Si |
| {shop_url} | URL de la tienda | Si |
| {shop_logo} | URL del logo de la tienda | Si |
| {shop_logo_url} | URL del logo (alternativo) | Si |
| {subject} | Asunto del email | Si |
| {firstname} | Nombre del cliente | Si se pasa en templateVars |
| {lastname} | Apellido del cliente | Si se pasa en templateVars |
| {email} | Email del cliente | Si se pasa en templateVars |
| {date} | Fecha actual formateada | Si |
| {today} | Fecha de hoy | Si |

## Enviar con Mail::Send()

*Enviar el email personalizado desde el modulo*

```php
<?php

private function sendMyNotification(Customer $customer, string $reference, string $status): bool
{
    $lang = new Language((int) $customer->id_lang);

    // Path al directorio de templates del modulo
    $templateDir = _PS_MODULE_DIR_ . $this->name . '/mails/';

    // Variables disponibles en el template
    $templateVars = [
        '{firstname}'    => $customer->firstname,
        '{lastname}'     => $customer->lastname,
        '{email}'        => $customer->email,
        '{reference}'    => $reference,
        '{date}'         => date('d/m/Y H:i'),
        '{status}'       => $status,
        '{customer_url}' => Context::getContext()->link->getPageLink('my-account'),
    ];

    return (bool) Mail::Send(
        (int) $customer->id_lang,
        'my_notification',         // Nombre del template (sin extension)
        'Tu solicitud ha sido procesada', // Asunto
        $templateVars,
        $customer->email,
        $customer->firstname . ' ' . $customer->lastname,
        null,                      // Reply-to email
        null,                      // Reply-to name
        null,                      // Adjunto
        null,
        $templateDir,              // Directorio de templates del modulo
        false,                     // No usar die() si falla
        (int) Context::getContext()->shop->id
    );
}
```

## Soporte multiidioma

*Crear directorios de idioma automaticamente al instalar*

```php
<?php

/**
 * Crear directorios de mails al instalar el modulo.
 * Solo crea los idiomas que tiene PrestaShop instalados.
 */
private function installMailTemplates(): bool
{
    $mailsDir = _PS_MODULE_DIR_ . $this->name . '/mails/';

    foreach (Language::getLanguages(false) as $lang) {
        $langDir = $mailsDir . $lang['iso_code'] . '/';
        if (!is_dir($langDir)) {
            mkdir($langDir, 0755, true);
        }

        $htmlFile = $langDir . 'my_notification.html';
        $txtFile  = $langDir . 'my_notification.txt';

        // Copiar desde el template de 'en' si no existe el del idioma
        if (!file_exists($htmlFile) && file_exists($mailsDir . 'en/my_notification.html')) {
            copy($mailsDir . 'en/my_notification.html', $htmlFile);
        }
        if (!file_exists($txtFile) && file_exists($mailsDir . 'en/my_notification.txt')) {
            copy($mailsDir . 'en/my_notification.txt', $txtFile);
        }
    }

    return true;
}
```


---

*Fuente: [https://ayudaprestashop.es/email/custom-templates](https://ayudaprestashop.es/email/custom-templates). Version Markdown generada automaticamente para consumo por LLMs.*
