Email template is not defined when try to send custom email
-
17-01-2021 - |
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>
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.