Loading a .phtml File Within an Observer in Magento 2

magento-2.1magento2magento2.2

I'm trying to load my .phtml files in the template folder within my observer but I'm getting this error

Invalid template file: 'VENDOR_MYModule::Category/index.phtml' in module: 'VENDOR_MYModule' block's name: 'category_0'

Here's the structure of my files

app
 + code
    + VENDOR
      + MYModule
        + Block
            - Category.php
        + Controller
            + Category
               - Index.php
        + etc
            + frontend
                - routes.xml
        + Observer
            - CategoryObserver.php
        + view
            + frontend
                + layout
                    - header_category_index.xml
                + templates
                    + category
                        - index.phtml

Now the content of my Block/Category.php is below

<?php
namespace VENDOR\MYModule\Block;

class Category extends \Magento\Framework\View\Element\Template 
{
    public function __construct(
        \Magento\Backend\Block\Template\Context $context,       
        array $data = []
    ){
        parent::__construct($context, $data);
    }

}

The content of my Controller/Category/Index.php is below

<?php
namespace VENDOR\MYModule\Controller\Category;

class Index extends \Magento\Framework\App\Action\Action
{
    protected $_pageFactory;    

    public function __construct(
        \Magento\Framework\App\Action\Context $context, 
        \Magento\Framework\View\Result\PageFactory $pageFactory
    )
    {
        $this->_pageFactory = $pageFactory;     
        return parent::__construct($context);
    }

    public function execute()
    {       
        return $this->_pageFactory->create();
    }   
}

The content of the layout/header_category_index.xml is below

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <referenceContainer name="content">
        <block class="VENDOR\MYModule\Block\Category" name="category_items" template="VENDOR_MYModule::category/index.phtml" />
    </referenceContainer>
</page>

The content of my .phtml is just a simple <h1>Hello world</h1>. Now in my Observer I'm trying to load this .phtml file but I can't load it and getting the error. The content of my Observer Observer\CategoryObserver is below

public function execute(\Magento\Framework\Event\Observer $observer)
{           
    $layout = $this->_layout->create();
    $block = $layout->createBlock('VENDOR\MYModule\Block\Category')->setTemplate('VENDOR_MYModule::Category/index.phtml')->toHtml();        

    $this->_logger->debug("[DEBUG]::" , [$block]);
}

Here's the content of my events.xml

<?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="catalog_category_save_after">
        <observer name="category-edit" instance="VENDOR\MYModule\Observer\CategoryObserver" />
    </event>   
</config>

But I'm getting the error as mentioned above. Any idea on how to load this .phtml file to the observer? I'm planning to write the content of this .phtml file to a .txt file. But I can't proceed since I tried outputting it but I'm still getting an error

UPDATE:

Tried my code using the Frontend controller/action access and the block successfully loaded. Now I think there's another way or implementation when retrieving the .phtml in the Admin part or in the Observer. Also note that the observer is triggered when I try to edit/save a catalog->category.

Best Answer

Change this line:

    $block = $layout->createBlock('VENDOR\MYModule\Block\Category')->setTemplate('VENDOR_MYModule::Category/index.phtml')->toHtml();        

to

    $block = $layout->createBlock('VENDOR\MYModule\Block\Category')->setTemplate('VENDOR_MYModule::category/index.phtml')->toHtml();        

[Update]

<?php
namespace SR\MagentoCommunity\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Event\Observer;

class CatalogCategorySaveAfter implements ObserverInterface
{
    private $layout;

    public function __construct(
        \Magento\Framework\View\Layout $layout
    ) {
        $this->layout = $layout;
    }

    public function execute(Observer $observer)
    {
        $block = $this->layout->createBlock('SR\MagentoCommunity\Block\Category')->setTemplate('SR_MagentoCommunity::category/index.phtml')->toHtml();
        error_log($block);
    }
}

Template location:

app/code/SR/MagentoCommunity/view/base/templates/category/index.phtml

And

app/code/SR/MagentoCommunity/etc/adminhtml/events.xml

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="catalog_category_save_after">
        <observer name="category-edit" instance="SR\MagentoCommunity\Observer\CatalogCategorySaveAfter" />
    </event>
</config>
Related Topic