Prestashop : Simplification de la mise en page des emails

Ce tutoriel est compatible avec les versions de Prestashop suivantes :
1.6 1.7 +
Cet article est assez ancien, malgré toute l'attention que j' apporte à mes contenus il est possible que celui-ci ne soit plus d'actualité.
N'hésitez pas à me le signaler si nécessaire via le formulaire de contact.

Note :
A compter la version 1.7.6 de Prestashop la gestion des emails a été changée et cet article n’est plus d’actualité.

Les emails dans Prestashop ne permettent aucune factorisation, chaque email comprends son code html complet, lorsque vous souhaitez modifier du contenu dans l’entête ou dans le pied de page d’un email il est nécessaire de réaliser la modification sur l’ensemble des emails du site.

Ce n’est pas très pratique et cela peut être source de perte de temps.
Nous allons voir dans cet article qu’il existe des solutions natives et rapides pour optimiser ce point.
Via des créations de modules comme souvent 🙂
Nous allons créer dans cet article un module hhmail dont vous retrouverez le code complet en fin d’article

Principe Technique et prérequis

Lors de l’envoi d’un email de nombreux événements sont exécutés dans la fonction Mail::send,  mais ceux qui nous intéressent sont les suivants :

  • actionEmailAddBeforeContent : exécuté avant la récupération du template de l’email
  • actionEmailAddAfterContent : exécuté après la récupération du template de l’email

Grâces à ces hooks nous pouvons donc injecter du contenu avant et après le contenu de l’email, il est donc aisé de gérer un header et un footer commun pour l’ensemble des emails 🙂

Pour éviter d’ajouter ces contenus sur des emails qui le contiennent déjà, il faudra restreindre la liste des templates sur lesquels ces contenus s’ajouteront, dans cette version je part du principe que seuls les emails surchargés dans le thème seront impactés.

Codes et exemples

Voici le code du module qui gère l’ensemble des principes énoncés ci-dessus, les commentaires sur les différentes fonctions expliquent le fonctionnement.

class Hhmail extends Module
{
 
    /** @var Liste des templates éligibles array | null */
    protected $_eligiblesTemplates;
 
    public function __construct()
    {
        $this->name = 'hhmail';
        $this->tab = 'others';
        $this->version = '0.1.0';
        $this->author = 'hhennes';
        $this->bootstrap = true;
        parent::__construct();
 
        $this->displayName = $this->l('Hh mail');
        $this->description = $this->l('Email Optimisation module');
       //A compter de la version 1.7.6 , la gestion des emails est changée et n'est plus compatible
        $this->ps_versions_compliancy = array('min' => '1.6.1.0', 'max' => '1.7.6.0');
    }
 
    /**
     * Installation du module
     * @return bool
     */
    public function install()
    {
        if (!parent::install()
            || !$this->registerHook([
                'actionEmailAddBeforeContent',
                'actionEmailAddAfterContent'
            ])
 
        ) {
            return false;
        }
 
        return true;
    }
 
 
    /**
     * Ajout de contenu AVANT le contenu du template email
     * @param array(
     *   'template' => $template,
     *   'template_html' => &$templateHtml,
     *   'template_txt' => &$templateTxt,
     *   'id_lang' => (int) $idLang,
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    public function hookActionEmailAddBeforeContent($params)
    {
        //Via ce paramètre il est possible de choisir les emails pour lequels appliquer ou non le comportement
        //Pour l'exemple la fonction récupère uniquement les emails suchargés dans le thème
        //Il est possible de faire une conf admin si nécessaire pour gérer les cas mais ici on est dans le cadre d'un poc ;)
        if (in_array($params['template'], $this->_getOverridablesTemplates())) {
            $params['template_html'] .= $this->_getHeaderContent();
        }
    }
 
 
    /**
     * Ajout de contenu APRES le contenu du template email
     * @param array(
     *   'template' => $template,
     *   'template_html' => &$templateHtml,
     *   'template_txt' => &$templateTxt,
     *   'id_lang' => (int) $idLang,
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    public function hookActionEmailAddAfterContent($params)
    {
        if (in_array($params['template'], $this->_getOverridablesTemplates())) {
            $params['template_html'] .= $this->_getFooterContent();
        }
    }
 
    /**
     * Récupération du contenu du header
     * @return string
     */
    protected function _getHeaderContent()
    {
        return $this->_getMailContent('header', $this->context->language->iso_code);
    }
 
    /**
     * Récupération du contenu du footer
     * @return string
     */
    protected function _getFooterContent()
    {
        return $this->_getMailContent('footer', $this->context->language->iso_code);
    }
 
