PrestaShop

Mastering PrestaShop Email Customization: Adding Product Features to Order Notifications

In the dynamic world of e-commerce, personalized communication is key to building customer loyalty and streamlining internal operations. PrestaShop, a robust and flexible platform, offers a solid foundation for online stores. However, businesses often require more than the default settings, especially when it comes to critical communications like order confirmation emails.

At Migrate My Shop, the PrestaShop Migration Hub, we frequently encounter requests from merchants looking to enhance their store's functionality. A common scenario, as highlighted in a recent forum thread, involves customizing the new order email template to include specific product features. This article will delve into how you can achieve this, using the example of adding a 'Company Owned' product feature to your PrestaShop 9.0.2 order emails.

PrestaShop back office showing product features and a customized order email with 'Company Owned' field
PrestaShop back office showing product features and a customized order email with 'Company Owned' field

The Power of Personalized Order Confirmations

Order confirmation emails are more than just receipts; they are a crucial touchpoint in the customer journey. They reassure customers, provide essential details, and can even reinforce branding. For businesses, they can also serve as vital internal documents, relaying specific product attributes that are critical for fulfillment, inventory, or accounting processes.

The default PrestaShop new order email template provides standard information: product reference, name, unit price, quantity, and total price. While sufficient for many, bespoke requirements often necessitate displaying additional product data, such as a 'Company Owned' flag, a specific warranty period, or a unique serial number. The challenge lies in bridging the gap between your custom product data and the email template's display logic.

The forum user, kepak, correctly identified the target template: prestashop/mails/themes/classic/modules/ps_emailalerts/new_order.html.twig. This indicates a modern PrestaShop setup utilizing Twig for templating, a significant shift from the older Smarty templates.

Understanding PrestaShop's Email System Architecture

Before diving into modifications, it's essential to understand how PrestaShop handles emails:

  • Modules: Email sending is typically triggered by modules. For order-related emails, the ps_emailalerts module is the primary culprit.
  • PHP Logic: The module's PHP code gathers all necessary data (order details, customer info, product list) and prepares it.
  • Templates: This prepared data is then passed to an email template (.html.twig for modern PrestaShop, .html and .txt for older versions or specific modules). The template's role is solely to render this data into a visually appealing email.
  • Translation: Email templates often use translation keys (e.g., {{ 'Reference'|trans({}, 'Emails.Body', locale)|raw }}) to ensure multi-language support.

The core problem identified by kepak is that custom product features are not automatically included in the data array passed to the new_order.html.twig template by default. Therefore, both the PHP logic and the Twig template need modification.

The Solution: Extending PrestaShop's Email Logic

Modifying core PrestaShop files is a cardinal sin in development. It makes upgrades a nightmare and can lead to instability. The recommended approach is always to use overrides or, even better, create a custom module.

Step 1: Create a Custom Module (Recommended Approach)

A custom module provides the cleanest and most upgrade-safe way to extend PrestaShop's functionality. Here's a high-level overview:

  1. Module Structure: Create a new module (e.g., mymodule_email_enhancements) in your /modules directory.
  2. Register a Hook: In your module's main PHP file (e.g., mymodule_email_enhancements.php), register the actionEmailSendBefore hook. This hook allows you to modify the email parameters (including template variables) just before an email is sent.
