Question

I created a module to send a custom email, but when i send the email i always got an error like this:

Email template '' is not defined.

app/code/Blob/Withdrawal/etc/adminhtml/system.xml

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <section id="my_mobile_app">
            <tab>blob</tab>
            <resource>Blob_Withdrawal::config_blob_withdrawal</resource>
            <group id="withdrawal" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="10" translate="label">
                <label>Withdrawal</label>
                <field id="request_mail" translate="label comment" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
            <label>Request E-mail Template</label>
            <comment>Email template chosen based on theme fallback when "Default" option is selected.</comment>
            <source_model>Magento\Config\Model\Config\Source\Email\Template</source_model>
        </field>
                <field id="approve_mail" translate="label comment" type="select" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
            <label>Approve E-mail Template</label>
            <comment>Email template chosen based on theme fallback when "Default" option is selected.</comment>
            <source_model>Magento\Config\Model\Config\Source\Email\Template</source_model>
        </field>
                <field id="reject_mail" translate="label comment" type="select" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="1">
            <label>Reject E-mail Template</label>
            <comment>Email template chosen based on theme fallback when "Default" option is selected.</comment>
            <source_model>Magento\Config\Model\Config\Source\Email\Template</source_model>
        </field>
            </group>
        </section>
    </system>
</config>

app/code/Blob/Withdrawal/etc/config.xml

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
    <default>
        <my_mobile_app>
            <withdrawal>
                <request_mail/>
                <approve_mail/>
                <reject_mail/>
            </withdrawal>
        </my_mobile_app>
    </default>
</config>

app/code/Blob/Withdrawal/etc/email_templates.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Email:etc/email_templates.xsd">
    <template id="my_mobile_app_withdrawal_request_mail" label="Request E-mail Template" file="request_email.html" type="html" module="Blob_Withdrawal" area="adminhtml"/>
    <template id="my_mobile_app_withdrawal_approve_mail" label="Approve E-mail Template" file="approve_email.html" type="html" module="Blob_Withdrawal" area="adminhtml"/>
    <template id="my_mobile_app_withdrawal_reject_mail" label="Reject E-mail Template" file="reject_email.html" type="html" module="Blob_Withdrawal" area="adminhtml"/>
</config>

app/code/Blob/Withdrawal/Helper/Email.php

     const XML_PATH_EMAIL_TEMPLATE_FIELD_REQUEST  = 'my_mobile_app/withdrawal/request_mail';
     const XML_PATH_EMAIL_TEMPLATE_FIELD_APPROVE  = 'my_mobile_app/withdrawal/approve_mail';
     const XML_PATH_EMAIL_TEMPLATE_FIELD_REJECT  = 'my_mobile_app/withdrawal/reject_mail';

     public function __construct(
        \Magento\Framework\App\Helper\Context $context,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation,
        \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder
    ) {
        $this->_scopeConfig = $context;
        parent::__construct($context);
        $this->_storeManager = $storeManager;
        $this->inlineTranslation = $inlineTranslation;
        $this->_transportBuilder = $transportBuilder;
    }

    protected function getConfigValue($path, $storeId)
    {
        return $this->scopeConfig->getValue(
            $path,
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
            $storeId
        );
    }


    public function getStore()
    {
        return $this->_storeManager->getStore();
    }


    public function getTemplateId($xmlPath)
    {
        return $this->getConfigValue($xmlPath, $this->getStore()->getStoreId());
    }

    public function generateTemplate($emailTemplateVariables,$senderInfo,$receiverInfo)
    {
        $template =  $this->_transportBuilder->setTemplateIdentifier($this->temp_id)
                ->setTemplateOptions(
                    [
                        'area' => \Magento\Framework\App\Area::AREA_ADMINHTML, /* here you can defile area and
                                                                                 store of template for which you prepare it */
                        'store' => $this->_storeManager->getStore()->getId(),
                    ]
                )
                ->setTemplateVars($emailTemplateVariables)
                ->setFrom($senderInfo)
                ->addTo($receiverInfo['email'],$receiverInfo['name']);
        return $this;
    }

    public function sendMail($emailTemplateVariables,$senderInfo,$receiverInfo,$type)
    {
        if ($type == 'request') {
          $typeId = self::XML_PATH_EMAIL_TEMPLATE_FIELD_REQUEST;
        } elseif ($type == 'approve') {
          $typeId = self::XML_PATH_EMAIL_TEMPLATE_FIELD_APPROVE;
        } else{
          $typeId = self::XML_PATH_EMAIL_TEMPLATE_FIELD_REJECT;
        }
        $this->temp_id = $this->getTemplateId($typeId);
        $this->inlineTranslation->suspend();
        $this->generateTemplate($emailTemplateVariables,$senderInfo,$receiverInfo);
        $transport = $this->_transportBuilder->getTransport();
        $transport->sendMessage();
        $this->inlineTranslation->resume();
    }

