I am trying to display a block as part of a response to an ajax call. Everything is working except I cannot get the controller to echo the template HTML code.
My module class:
class MyModule_Ajax_ProductController extends Mage_Catalog_ProductController {
public function indexAction() {
if ($product = $this->_initProduct()) {
echo '<div>hello</div>'; //this works
echo $this->getLayout()->createBlock('ajax/product')->setTemplate('mymodule_ajax/product.phtml')->toHtml();
//I also tried:
//$layout = $this->getLayout();
//$update = $layout->getUpdate();
//$update->load('ajax_product_index');
//$layout->generateXml();
//$layout->generateBlocks();
//$output = $layout->getOutput();
//echo $output;
}
}
}
Inside my template file product.phtml - this HTML never gets shown. (saved to app/design/frontend/default/default/template/mymodule_ajax/product.phtml)
<div>HERE!</div>
My block class:
class MyModule_Ajax_Block_Product extends Mage_Catalog_Block_Product
{
private $product;
protected function _construct()
{
parent::_construct();
$this->setTemplate('mymodule_ajax/product.phtml');
}
protected function _toHtml() {
return parent::_toHtml();
}
public function setProduct($product) {
$this->product = $product;
return $this;
}
public function getProduct() {
return $this->product;
}
}
My layout/mymodule_ajax.xml
<?xml version="1.0"?>
<layout>
<ajax_product_index>
<reference name="root">
<block type="ajax/project" name="root" output="toHtml" template="mymodule_ajax/product.phtml"/>
</reference>
</ajax_product_index>
</layout>
I am assuming that because I am setting up the template programmatically in my block class I shouldn't need the module reference? Removing the reference makes no difference.
I get no PHP errors, the HTML displayed renders
<html>
<head></head>
<body></body>
</html>
I simply can't figure out what I am doing wrong? I'm using Magento CE 1.8.1
I find these things very difficult. I am going to try to answer in two parts:
PART ONE
You may want to try to render the layout in the controller so try this first then read the additional items below:
//file: app/code/local/MyModule/Ajax/controllers/ProductController.php
//class: MyModule_Ajax_ProductController
//function: indexAction()
$this->loadLayout();
$this->renderLayout();
BUT you are making an Ajax module. So you might want to utilise controller methods such as:
//set the response
$this->getResponse()
//->clearHeaders()
->setHeader('Content-Type', 'application/json')
->setBody(json_encode($someReturnObject));
return;
And if you want to setBody()
to a block's HTML then in the controller the code you have posted above is looking good (but see part two below):-
$this->loadLayout();
$myBlock = $this->getLayout()->createBlock('ajax/product');
$myBlock->setTemplate('mymodule_ajax/product.phtml');
$myHtml = $myBlock->toHtml(); //also consider $myBlock->renderView();
$this->getResponse()
->setHeader('Content-Type', 'text/html')
->setBody($myHtml);
return;
And actually even just calling exit();
at the end of indexAction()
will flush the PHP output buffer to the browser.
I note that you are making a product controller. Studying the code in the class you are extending may help:
//file: app/code/core/Mage/Catalog/controllers/ProductController.php
//class: Mage_Catalog_ProductController
//function: viewAction()
public function viewAction()
{
// Get initial data from request
$categoryId = (int) $this->getRequest()->getParam('category', false);
$productId = (int) $this->getRequest()->getParam('id');
$specifyOptions = $this->getRequest()->getParam('options');
// Prepare helper and params
$viewHelper = Mage::helper('catalog/product_view');
$params = new Varien_Object();
$params->setCategoryId($categoryId);
$params->setSpecifyOptions($specifyOptions);
// Render page
try {
$viewHelper->prepareAndRender($productId, $this, $params);
} catch (Exception $e) {
//...
}
}
which might give you some ideas about sending Magento-standard product-related HTML to the browser. You may find the prepareAndRender()
helper function more interesting but ultimately it uses $this->renderLayout()
to create the output html (here $this
is the controller).
PART TWO
I think you need to concentrate on the line in your code:
echo $this->getLayout()->createBlock('ajax/product')->setTemplate('mymodule_ajax/product.phtml')->toHtml();
and either change it to
echo $this->getLayout()->createBlock('mymodule_ajax/product')->setTemplate('mymodule_ajax/product.phtml')->toHtml();
or, in your module's config.xml file add something like: (I think this is the answer you need)
<config>
<global>
<!-- ... -->
<blocks>
<ajax>
<class>MyModule_Ajax_Block</class>
</ajax>
</blocks>
<!-- ... -->
</global>
</config>
so that Magento can understand that createBlock('ajax/product')
means MyModule_Ajax_Block_Product
and not Mage_Ajax_Block_Product
.
I also recommend you change MyModule
to Mymodule
throughout so that there is not a capital letter in the middle. Because
$this->getLayout()->createBlock('mymodule_ajax/product')
well, I don't understand the fine details but generally Magento will make mymodule
into Mymodule
not MyModule
Does that make sense?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With