cancel
Showing results for 
Search instead for 
Did you mean: 

Email template with block

Email template with block

Hi everybody:

 

I'm developing a new module, and I'm stuck trying to insert a block in my email template. I need to loop over a product list array in that template. Because there is no way to loop there I've trying to do it using a block.

 

I have tried to call the block in this way:

 

{{block class="Magento\\Framework\\View\\Element\\Template" type="core/template" area="frontend" template="Slx_Lowstocknotifier::email/low_stock_product_table.phtml" }}

 

 Where Slx_Lowstocknotifier is my module name. And low_stock_product_table.phtml is inside my module folder in view/frontend/templates/email/low_stock_product_table.phtml

 

When magento is trying to compose the email, it fails getting this trace in system.log:

 

[2016-03-11 10:54:34] main.CRITICAL: Invalid template file: 'Slx_Lowstocknotifier::email/low_stock_product_table.phtml' in module: '' block's name: 'magento\framework\view\element\template_0' [] []

 

 

Any ideas? Is there other way to insert a block there?

 

 

Thanks in advance.

9 REPLIES 9

Re: Email template with block

In which situations do you send the email?

Re: Email template with block

Hi,

 

 

At the moment I'm sending it from a console command. If I don't use the block the email is sent correctly.

 

 

Thanks again.

Re: Email template with block

Maybe your console command use another area, not frontend?
Try to remove the area="frontend" declaration and move the template from the frontend folder to the base folder.

Re: Email template with block

Hi again:

 

 

I have been trying your solution but it di not resolve the problem. I made a trace in  

Magento\Framework\View\Element\Template.php

And looking in:

protected function _toHtml()
{
if (!$this->getTemplate()) {
return '';
}
return $this->fetchView($this->getTemplateFile());
}

 I can see the file is trying to fetch is correct, the path is correct.

 

Now I'm getting the following exception: 

 

[2016-03-14 08:59:38] main.CRITICAL: exception 'BadMethodCallException' with message 'Missing required argument $debugHintsPath of Magento\Developer\Model\TemplateEngine\Plugin\DebugHints.' in /proyectos/demo2-tienda/codigo/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:45
Stack trace:
#0 /proyectos/demo2-tienda/codigo/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php(82): Magento\Framework\ObjectManager\Factory\Dynamic\Developer->_resolveArguments('Magento\\Develop...', Array, Array)
#1 /proyectos/demo2-tienda/codigo/vendor/magento/framework/ObjectManager/ObjectManager.php(71): Magento\Framework\ObjectManager\Factory\Dynamic\Developer->create('Magento\\Develop...')
#2 /proyectos/demo2-tienda/codigo/vendor/magento/framework/Interception/PluginList/PluginList.php(234): Magento\Framework\ObjectManager\ObjectManager->get('Magento\\Develop...')
#3 /proyectos/demo2-tienda/codigo/vendor/magento/framework/Interception/Interceptor.php(149): Magento\Framework\Interception\PluginList\PluginList->getPlugin('Magento\\Framewo...', 'debug_hints')
#4 /proyectos/demo2-tienda/codigo/var/generation/Magento/Framework/View/TemplateEngineFactory/Interceptor.php(26): Magento\Framework\View\TemplateEngineFactory\Interceptor->___callPlugins('create', Array, Array)
#5 /proyectos/demo2-tienda/codigo/vendor/magento/framework/View/TemplateEnginePool.php(44): Magento\Framework\View\TemplateEngineFactory\Interceptor->create('phtml')
#6 /proyectos/demo2-tienda/codigo/vendor/magento/framework/View/Element/Template.php(255): Magento\Framework\View\TemplateEnginePool->get('phtml')
#7 /proyectos/demo2-tienda/codigo/vendor/magento/framework/View/Element/Template.php(281): Magento\Framework\View\Element\Template->fetchView('/proyectos/demo...')
#8 /proyectos/demo2-tienda/codigo/vendor/magento/framework/View/Element/AbstractBlock.php(652): Magento\Framework\View\Element\Template->_toHtml()
#9 /proyectos/demo2-tienda/codigo/vendor/magento/module-email/Model/Template/Filter.php(366): Magento\Framework\View\Element\AbstractBlock->toHtml()
#10 [internal function]: Magento\Email\Model\Template\Filter->blockDirective(Array)
#11 /proyectos/demo2-tienda/codigo/vendor/magento/framework/Filter/Template.php(141): call_user_func(Array, Array)
#12 /proyectos/demo2-tienda/codigo/vendor/magento/module-email/Model/Template/Filter.php(963): Magento\Framework\Filter\Template->filter('{{template conf...')
#13 /proyectos/demo2-tienda/codigo/vendor/magento/module-email/Model/AbstractTemplate.php(352): Magento\Email\Model\Template\Filter->filter('{{template conf...')
#14 /proyectos/demo2-tienda/codigo/vendor/magento/module-email/Model/Template.php(375): Magento\Email\Model\AbstractTemplate->getProcessedTemplate(Array)
#15 /proyectos/demo2-tienda/codigo/vendor/magento/framework/Mail/Template/TransportBuilder.php(273): Magento\Email\Model\Template->processTemplate()
#16 /proyectos/demo2-tienda/codigo/vendor/magento/framework/Mail/Template/TransportBuilder.php(227): Magento\Framework\Mail\Template\TransportBuilder->prepareMessage()
#17 /proyectos/demo2-tienda/codigo/app/code/Solucionex/Lowstocknotifier/Console/Command/LowStockCommand.php(106): Magento\Framework\Mail\Template\TransportBuilder->getTransport()
#18 /proyectos/demo2-tienda/codigo/app/code/Solucionex/Lowstocknotifier/Console/Command/LowStockCommand.php(119): Solucionex\Lowstocknotifier\Console\Command\LowStockCommand->sendEmail(Array)
#19 /proyectos/demo2-tienda/codigo/vendor/symfony/console/Symfony/Component/Console/Command/Command.php(257): Solucionex\Lowstocknotifier\Console\Command\LowStockCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#20 /proyectos/demo2-tienda/codigo/vendor/symfony/console/Symfony/Component/Console/Application.php(874): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#21 /proyectos/demo2-tienda/codigo/vendor/symfony/console/Symfony/Component/Console/Application.php(195): Symfony\Component\Console\Application->doRunCommand(Object(Solucionex\Lowstocknotifier\Console\Command\LowStockCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#22 /proyectos/demo2-tienda/codigo/vendor/magento/framework/Console/Cli.php(49): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#23 /proyectos/demo2-tienda/codigo/vendor/symfony/console/Symfony/Component/Console/Application.php(126): Magento\Framework\Console\Cli->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#24 /proyectos/demo2-tienda/codigo/bin/magento(25): Symfony\Component\Console\Application->run()
#25 {main} [] []