app/code/Blob/Withdrawal/view/adminhtml/email/approve_email.html app/code/Blob/Withdrawal/view/adminhtml/email/reject_email.html app/code/Blob/Withdrawal/view/adminhtml/email/request_email.html

<!--@subject Credit Withdrawal @-->


<!--@styles
body,td { background:#FFFFFF; margin:0; padding:0; color:#2f2f2f; font:13px/1.35em Verdana, Arial, Helvetica, sans-serif; }
pre{ white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;}
@-->
{{template config_path="design/email/header_template"}}
<div style="font:13px/1.35em Verdana, Arial, Helvetica, sans-serif;">
    <table cellspacing="0" cellpadding="0" border="0" width="98%"
           style="margin-top:10px; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; margin-bottom:10px;">
        <tr>
            <td align="center" valign="top">
                <!-- [ middle starts here] -->
                <table cellspacing="0" cellpadding="0" border="0" width="660">
                    <tr>
                        <td valign="top">
                            <p>
                                hello
                            </p>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
</div>
Was it helpful?

Solution

Fill your email template default config value in etc/config.xml file with email template id which has been defined in etc/email_templates.xml file. in your case:

app/code/Blob/Withdrawal/etc/email_templates.xml

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
    <default>
        <my_mobile_app>
            <withdrawal>
                <request_mail>my_mobile_app_withdrawal_request_mail</request_mail>
                <approve_mail>my_mobile_app_withdrawal_approve_mail</approve_mail>
                <reject_mail>my_mobile_app_withdrawal_reject_mail</reject_mail>
            </withdrawal>
        </my_mobile_app>
    </default>
</config>

OTHER TIPS

Send custom email in magento 2.

app/code/Test/Testmail/etc/email_templates.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:Magento:module:Magento_Email:etc/email_templates.xsd">
    <template id="testmail_section_testmail_email_testmail_email_template" label="Test Email" file="email_template.html" type="html" module="Test_Testmail" area="frontend"/>
</config>

app/code/Test/Testmail/etc/adminhtml/system.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <tab id="testmail" translate="label" sortOrder="10">
            <label>Test Email</label>
        </tab>
        <section id="testmail_section" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1">
            <class>separator-top</class>
            <label>Test Email</label>
            <tab>testmail</tab>
            <resource>Test_Testmail::testmail</resource>
             <group id="testmail_email" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                 <label>Email Options</label>
                <field id="testmail_recipient_email" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
                    <label>Send Emails To</label>
                    <validate>validate-email</validate>
                </field>
                <field id="testmail_sender_email_identity" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
                    <label>Email Sender</label>
                    <source_model>Magento\Config\Model\Config\Source\Email\Identity</source_model>
                </field>
                 <field id="testmail_email_template" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
                    <label>Email Template</label>
                    <comment>Email template chosen based on theme fallback when "Default" option is selected.</comment>
                    <source_model>Magento\Config\Model\Config\Source\Email\Template</source_model>
                </field>
            </group>
        </section>
    </system>
</config>

app/code/Test/Testmail/Controller\Index\Send.php

    public function execute()
    {
        $productId = $this->getRequest()->getParam('productid');
        $name = $this->getRequest()->getParam('name');
        $phone = $this->getRequest()->getParam('phone');
        $email = $this->getRequest()->getParam('emailid');

        $this->testmailFactory->create()->setProductId($productId)->setName($name)->setPhone($phone)->setEmail($email)->save();

        $productname = $this->product->create()->load($productId);
        $productname = $productname->getName();
        $data = array('productname' => $productname, 'name' => $name, 'email' => $email, 'phone' => $phone);

        $this->_helper->sendemail($data);
    }

app/code/Test/Testmail/Helper/Sendemail.php

    public function sendemail($data)
    {
        $toemail = $this->_scopeConfig->getValue('testmail_section/testmail_email/testmail_recipient_email');
        $productname = $data['productname'];
        $name = $data['name'];
        $email = $data['email'];
        $phone = $data['phone'];

        $template = $this->_scopeConfig->getValue('testmail_section/testmail_email/testmail_email_template');

        $store = $this->_storeManager->getStore()->getId();
        $transport = $this->_transportBuilder->setTemplateIdentifier($template)
            ->setTemplateOptions(['area' => 'frontend', 'store' => $store])
            ->setTemplateVars(
                [
                    'store' => $this->_storeManager->getStore(),
                    'productname' => $productname,
                    'name' => $name,
                    'email' => $email,
                    'phone' => $phone,
                ]
            )
            ->setFrom('general')
        // you can config general email address in Store -> Configuration -> General -> Store Email Addresses
            ->addTo($toemail)
            ->getTransport();
        $transport->sendMessage();

    }

app/code/Test/Testmail/view/frontend/email/email_template.html

<div style="background:#F6F6F6; font-family:Verdana, Arial, Helvetica, sans-serif; font-size:12px; margin:0; padding:0;">

        <table cellspacing="0" cellpadding="0" border="0" width="100%">
                <center><h2>{{trans "~: Test Email's Details :~"}}</h2></center>
            <tr>
                <td align="center" valign="top" style="padding:20px 0 20px 0">
                    <table bgcolor="#FFFFFF" cellspacing="0" cellpadding="10" border="0" width="650" style="border:1px solid #E0E0E0;">

                        <tr>
                            <td><b>{{trans "Product Name :"}}</b></td>
                            <td>{{var productname}}.</td>
                        </tr>
                        <tr>
                            <td><b>{{trans "Name :"}}</b></td>
                            <td>{{var name}}.</td>
                        </tr>
                       <tr>
                            <td><b>{{trans "Email :"}}</b></td>
                            <td>{{var email}}.</td>
                        </tr>
                        <tr >
                            <td><b>{{trans "Mobile Number :"}}</b></td>
                            <td>{{var phone}}.</td>
                        </tr>
                    </table>
                </td>
            </tr>
        </table>
</div>

I hope this will useful for you.:)

