Sometimes you need to render a line item in the cart differently than the rest.
A sample usage case would be to prevent the quanity of a cart item to be changed.
A built in feature of the cart rendering, is the ability to render each product type with a different template.
You can define the template via layout xml, using the "addItemRender" action within the 'checkout.cart' block
However, it is impractical to go an create a whole new product type, each time you want to render a cart line litem differently.
This article show another, and actually very very easy way, to get this done.
Simply put, we can trick the cart rendering code to think the line item is a dirrent product type, thus allowing it to render differently.
In this eaxmple, we are going to add a FREE product to a persons cart, after they completed the registration process. - So basically a quick and easy way to give out a FREE gift for new registrations. The code can be adapted to work with any other usage case.
This was all done on magento CE 1.9, so older versions may differ slightly.
I am not going to explain how to create an entire module. I am making the assumption that you already have knowledge about how to do all that, and understand the structure of the magento module code/folders.
I called the module: ProxiBlue_InjectGift. Some parts, like the product_id, is hard coded for this example. You'd want to make it more configurable in a real world application.
Lets get some code done.....
The first step is to set your module to observe the event: 'customer_register_success'
<events>
<customer_register_success>
<observers>
<proxiblue_injectgift_customer_register_success>
<class>proxiblue_injectgift/customer_observer</class>
<method>customer_register_success</method>
</proxiblue_injectgift_customer_register_success>
</observers>
</customer_register_success>
</events>
Now, create the observer class, and in that the following method holds the code.
public function customer_register_success(Varien_Event_Observer $observer)
{
$_product = mage::getModel('catalog/product')->load(100); // LOAD YOUR GIFT PRODUCT HERE
$cart = Mage::getModel('checkout/cart');
// ADD THE PRODUCT TO THE CART
$cart->addProduct($_product, array('qty' => 1));
// THIS IS THE PART WHERE WE TRICK THE CART.
// WE SET THE PRODUCT TYPE OF THIS PRODUCT BY USING A QUOTE ITEM OPTION
// THIS WILL ONLY BE USED IN THE RENDERING. THE PRODUCT WILL REMAIN ITS REAL TYPE
$quote = $cart->getQuote();
$quoteItem = $quote->getItemByProduct($_product);
$option = Mage::getModel('sales/quote_item_option')
->setProductId($_product->getId())
->setCode('product_type')
->setProduct($_product) // needed for EE only ?
->setValue('noqty'); // THIS IS THE NAME WE WILL USE FOR THE ITEM RENDERER IN XML
$quoteItem->addOption($option);
}
The next step is to simply add a new item renderer in layout xml for the above.
This can be done via local.xml (or your modules defined layout xml file)
In this example, I called the renderer 'noqty'
<checkout_cart_index>
<reference name="checkout.cart">
<action method="addItemRender">
<type>noqty</type> <!-- MATCH THE NAME USED IN THE OPTION -->
<block>checkout/cart_item_renderer</block>
<template>checkout/cart/item/noqty.phtml</template> <!-- YOUR TEMPLATE FILE -->
</action>
</reference>
</checkout_cart_index>
Next, and last, simply create the custom template file.
BANG - you have an item that renders using a custom template, without having the need to create a new product type.