A while ago I had to make the product view area update through AJAX. Most answers on StackOverflow didn’t satisfy me because they told you to copy the required blocks over to your own layout handle or something similar.

After playing around with output blocks and handles, I came up with a better way to fetch the content block without touching a single line of layout XML.

Firstly, you need to define your own controller action to which you can send the request with a productid parameter.

$id = $this->getRequest()->getParam('productid');
$product = Mage::getModel('catalog/product')->load($id);

We need to register the product in the registry in order for other blocks can access it. I’ve registered both the product and current_product registry keys as they’re both used. current_product is used for the configurable product’s option block for example.

Mage::register('product', $product);
Mage::register('current_product', $product);

Actually, you can replace the above with the following line, which does essentially the same thing, but fires off a couple of handy events as well.

$product = Mage::helper(‘catalog/product’)->initProduct($product->getId(), $this)

Next, add the handles we want. You'll need to add the default handle first because the order of handles is important for the layout sysem to do it’s job.

Also, don’t worry if you don’t see all layout handles here - our next call to loadLayout will add other handles such as customer_logged_in.

$this->getLayout()->getUpdate()->addHandle(array(
    'default',
    'catalog_product_view',
    'PRODUCT_TYPE_' . $product->getTypeId(),
    'PRODUCT_' . $product->getId()
));

Also, dispach an event that makes Mage_Reports work as expected.

Mage::dispatchEvent('catalog_controller_product_view', array('product' => $product));

This might come in handy too:

Mage::getSingleton('catalog/session')->setLastViewedProductId($product->getId());

Let’s load our layout.

$this->loadLayout();

Remove our root output block and add content to the output bocks.

$this->getLayout()->removeOutputBlock('root')->addOutputBlock('content');

And finally, start rendering!

$this->renderLayout();

You can use this method to output any block on any handle. Also, your config.xml is very lightweight - you only need to define a frontend router.

By taking this approach, any modules manipulating the catalog_product_view handle should integrate seamlessly.

layout.xml magento