name = 'mymodule_email_enhancements';
        $this->tab = 'front_office_features';
        $this->version = '1.0.0';
        $this->author = 'Migrate My Shop';
        $this->need_instance = 0;
        $this->bootstrap = true;

        parent::__construct();

        $this->displayName = $this->l('Email Enhancements');
        $this->description = $this->l('Adds custom data to email templates.');

        $this->ps_versi => '1.7.0.0', 'max' => _PS_VERSION_];
    }

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

    public function uninstall()
    {
        return parent::uninstall();
    }

    public function hookActionEmailSendBefore($params)
    {
        // Check if this is the new order email
        if (isset($params['template']) && $params['template'] === 'new_order') {
            // Ensure list_products exists and is an array
            if (isset($params['templateVars']['list_products']) && is_array($params['templateVars']['list_products'])) {
                $updated_products = [];
                foreach ($params['templateVars']['list_products'] as $product_data) {
                    // Load the full Product object to get features
                    $product = new Product((int)$product_data['id_product'], false, (int)$params['id_lang']);

                    $company_owned_value = '';
                    if (Validate::isLoadedObject($product)) {
                        $features = $product->getFeatures();
                        foreach ($features as $feature) {
                            // Assuming 'Company Owned' is a feature with a specific ID or name
                            // You might need to find the ID of your 'Company Owned' feature
                            // For example, if its ID is 5:
                            if ($feature['id_feature'] == (int)Configuration::get('MY_COMPANY_OWNED_FEATURE_ID')) {
                                $feature_value = new FeatureValue($feature['id_feature_value'], (int)$params['id_lang']);
                                $company_owned_value = $feature_value->value;
                                break;
                            }
                        }
                    }
                    // Add the custom feature to the product data array
                    $product_data['company_owned'] = $company_owned_value;
                    $updated_products[] = $product_data;
                }
                // Update the templateVars with the enriched product list
                $params['templateVars']['list_products'] = $updated_products;
            }
        }
        // Return the modified parameters
        return $params;
    }
}

Important: You'll need to replace Configuration::get('MY_COMPANY_OWNED_FEATURE_ID') with the actual ID of your 'Company Owned' feature. You can find this in your PrestaShop back office under Catalog > Attributes & Features > Features.

Step 2: Modify the Twig Email Template

Once your custom module is active and injecting the 'company_owned' variable into the list_products array, you need to update the email template to display it.

  1. Copy the Template: To avoid modifying the module's original template directly (which could be overwritten during updates), copy prestashop/mails/themes/classic/modules/ps_emailalerts/new_order.html.twig to your active theme's mail directory. For example, if your theme is 'classic', copy it to themes/classic/mails/modules/ps_emailalerts/new_order.html.twig. PrestaShop will prioritize templates found in your active theme.
  2. Edit the Template: Open the copied new_order.html.twig file and locate the product table section. You'll need to add a new table header () and a corresponding table data cell () within the product loop.

        {% for product in list_products %}
        
        {% endfor %}
    
{{ 'Reference'|trans({}, 'Emails.Body', locale)|raw }} {{ 'Product'|trans({}, 'Emails.Body', locale)|raw }} {{ 'Company Owned'|trans({}, 'Emails.Body', locale)|raw }} {{ 'Unit price'|trans({}, 'Emails.Body', locale)|raw }} {{ 'Quantity'|trans({}, 'Emails.Body', locale)|raw }} {{ 'Total price'|trans({}, 'Emails.Body', locale)|raw }}
{{ product.reference }} {{ product.product_name }} {{ product.company_owned }} {{ product.unit_price }} {{ product.quantity }} {{ product.total_price }}

Best Practices and Considerations

  • Clear Cache: After making any code or template changes, always clear your PrestaShop cache (Advanced Parameters > Performance) to ensure your modifications take effect.
  • Testing: Thoroughly test the email sending process by placing a new order. Check both the HTML and plain text versions of the email.
  • Multi-language: If your shop supports multiple languages, ensure your custom feature values are correctly translated and displayed for each locale. The trans filter in Twig is crucial for static text.
  • Performance: While loading product features for each item in an order is generally efficient, be mindful of the number of database queries if you're fetching complex data for hundreds of products in a single email.
  • Migration Readiness: When considering a PrestaShop migration, custom modules and carefully managed template overrides are far easier to transfer and adapt than core hacks. At Migrate My Shop, we specialize in handling such customizations during platform transitions, ensuring your unique business logic remains intact.

Conclusion

Customizing PrestaShop email templates to include specific product features is a powerful way to enhance both customer experience and internal operational efficiency. By following best practices – utilizing custom modules and theme overrides – you can extend your PrestaShop store's capabilities without compromising its stability or upgrade path.

While the initial forum query highlighted the complexity, a structured approach involving PHP logic to prepare data and Twig templating to render it makes this task manageable for developers. If you're planning a PrestaShop migration or need expert assistance with complex customizations, don't hesitate to reach out to the specialists at Migrate My Shop. We're here to ensure your e-commerce journey is smooth and successful.

Share:

Start with the tools

Explore migration tools

See options, compare methods, and pick the path that fits your store.

Explore migration tools