Select Page

How to add email layouts in a theme from an external module

Ravindra Gautam
Published: October 11, 2022

In this blog, we are about to learn, how to add email layouts in a theme from an external module.

We can add our own email layouts from our module.

Each time we install a language or if we generate them via the back office our layout will be rendered, translated, and exported in the appropriate folders.

Let’s assume for this example we want to add our layout for both themes modern and classic. Then we have to prepare our layouts.

Let’s start,

We store them in the mail/layouts folder of our module.

our_module_name/mail/layouts/custom_classic_webkul_layout.html.twig

{# modules/WkTestModule/mails/layout/custom_classic_webkul_layout.html.twig #}
{# You can use the theme layout (if present) to extend it easily #}
{% extends '@MailThemes/classic/components/layout.html.twig' %}
{% block content %}
<tr>
  <td align="center" class="titleblock">
    <font size="2" face="{{ languageDefaultFont }}Open-sans, sans-serif" color="#555454">
      <span
        class="title">{{ 'This is an example mail template created by webkul from my module for classic theme'|trans({},
        'EmailsBody', locale)|raw }}</span>
    </font>
  </td>
</tr>
<tr>
  <td class="space_footer">&nbsp;</td>
</tr>
{% endblock %}
{% block footer %}
<tr>
  <td class="space_footer">&nbsp;</td>
</tr>
<tr>
  <td class="footer" style="border-top: 4px solid #333333">
    <span>{{ '<a href="{shop_url}">{shop_name}</a> created by <a
        href="https://webkul.com/">Webkul</a>'|trans({'{prestashop_url}':
      'https://www.prestashop.com/?utm_source=marchandprestashop&utm_medium=e-mail&utm_campaign=footer_1-7'},
      'Emails.Body', locale)|raw }}</span>
  </td>
</tr>
{% endblock footer %}

our_module_name/mail/layouts/custom_modern_webkul_layout.html.twig

{# modules/WkTestModule/mails/layout/custom_modern_webkul_layout.html.twig #}
{% extends '@MailThemes/modern/components/layout.html.twig' %}
{% block content %}
<tr>
  <td align="center" class="titleblock">
    <font size="2" face="{{ languageDefaultFont }}Open-sans, sans-serif" color="#555454">
      <span
        class="title">{{ 'This is an example mail template created by webkul from my module for modern theme'|trans({},
        'EmailsBody', locale)|raw }}</span>
    </font>
  </td>
</tr>
<tr>
  <td class="space_footer">&nbsp;</td>
</tr>
{% endblock %}
{% block footer %}
<tr>
  <td class="space_footer">&nbsp;</td>
</tr>
<tr>
  <td class="footer" style="border-top: 4px solid #333333">
    <span>{{ '<a href="{shop_url}">{shop_name}</a> created by <a
        href="https://webkul.com/">Webkul</a>'|trans({'{prestashop_url}':
      'https://www.prestashop.com/?utm_source=marchandprestashop&utm_medium=e-mail&utm_campaign=footer_1-7'},
      'Emails.Body', locale)|raw }}</span>
  </td>
</tr>
{% endblock footer %}

Now we will register a new hook named “actionListMailThemes”. It is used to add a new layout to our theme’s layout collection.

<?php
use PrestaShop\PrestaShop\Core\MailTemplate\Layout\Layout;
use PrestaShop\PrestaShop\Core\MailTemplate\ThemeCatalogInterface;
use PrestaShop\PrestaShop\Core\MailTemplate\ThemeCollectionInterface;
use PrestaShop\PrestaShop\Core\MailTemplate\ThemeInterface;
class WkTestModule extends Module 
{
    public function __construct()
	{
		$this->name = 'wktestmodule';
		$this->tab = 'front_office_features';
		$this->version = '4.0.0';
		$this->author = 'Webkul';
		$this->need_instance = 0;
		parent::__construct();
		$this->bootstrap = true;
		$this->secure_key = Tools::encrypt($this->name);
		$this->displayName = $this->l('Wk Test Module');
		$this->description = $this->l('Wk Test Module');
		$this->confirmUninstall = $this->l('Are you sure you want to uninstall this module?');
		$this->ps_versions_compliancy = array(
			'min' => '1.7',
			'max' => _PS_VERSION_
		);
	}
    
    public function install() 
    {
        return parent::install()
            // This class constant contains 'actionBuildMailLayoutVariables'
            && $this->registerHook(ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK)
        ;
    }
    
    public function uninstall() 
    {
        return parent::uninstall()
            && $this->unregisterHook(ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK)
        ;        
    }
    
    public function enable($force_all = false) 
    {
        return parent::enable()
            && $this->registerHook(ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK)
        ;
    }
    
    public function disable($force_all = false) 
    {
        return parent::disable()
            && $this->unregisterHook(ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK)
        ;        
    }
    
    /**
     * @param array $hookParams
     */
    public function hookActionListMailThemes(array $hookParams)
    {
        if (!isset($hookParams['mailThemes'])) {
            return;
        }
        /** @var ThemeCollectionInterface $themes */
        $themes = $hookParams['mailThemes'];
        /** @var ThemeInterface $theme */
        foreach ($themes as $theme) {
            if (!in_array($theme->getName(), ['classic', 'modern'])) {
                continue;
            }
            // Add a layout to each theme (don't forget to specify the module name)
            $theme->getLayouts()->add(new Layout(
                'custom_template',
                __DIR__ . '/mails/layouts/custom_' . $theme->getName() . '_webkul_layout.html.twig',
                '',
                $this->name
            ));
        }
    }
}

Now we will get result like this.

design-preview
Email-html-content

We can also use the constant name ThemeCatalogInterface::LIST_MAIL_THEMES_HOOK instead of actionListMailThemes.

That’s all about this blog.

If any issues or doubts in the above step, please feel free to let us know in the comment section.

We would be happy to help.

You can learn How to extend an email layout in a theme from a module.

You can also explore our PrestaShop Development Services and a large range of quality PrestaShop Modules.

For any doubt contact us at [email protected].

Source: webkul.com