    /**
     * Récupération du contenu des fichiers mails situés dans /mails/codeLangue/
     * @param $template
     * @param $iso_code
     * @return bool|false|string
     */
    protected function _getMailContent($template, $iso_code)
    {
        $templateFile = _PS_MODULE_DIR_ . $this->name . '/mails/' . $iso_code . '/' . $template . '.html';
        if (is_file($templateFile)) {
            return Tools::file_get_contents($templateFile);
        }
        return false;
    }
 
    /**
     * Récupération des emails éligibles pour être managés avec un header/footer
     * On part du principe que ce ne sont que ceux du thème
     * ( car les emails initiaux de Prestashop les comportent déjà )
     * @return array
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function _getOverridablesTemplates()
    {
        if (null === $this->_eligiblesTemplates) {
 
            $templates = [];
            $defaultLang = (int)Configuration::get('PS_LANG_DEFAULT');
            $language = new Language($defaultLang);
            $mailDefaultDir = _PS_THEME_DIR_ . 'mails/' . $language->iso_code . '/';
 
            //Pas d'utilisation de lib symfony pour compatibilité avec PS < 1.7
            if (is_dir($mailDefaultDir)) {
                $handle = opendir($mailDefaultDir);
                while (false !== ($entry = readdir($handle))) {
                    if ($entry != "." && $entry != ".." 
                        && !is_dir($mailDefaultDir . '/' . $entry) //Exclusion des dossier
                        //On prends uniquement les fichiers avec extension html
                        && 'html' === strtolower(pathinfo($mailDefaultDir . '/' . $entry, PATHINFO_EXTENSION))
                    ) {
                        $templates[] = pathinfo($entry, PATHINFO_FILENAME);
                    }
                }
            }
            $this->_eligiblesTemplates = $templates;
        }
 
        return $this->_eligiblesTemplates;
    }
}

Voici le contenu d’un email dans lequel l’entête et le pied de page ont été supprimé ( email mot de passe oublié )

/

<!-- Le header est ajouté automatiquement via le module hhmail -->
		<span style="color: #555454; font-family: Open-sans, sans-serif; font-size: small;">
			<span class="title" style="font-weight: 500; font-size: 28px; text-transform: uppercase; line-height: 33px;">Bonjour {firstname} {lastname},</span>
		</span>
 

Vos nouvelles informations d’identification sur {shop_name}

Adresse e-mail : {email}
 
<br>
 
		<span style="color: #555454; font-family: Open-sans, sans-serif; font-size: small;">
 
				Vous pouvez accéder à tout moment au suivi de votre commande et télécharger votre facture dans <a style="color: #337ff1;" href="{history_url}">"Historique des commandes"</a> de la rubrique <a style="color: #337ff1;" href="{my_account_url}">"Mon compte"</a> sur notre site.			
		</span>
 
 
		<span style="color: #555454; font-family: Open-sans, sans-serif; font-size: small;">
 
				Si vous avez un compte invité, vous pouvez suivre votre commande dans la section <a style="color: #337ff1;" href="{guest_tracking_url}?id_order={order_name}">"Suivi invité"</a> de notre site.			
		</span>
 
 
<!-- Le footer est ajouté automatiquement via le module hhmail -->

Les contenus des parties header et footer ne présentent pas d’intérêt je ne les détaille pas ici mais vous pouvez les trouvez dans l’archive.

Voici le rendu final du mail avec le remplacement du header et du footer ( exactement le même que les autres emails. ), mais les contenus sont récupérés dynamiquement du module hhmail

Email avec header et footer dynamique

En revanche si vous avez des modifications à faire dans les styles, dans l’entête ou le footer de vos emails les modifications seront instantanées sur tous les emails utilisant les templates,  🙂

Vous pouvez télécharger le module ici : hhmail

2 réflexions sur “Prestashop : Simplification de la mise en page des emails”

  1. Bonjour Hervé,

    Je viens de lire ton article sur les emails de la 1.7 mais je suis confronté à un « drôle » de problème. Tous mes emails sont en anglais, si j’essaie de les afficher dans les traductions, j’ai un message d’erreur en rapport avec le thème (alors qu’aucun email n’est stocké dans le thème) et chose hallucinante, je m’aperçois que le dossier mails/fr n’était pas livré avec le package. Seul le mails/en était présent. Du coup, est ce que tu sais si on peut le récupérer quelque part ?
    D’avance je te remercie.
    Cordialement.
    Renaud.

    1. Bonjour Renaud,

      Dans le cas ou il manque des contenus de langues sur ton site, tu peux réinitialiser les traductions.
      Idéalement sur un autre environnement, via le menu « International / Localisations « , puis dans le bloc import de localisations choisir le pays France.
      Les contenus natifs liés seront automatiquement téléchargés.

      Cordialement,
      Hervé

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *