Mini Tutorial: Alternative Configurable Products Display in Magento

I’d like to go over an alternative set up to display configurable products in Magento. The standard way involves displaying only the parent product on the site. The visibility of the parent in this case would be set to “Catalog,Search”, and the child products would be set to “Not Visible Individually”. This displays the parent on the category and search page, and when selected, displays the parent product view page.

In some cases, however, it may be beneficial to display the child products on the category page, all with their own unique URL, but displaying the parent on the product page for each, with the child configurable option set. So instead of just having “Sweater” on the category page, you would actually have:
– “Sweater-Small”
– “Sweater-Medium”
– “Sweater-Large” etc.

All of these products would still link to their own url:
– www.website.com/sweater-small
– www.website.com/sweater-medium
– www.website.com/sweater-large

…but still display the parent product on the product page, so the customer has to option to change, in this example, size from the product page.

Related: 10 Real World Examples of Shopping Cart Price Rules

To do this, we would first need to change the visibility of the products to the opposite of the normal set up. The parent product needs to be set to “Not Visible Individually”, and the children need to be set to “Catalog,Search”. This insures that the simples will all be shown on the category page, and not the parents. Overwire the viewAction() in the ProductController. First, create the directory paths

app/code/local/MyCompany/CustomConfig/controllers

and

app/code/local/MyCompany/CustomConfig/etc

Under /controllers/, create the file ProductController.php and set it up in this way:

<?php

require_once 'Mage/Catalog/controllers/ProductController.php';
class MyCompany_CustomConfig_ProductController extends Mage_Catalog_ProductController
{
    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');
		$size = null;

		//This checks if the product being requested is a simple product, and if it is, it loads the parent product instead.
        if($arrayOfParentIds = Mage::getSingleton("catalog/product_type_configurable")->getParentIdsByChild($productId))
        {
            $product_model = Mage::getModel('catalog/product')->load($productId);
            if($product_model->getAlternativeTemplate() && $product_model->getTypeId() == 'simple')
            {
                $parentId = (count($arrayOfParentIds) > 0 ? $arrayOfParentIds[0] : null);
                $productId = $parentId;				
                $size = $product_model->getSize();
            }
        }

        // Prepare helper and params
        $viewHelper = Mage::helper('catalog/product_view');

        $params = new Varien_Object();
        $params->setCategoryId($categoryId);
        $params->setSpecifyOptions($specifyOptions);
		
        if($size)
        {            
			//This sets a parameter of the size attribute of the selected simple product
            Mage::app()->getRequest()->setParam('size',$size);
        }

        // Render page
        try {
            $viewHelper->prepareAndRender($productId, $this, $params);
        } catch (Exception $e) {
            if ($e->getCode() == $viewHelper->ERR_NO_PRODUCT_LOADED) {
                if (isset($_GET['store'])  && !$this->getResponse()->isRedirect()) {
                    $this->_redirect('');
                } elseif (!$this->getResponse()->isRedirect()) {
                    $this->_forward('noRoute');
                }
            } else {
                Mage::logException($e);
                $this->_forward('noRoute');
            }
        }
    }
}

Now, under /etc/, create the file config.xml and set it up like so:

<?xml version='1.0'?>
<config>
    <frontend>                
        <routers>
            <catalog>
                <args>
                    <modules>
                        <MyCompany_CustomConfig before="Mage_Catalog">MyCompany_CustomConfig</MyCompany_CustomConfig>
                    </modules>
                </args>
            </catalog>
        </routers>
    </frontend>
</config>

This is just the standard config to overwrite an existing magento controller.

Now we can activate the module by creating the file MyCompany_CustomConfig.xml under /app/etc/modules/

<?xml version="1.0"?>
<config>
    <modules>
        <MyCompany_CustomConfig>
            <active>true</active>
            <codePool>local</codePool>
        </MyCompany_CustomConfig>
    </modules>
</config>

Finally, create the file app/design/frontend/yourtheme/template/catalog/product/view/type/options/configurable.phtml and add this at the bottom:

    <?php if(strtolower($this->getRequest()->getParam('size')) != ''): ?>
        <?php $size_param = strtolower($this->getRequest()->getParam('size')) ?>
        <?php Mage::app()->getRequest()->setParam('size',''); ?>
        <script type="text/javascript">
            jQuery(document).ready(function(){
               var colour = "<?php echo $size_param ?>";
               var product_id = <?php echo $_product->getEntityId() ?>;
                var selectReference = 'attribute[size_attribute_id]';
               $(selectReference).setValue(colour);
               $(selectReference).simulate('change');
            });
        </script>
    <?php endif; ?>

Just remember to replace [size_attribute_id] with the actual attribute id you need to use. For Instance ‘attribute547’.