Magento – Switch Between product/view.phtml Templates Based on an Attribute

layoutoverridestemplate

I want to create a second product view. The value of a custom attribute determines which template supposed to be used. Now I'm struggling about the best approach.

I've already overwritten the viewAction() of the ProductController. But I don't know how I can replace the template based on a custom_attribute. Could anyone please point me in the right direction?

Thank you so much for any help!

Best Answer

You can do this without changing core files, you need to create an observer that will create a new layout handle based on the attribute. Then you can create a layout update for that handle to change the template used for the product view page.

The following code is based on the article from http://magebase.com/magento-tutorials/creating-custom-layout-handles/

Module init file app/etc/modules/Example_AttributeHandle.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <Example_AttributeHandle>
            <active>true</active>
            <codePool>local</codePool>
        </Example_AttributeHandle>
    </modules>
</config>

Module configuration: app/code/local/Example/AttributeHandle/etc/config.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <Example_AttributeHandle>
            <version>0.1.0</version>
        </Example_AttributeHandle>
    </modules>
    <global>
        <events>
            <controller_action_layout_load_before>
                <observers>
                    <attributesethandle>
                        <class>Example_AttributeHandle_Model_Observer</class>
                        <method>addAttributeHandle</method>
                    </attributesethandle>
                </observers>
            </controller_action_layout_load_before>
        </events>
    </global>
</config>

Observer file: app/code/local/Example/AttributeHandle/Model/Observer.php

<?php
class Example_AttributeHandle_Model_Observer
{
    /**
     * Converts attribute value of current product to nice name ([a-z0-9_]+).
     * Adds layout handle PRODUCT_ATTRIBUTE_<attribute>_<value> after
     * PRODUCT_TYPE_<product_type_id> handle
     *
     * Event: controller_action_layout_load_before
     *
     * @param Varien_Event_Observer $observer
     */
    public function addAttributeHandle(Varien_Event_Observer $observer)
    {
        $product = Mage::registry('current_product');

        /**
         * Return if it is not product page
         */
        if (!($product instanceof Mage_Catalog_Model_Product)) {
            return;
        }

        $attributeName = 'myattribute';
        /**
         * Convert attribute value to alphanumeric + underscore string
         */
        $niceName = str_replace('-', '_', $product->formatUrlKey($product->getData($attributeName)));

        /* @var $update Mage_Core_Model_Layout_Update */
        $update = $observer->getEvent()->getLayout()->getUpdate();
        $update->addHandle('PRODUCT_ATTRIBUTE_'.$attributeName.'_' . $niceName);
    }
}

Replace the $attributeName value with the attribute that you would like to use. When the attribute is dropdown, it will use the numeric value of the selected option. Also this will not work for multiselect attributes.

Now you can change the product view template with the following code in your local.xml to select an other template when the product attribute myattribute has the value demotxt:

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

Hope that this info is helpful, I did not had the option to test it completly.

Related Topic