I have created a custom attribute for customers. In the next step I want to access it in email templates. For example in the password forgotten template.

The variable "customer" contains the following information:

            [email] => doe@example.com
            [firstname] => John
            [lastname] => Doe
            [prefix] => Mr.
            [gender] => 0
            [store_id] => 1
            [website_id] => 1
            [addresses] => Array

            [disable_auto_group_change] => 0
            [custom_attributes] => Array
                    [0] => Array
                            [attribute_code] => my_custom_attribute
                            [value] => 1234


            [name] => John Doe

The only way that works is to use {{var customer.custom_attributes.0.value}}. But this doesn't seem to be a reasonable way, because the array key "0" is not reliably the one of my_custom_attribute.

How can I access my_custom_attribute reliable?

side note: Creating a plugin for the EmailNotification::getFullCustomerData() method doesn't work either, because this method is private.

  • Did you find a solution for it? I have found a way for it.
    – ZealousWeb
    Mar 4, 2021 at 11:32

2 Answers 2


To achieve this we need to pass dynamic data through handle.First this is my data which i got in "custom_attributes" - https://prnt.sc/10cvmir

Please follow below steps.Please create any named layout file in any of your module , here i have created "custom_attribute_email.xml"

Step 1: Please create file "custom_attribute_email.xml" under path PackageName/Vendor/view/frontend/layout

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd" label="Email Product List" design_abstraction="custom">
        <block class="Magento\Framework\View\Element\Template" name="additional.customer.info" template="PackageName_Vendore::customer/email.phtml"/>

Step 2: Please create email.phtml file under path PackageName/Vendor/view/frontend/templates/customer

<?php $customer = $block->getCustomer(); ?>
<?php foreach ($customer['custom_attributes'] as $key => $data): ?>
    <p><strong><?php echo $data['attribute_code']; ?></strong>:<span><?php echo $data['value']; ?></span></p>
<?php endforeach; ?>

Now please open any of your email template , here i have taken forgot password email template. Then in your email template add the below code like this - https://prnt.sc/10cvqqh

{{layout handle="custom_attribute_email" customer=$customer area="frontend"}}

Note : Your template variable customer should be object

Output will be :- https://prnt.sc/10cvg97

This code will perfectly work for you. Please change code in phtml file according to your need. Please check and let me know on this.

Thanks Cheers!

  • Does this work with Version 2.4.2? $block->getCustomer() returns always null. :( [Trying to access array offset on value of type null]
    – ulbiopro
    Mar 4, 2021 at 13:17
  • Yes , it will work.Your template variable customer object should be passed like this {{layout handle="custom_attribute_email" customer=$customer area="frontend"}}
    – ZealousWeb
    Mar 4, 2021 at 13:39
  • Please follow all steps to make it work. I have practically checked after that i have posted here.
    – ZealousWeb
    Mar 4, 2021 at 13:40
  • Got it: It only works with template files. If I set up a template via Backend, it won't work. Can you confirm this?
    – ulbiopro
    Mar 4, 2021 at 13:43
  • Yes , it won't work. I have shown you just for front end according to your requirement.
    – ZealousWeb
    Mar 4, 2021 at 13:45

This is a reasonably well answer, but not as comprehensive as I want it to be. The custom attributes are only accessable with template files, not with templates that are user defined

I created a plugin for Magento\Framework\Reflection\CustomAttributesProcessor which isn't the perfect way I guess, but much more versatile. It replaces the array_keys with the corresponding attribute_code, so you can access it via {{var customer.custom_attributes.my_custom_attribute.value}}

As far as I can tell, it doesn't break anything else either.


<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <!-- creates accessable custom attribute keys with attribute code -->
    <type name="Magento\Framework\Reflection\CustomAttributesProcessor">
        <plugin name="Vendor_Module_Reflextion_CustomAttributesProcessorPlugin" type="Vendor\Module\Plugin\Reflection\CustomAttributesProcessorPlugin" sortOrder="10" />



namespace Vendor\Module\Plugin\Reflection;

use Magento\Framework\Api\AttributeValue;

 * creates DataOutputArray which is reliable accessible from email templates
class CustomAttributesProcessorPlugin
  public function afterBuildOutputDataArray($subject, $result) {
    $customAttributes = [];
    foreach ($result as $attribute) {
        $customAttributes[$attribute[AttributeValue::ATTRIBUTE_CODE]] = 
            AttributeValue::VALUE => $attribute[AttributeValue::VALUE],
            AttributeValue::ATTRIBUTE_CODE => $attribute[AttributeValue::ATTRIBUTE_CODE]

    return $customAttributes;

Can anyone confirm?

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.