1

I have custom options that are added to certain products dynamically using the catalog_controller_product_view event and my own observer.

Related: How to add dynamic Select Custom Options in Observer

I'd like to now use an option renderer other than the default. Ideally, I'd like to set my own type field to the option when created so that it uses my own value, ie:

$optionModel = Mage::getModel('catalog/product_option')
    ...
    ->setType('my_option_type')
    ...

This, of course, requires my custom option type to have an associated Block, Model, etc. This also seems to require rewriting the Mage_Catalog_Model_Product_Option class to include my custom option type.

Unfortunately, the Magento team didn't think these option renderers would have been useful as templates, as the markup is essentially all created in the getValuesHtml() method inside the option's associated block class (ie. Mage_Catalog_Block_Product_View_Options_Type_Select)

How can I set my own renderer (preferably as a template, none of this sloppy getValuesHtml() stuff) to a custom option that is created dynamically on product view?

Really, all I need to do is add some additional data attributes to each option value's input element.

1 Answer 1

1

Even tho custom option renderers can be added via layout update by calling addOptionRenderer on product.info.options block, using custom types will never work without rewriting getGroupByType method inside Mage_Catalog_Model_Product_Option class.

You can trick Magento to show your custom type on product view page by doing something like this in local.xml

<catalog_product_view>
        <reference name="product.info.options.wrapper">
            <block type="foo_bar/options" name="product.info.options" as="product_options" template="catalog/product/view/options.phtml">
                <action method="addOptionRenderer"><type>text</type><block>catalog/product_view_options_type_text</block><template>catalog/product/view/options/type/text.phtml</template></action>
                <action method="addOptionRenderer"><type>file</type><block>catalog/product_view_options_type_file</block><template>catalog/product/view/options/type/file.phtml</template></action>
                <action method="addOptionRenderer"><type>select</type><block>catalog/product_view_options_type_select</block><template>catalog/product/view/options/type/select.phtml</template></action>
                <action method="addOptionRenderer"><type>date</type><block>catalog/product_view_options_type_date</block><template>catalog/product/view/options/type/date.phtml</template></action>
                <action method="addOptionRenderer"><type>test</type><block>foo_bar/options_test</block><template>foo_bar/options/test.phtml</template></action>
            </block>
        </reference>
    </catalog_product_view>

Block class:

class Foo_Bar_Block_Options extends Mage_Catalog_Block_Product_View_Options
{
    public function getOptionHtml(Mage_Catalog_Model_Product_Option $option)
    {
        if ($option->getType() == 'test') {
            $renderer = $this->getOptionRender(
                $option->getType()
            );
        } else {
            $renderer = $this->getOptionRender(
                $this->getGroupOfOption($option->getType())
            );
        }

        if (is_null($renderer['renderer'])) {
            $renderer['renderer'] = $this->getLayout()->createBlock($renderer['block'])
                ->setTemplate($renderer['template']);
        }

        return $renderer['renderer']
            ->setProduct($this->getProduct())
            ->setOption($option)
            ->toHtml();
    }
}

And this will work until you try to add to cart because that is when getGroupByType is called again and we get a nice error message. :)

4
  • I guess I don't really care so much about what happens when adding to cart, since that is where I am already adding my options as additional_options after I perform necessary price calculations. It's fine that they use default renderers there, since that's pretty much what they are, I simply need to add some data values into the <input> that gets generated.
    – pspahn
    Jan 20, 2015 at 0:43
  • Is the renderer block (Foo_Bar_Block_Options_Test in your example) simply "there"? Should it use getValuesHtml()? Using your example, this doesn't seem to be working.
    – pspahn
    Jan 20, 2015 at 18:04
  • Oh, I forgot to add it. It's just an empty class which extends Mage_Catalog_Block_Product_View_Options_Type_Text Jan 20, 2015 at 18:12
  • Yeah, I figured that. I forgot I previously modified the options.phtml template to remove the call to $option->getOptionHtml() - This is pretty much exactly what I needed, thanks!
    – pspahn
    Jan 20, 2015 at 18:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.