Replace your function code like this.

public function sendMail($emailTemplateVariables,$senderInfo,$receiverInfo,$type)
{
    $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE;

    if ($type == 'request') 
    {
       $typeId = $this->_scopeConfig->getValue(self::XML_PATH_EMAIL_TEMPLATE_FIELD_REQUEST,$storeScope);
    } 
    elseif ($type == 'approve') 
    {
       $typeId = $this->_scopeConfig->getValue(self::XML_PATH_EMAIL_TEMPLATE_FIELD_APPROVE,$storeScope);
    } 
    else
    {
      $typeId = $this->_scopeConfig->getValue(self::XML_PATH_EMAIL_TEMPLATE_FIELD_REJECT,$storeScope);
    }
    $this->temp_id = $this->getTemplateId($typeId);
    $this->inlineTranslation->suspend();
    $this->generateTemplate($emailTemplateVariables,$senderInfo,$receiverInfo);
    $transport = $this->_transportBuilder->getTransport();
    $transport->sendMessage();
    $this->inlineTranslation->resume();
}

The issue seems to be that you are not passing template id temp_id in the following code while calling generateTemplate

$this->generateTemplate($emailTemplateVariables,$senderInfo,$receiverInfo);

and also you are not receiving the template id in the function

generateTemplate($emailTemplateVariables,$senderInfo,$receiverInfo)

Pass the value and receive it to fix the issue or declare temp_id as the global class variable.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top