0

I have a Raw Controller where i load products in based on a search. Now i need this to be without JS and css (therefor the RAW type) because i will load that into my page later on with ajax.

This is the fastest way that i came up with to do this.

BUT , It is really hard to implement blocks and childblocks into the Raw Controller. I would prefer it much more if i could use an XML for that.

So how would i do that exactly?

Code now :

 public function execute()
    {
   $layout = $this->_template->getLayout();

        $html = '<div class="container mx-auto productsrow">';
        $html .= '<div class="row no-gutters">';
        $html .= $this->_template->setAttribute("class", 'page-products')->toHtml();
 $html .= $layout->createBlock('Vendor\Module\Block\Search\Products')->setTemplate('Vendor_Module::searchproducts.phtml')->toHtml();
        $html .= '</div>';
        $html .= '</div>';



        $this->_translateInline->processResponseBody($html);

        $result = $this->_resultRawFactory->create();
        $result->setContents($html);

        return $result;
}

As you can see i need to manually create blocks etc to have in my controller since its a raw controller.

But isn't here a way how to have a raw controller but still use an XML OR use a page controller but exclude all css/js so the page loads really fast.

2 Answers 2

1

You can to use layout handle in the custom controller (replace $handle and $blockName to your values):

/** @var \Magento\Framework\View\Result\PageFactory */
protected $pageFactory;

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

/**
 * @return \Magento\Framework\Controller\ResultInterface
 */
public function execute()
{
    /** @var \Magento\Framework\View\Result\Page $page */
    $page = $this->pageFactory->create();
    $page->addHandle($handle); // for example, wishlist_index_index

    /** @var \Magento\Framework\View\Element\AbstractBlock $block */
    $block = $page->getLayout()->getBlock($blockName); // block name in the layout

    /** @var \Magento\Framework\Controller\Result\Raw $result */
    $result = $this->resultFactory->create($this->resultFactory::TYPE_RAW);
    $result->setContents($block ? $block->toHtml() : '');

    return $result;
}

I'm not sure this approach most correct and fastest, but it is works very well on my ajax requests. Write me if you'll have any issues.

1
  • I actually found a really nice solution myself that i will post later on. But thanks for you input! Nov 19, 2017 at 16:31
0

What i end up doing was the following :

 public function execute()
    {
   $layout = $this->_template->getLayout();
        $layout->getUpdate()->addHandle('search_custom');
        $layout->generateXml();
  $html = '<div class="row no-gutters">';
        $html .= $layout->getOutput();
        $html .= '</div>';
 $result = $this->_resultRawFactory->create();
        $result->setContents($html);

        return $result;
    }

You can do all kind of neat things with this like lets say we have the next search_custom.xml (you need to have the custom page layout search_custom since we add that handle) : search_custom.xml :

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">

    <body>
<attribute name="class" value="page-products"/>
        <container name="content">
                <block class="Magento\CatalogSearch\Block\SearchResult\ListProduct" name="search_result_list" template="Magento_Catalog::product/list.phtml" cacheable="false">
                    <arguments>
                        <!-- If argument's position depends on image size changeable in VDE:
                        positions:list-secondary,grid-secondary,list-actions,grid-actions,list-primary,grid-primary
                    -->
                        <argument name="positioned" xsi:type="string">positions:list-secondary</argument>
                    </arguments>
                    <action method="setToolbarBlockName">
                        <argument name="name" xsi:type="string">product_list_toolbar</argument>
                    </action>
                    <block class="Magento\Framework\View\Element\RendererList" name="category.product.type.details.renderers" as="details.renderers">
                        <block class="Magento\Framework\View\Element\Template" as="default"/>
                    </block>
                    <block class="Magento\Catalog\Block\Product\ProductList\Item\Container" name="catalogsearch.product.addto" as="addto">
                        <block class="Magento\Catalog\Block\Product\ProductList\Item\AddTo\Compare"
                               name="catalogsearch.product.addto.compare" as="compare"
                               template="Magento_Catalog::product/list/addto/compare.phtml"/>
                    </block>
                </block>
        </container>
    </body>
</page>

Index.php adjusted:

/**
 * function with my own custom search with getList() and filters to get the right product collection
 *
 */
$products = $this->_products->getProducts($_GET['inputvalue']);
$idarray = array();

/*
 * Abstract collection uses ID's so we get all the ID's
 */
foreach ($products as $product){
    $productid = $product->getId();
    if (isset($productid)) {
        $idarray[] = $productid;
    }
}

/**
 * use the ID's to create a new product collection
 */
$productcollection =
    $this->productCollection
        ->addIdFilter($idarray)
        ->addFieldToSelect('*');

$list = $layout->getBlock('search_result_list');
/**
 * We can set the product collection with our own
 */
$list->setProductCollection($productcollection);
$list->setUseToolbar(false);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.