I created a controller action with the same logic and it is working perfect, so I suppose it is something related to the templates and commands.  Furthermore I set the area in the command controller:

 

public function __construct(
\Magento\Framework\App\State $state,
\Magento\Framework\ObjectManagerInterface $objectManager,
\Magento\Framework\Mail\Template\TransportBuilder $transportBuilder,
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
\Magento\Store\Model\StoreManagerInterface $storeManager
)
{
$this->objectManager = $objectManager;
$this->transportBuilder = $transportBuilder;
$this->scopeConfig = $scopeConfig;
$this->storeManager = $storeManager;

$state->setAreaCode('frontend');
parent::__construct();
}

 

Thanks again.

 

 

 

 

 

 

Re: Email template with block

Hi,

 

Did you manage to find a solution to your problem?

 

I have a very similar issue..

 

I have a command that fetch data from a warehouse management system and process orders.

 

I try to send an email with the tracking number but when I do I get the same error as you:

 

 

string(102) "Missing required argument $debugHintsPath of Magento\Developer\Model\TemplateEngine\Plugin\DebugHints."

 

I do set up my area code to frontend.

 

$this->state->setAreaCode('frontend');

 

But when I try to send the email I get the error above.

 

try {
$this->orderSender->send($order_instance);
} catch (\Exception $e) {
var_dump($e->getMessage());
die();
}

I really don't understand why I get this error...

 

Re: Email template with block

Hi AHeaven-1, I was struggling with the same issue, this seemed to work for me: 

 

$state->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL);

If you don't plan on using the state class beyond the constructor I would not even bother assigning it to $this eg:

private $_transportBuilder;

    public function __construct(
        \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder,
        \Magento\Framework\App\State $state
    ){

        $state->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL);
        $this->_transportBuilder = $transportBuilder;
    }

Finally if you intend running this command as a cron job, using magento's cron feature may be a bit more eloquent than using the command line directly.

Re: Email template with block

Hey AHeaven-1,

Have you been able to fix this issue? I tried Zengoma's fix, setting the area code to both global and frontend, but I am still getting the error. I set up a controller with the same code, and the email sends fine when I go to the route. However, when I call that controller in my cron job, it gives me the error once more.

 

Any help would be greatly appreciated.

Re: Email template with block

What worked for me was the following:


$this->_objectManager->configure($this->_configLoader->load('adminhtml'));

 

This was occurring for me in a test script that I simply use for testing during development:

 

class TestApp
extends \Magento\Framework\App\Http
implements \Magento\Framework\AppInterface {
/**
* @param \Magento\Framework\ObjectManagerInterface $objectManager
* @param Event\Manager $eventManager
* @param AreaList $areaList
* @param RequestHttp $request
* @param ResponseHttp $response
* @param ConfigLoaderInterface $configLoader
* @param State $state
* @param Filesystem $filesystem,
* @param \Magento\Framework\Registry $registry
*/
public function __construct(
\Magento\Framework\ObjectManagerInterface $objectManager,
Event\Manager $eventManager,
AreaList $areaList,
RequestHttp $request,
ResponseHttp $response,
ConfigLoaderInterface $configLoader,
State $state,
Filesystem $filesystem,
\Magento\Framework\Registry $registry
) {
parent::__construct($objectManager, $eventManager, $areaList, $request, $response, $configLoader, $state, $filesystem, $registry);

$this->_state->setAreaCode('adminhtml');
$this->_objectManager->configure($this->_configLoader->load('adminhtml'));
}

 

Adding the $this->_objectManager->configure line solved the issue for me. It dictates that the di.xml directive set in vendor/magento/module-developer/etc/adminhtml/di.xml is loaded. For the frontend, the same would need to be done, replacing 'adminhtml' with 'frontend' (I think that would be it, haven't tested that)

Re: Email template with block - Working Solution

The solution from @dunagan5887 is confirmed to be working.

 

In my case it was used for the frontend area.

 

Please find a working version command line class below:

 

<?php
namespace NameSpace\Module\Console\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Magento\Framework\Exception\LocalizedException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class CustomCommandClass extends Command
{
    public function __construct(
        \Magento\Framework\App\State $state,
        \Magento\Framework\ObjectManagerInterface $objectManager,
        \Magento\Framework\ObjectManager\ConfigLoaderInterface $configLoader
    ) {
        $state->setAreaCode('frontend');
        $objectManager->configure($configLoader->load('frontend'));
        parent::__construct();
    }

    ...

}