Want to add some text/content in order email which is dependent on order data.

For this I want to call a template file, where I can get the order data and based on that I want to perform my calculation.

How can I call this template in order email ?


You can achieve this from just a block calling from email and pass the order variable in that block and do you calculation like : in email template just use this to call block

{{block class="Magento\Framework\View\Element\Template" order=$order name="order_sms" template="[vendor]_[module]::[filename].phtml" area="frontend"}}

And in your [vendor]/[module]/[frontend]/[templates]/[filename].phtml

$order = $this->getData('order');

After this you can perform your calculation and write your html here.

  • In {{.. order=$order ..}} do we access/get the $order-variable from [filename].phtml ? Or do we set the $order-variable for [fielname].phtml ? – Blackpanther0001 Dec 24 '16 at 16:42
  • report.DEBUG: NULL [] [], I can't get order details this way. – MagentoAaron Jul 31 '20 at 20:41
  • @MagentoAaron, since Magento 2.3.4+ you can't get order data like this anymore unforunately. You will additionaly need to go to email_templates and for the desired email template put "1" in the field "is_legacy". Then this answer works, but this might change in v. 2.4+ – Lez Aug 3 '20 at 14:31
  • @Lez thanks for the reply. I have an open question for this if you have any ideas, I'm still stuck trying to get the order data - magento.stackexchange.com/questions/318841/… – MagentoAaron Aug 3 '20 at 15:26
  • @MagentoAaron I'm not sure what RMA auth email is, so I can't help there. But if the template doesn't have order data in general, you would first have to bring that data to the template before you can use it in an inserted block. My suggestion would be to analyze how Magento core does this and go from there. – Lez Aug 4 '20 at 7:55

A quick reference:

Take a look:


protected function prepareTemplate(Order $order)
        $transport = [
            'order' => $order,
            'billing' => $order->getBillingAddress(),
            'payment_html' => $this->getPaymentHtml($order),
            'store' => $order->getStore(),
            'formattedShippingAddress' => $this->getFormattedShippingAddress($order),
            'formattedBillingAddress' => $this->getFormattedBillingAddress($order),
        $transport = new \Magento\Framework\DataObject($transport);

            ['sender' => $this, 'transport' => $transport]



As we can see, Magento passes some dynamic transport data to the template email.

We can get the email customer note var order.getEmailCustomerNote() or var order.getShippingDescription().

<!--@subject {{trans "Your %store_name order confirmation" store_name=$store.getFrontendName()}} @-->
<!--@vars {
"var formattedBillingAddress|raw":"Billing Address",
"var order.getEmailCustomerNote()":"Email Order Note",
"var order.increment_id":"Order Id",
"layout handle=\"sales_email_order_items\" order=$order area=\"frontend\"":"Order Items Grid",
"var payment_html|raw":"Payment Details",
"var formattedShippingAddress|raw":"Shipping Address",
"var order.getShippingDescription()":"Shipping Description"
"var shipping_msg":"Shipping message"
} @-->
{{layout handle="sales_email_order_items" order=$order area="frontend"}}

The layout handle will load the layout vendor/magento/module-sales/view/frontend/layout/sales_email_order_items.xml. So, we can override the layout and template of order email items or define our own layouts and templates.

For customization purpose, Magento gives us some Observer events. We can use these events to add more data to our template.


We should see more in vendor/magento/module-sales/Model/Order/Email


This was my method for getting product attributes into my email template. I utilize the productRepositoryInterface to pull custom attributes that we store as JSON strings.

Our business uses core charges (like when you buy a battery at an auto parts store). So we needed to display what the total core charge would be for items in the cart. We also needed to show Important notes that are stored in a particular section of a JSON string that we store in a custom product attribute.

I call the block and phtml file in my email template:

{{block class="[VENDOR]\[MODULE]\Block\CoresEmail" order=$order name="custom_attribute_stuff" template="[vendor]_[module]::emailcores.phtml" area="frontend"}}

And this in the emailcores.phtml file

$order = $this->getData('order')->getItems();

$items = [];
$corebank = 0;
$notes = [];

foreach ($order as $items){
    $items = $items->getData();

    $id = $items['product_id'];

    if ($id){
        $core = $block->getCoreTotal($id);
        array_push($notes, $block->getProductImportantNotes($id)) ;
        $corebank = $core + $corebank;

<table width="100%" style="padding-right: 10px;">
        <td style="padding: 10px;">
            <?php if($notes): ?>
                <p style="font-weight: bold;">Important Notes:</p>
               <?php foreach ($notes as $note): ?>
                   <?php foreach ($note as $detail): ?>
                        <li><?= $detail ?></li>
                   <?php endforeach; ?>
                <?php endforeach; ?>
            <?php endif; ?>
        <td style="padding: 10px;">
            <p style="text-align: right; font-weight: bold;">Core Deposit:     $<?= $corebank ?>.00</p>
            <p style="text-align: right;"><i>* Core deposit not reflected in order total.</i></p>

And then my CoresEmail.php block file contains this:


namespace [VENDOR]\[MODULE]\Block;

use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;

class CoresEmail extends Template

    protected $productRepository;

     * Constructor
     * @param Context $context
     * @param array   $data
    public function __construct(
        Context $context,
        \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
        array $data = []
    ) {
        parent::__construct($context, $data);
        $this->_product = $productRepository;

    public function getCoreTotal($id)
        $coretotal = 0;

            $coredeposit = json_decode($this->_product->getById($id)->getEteCoreDeposit(), true);
            try {$core = $coredeposit;} catch (\Exception $ex) {$core = [];}
            if ($core){
                $coretotal = $coretotal + $core;

        return $coretotal;

    public function getProductImportantNotes($id)
        $note_array = [];
        $product = json_decode($this->_product->getById($id)->getPiesDescriptions(), true);
        try {$pies = $product;} catch (\Exception $ex) {$pies = [];}
        if ($pies){
            $note_array = str_getcsv($pies['EXT']);
            return $note_array;
        } else {
            return $note_array;

This produces the following result in a new order email: Screenshot of sucessful product attribute pulled into order email template

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.