cancel
Showing results for 
Search instead for 
Did you mean: 

Email template with block

   Did you know you can see the translated content as per your choice?

Translation is in progress. Please check again after few minutes.

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();
    }

    ...

}