Taking Control of Product Options in Magento


It’s about 18 months since I first grappled with custom options for products in Magento. This was for the MyBlinds website which I’ve blogged about previously, and will do so again. A large number of products (2000), a number of different product types (7) as well a  reasonable number of options per product (on average 6) meant a complicated category setup. Ultimately, in this scenario, I built a custom import script that imported the custom options for each product type.

Unfortunately, at the time, I wasn’t aware of Custom Option Templates. This module allows you to create a template of custom options, and apply it to whatever products you like. So there’s no need to import the custom options for the products, but just assign the appropriate template post-import.

I’ve only come across one problem with this module. It has problems assigning more than 200 products to a particular template. This isn’t the end of the world, as we can just create a duplicate of a particular template, and assign the duplicate template to the products beyond 200. You need to be careful in doing this, as it can be easy to assign 2 or more templates to 1 product, and none to another, if you’re not careful about how you go about it.

What’s also important, I think, in getting to grips with custom options for products in Magento, is to seriously consider scrapping the default product view template (/app/design/frontend/<your_interface>/<your_theme>/template/catalog/product/view.phtml). It’s very restricting in how it renders custom options. There’s no flexibility in terms of more sophisticated validation, tooltips to explain the meaning/importance of certain options, etc.

As an example of the restrictions in the rendering of custom options in the default template, the input fields have ids something like “option_728”. What is the use of a unique identifier that I have no way of knowing what it is in advance, so that I can not target it using Javascript or CSS?

Instead I find it better to create a custom view template for each of your product types where you can hand-craft the HTML to fit your user experience needs. This gives you complete control over how the page looks and you can create radically different product view pages based on the product type or category. In hand-crafting the HTML, it can become a little more complex to put in the appropriate option ids and names on the input fields. Thus far, I’ve been updating the options with the appropriate names using AJAX on product load. This isn’t ideal and I will be working on some custom functions to do this as part of the page rendering on a current project. But ultimately you can add the necessary ids and classes to your custom options so you can target them to your heart’s content.

The only problem in this approach, is that the “custom layout update” field needs to be filled in for each product with the appropriate update to use the custom template rather than the default template:

<reference name="product.info">
	    <action method="setTemplate"><template>catalog/product/custom.phtml</template></action>
	</reference>

Obviously, if you want to make a change to the name of the template being used, you can use the mass update attributes action in the product grid in the Magento backend. It does seem like overkill however. Wouldn’t it be nice to be able to simply set the product page template at the category level. This is possible with a small piece of custom code. By default, Magento will let you set the page layout or custom design of a category to be applicable to its subcategories and products. However, this doesn’t extend to “custom layout updates”. So that’s what the following code does. It means that when you set a custom layout update in a category, and set it to apply to all of its children, that it will be taken up by the products. In this way, we can set a custom product template for an entire category, in one place only.

<global>
	        <models>
	            <catalog>
	                  <rewrite>
	                    <category>SF9_Custom_Model_Category</category>
	                    <product>SF9_Custom_Model_Product</product>
	                    </rewrite>
	               </catalog>
	        </models>
	</global>
<?php
	class SF9_Custom_Model_Category extends Mage_Catalog_Model_Category
	{   
	    public function getCustomLayoutUpdate(){
	        $customLayoutUpdate = $this->getData('custom_layout_update');
	        if ($customLayoutUpdate == "") {
	            $parent = $this->getParentCategory();
	            if($parent){
	                $customLayoutUpdate = $parent->getCustomLayoutUpdate();
	               }
	        }
	        return $customLayoutUpdate;
	    }
	}
?>
<?php
	class SF9_Custom_Model_Product extends Mage_Catalog_Model_Product
	{   
	    public function getCustomLayoutUpdate(){
	        $customLayoutUpdate = $this->getData('custom_layout_update');
	        if ($customLayoutUpdate == "") {
	            $parent = Mage::registry('current_category');
	                 if($parent){
	                     $customLayoutUpdate = $parent->getCustomLayoutUpdate();
	                }
	        }
	        return $customLayoutUpdate;
	    }
	}
?>

 

Alan Morkan
Alan Morkan |