Magento – the correct way to override / replace the custom options container

custom-optionslayoutmagento-1overrides

Background

I am developing a module that creates a few custom entities which relate/impact the options available for a particular product. Here's how it works:

When a product loads, a query is performed on my custom entities using two of the product's attributes.

I use the result of the query and present it in a 2-step fashion, like this (the customer's first selection impacts the options available for their second):

intended interface

The Challenge

Here's what I know I need to accomplish on the frontend:

1. Override two pieces of logic in Product view.phtml:

— First:

<form action="<?php echo $this->getSubmitUrl($_product) ?>" method="post" id="product_addtocart_form"<?php if($_product->getOptions()): ?> enctype="multipart/form-data"<?php endif; ?>>

… you'll notice enctype="multipart/form-data" only gets added if $_product->getOptions() is true, and my products won't actually have them (so this would return false).

— Second:

 <?php if ($_product->isSaleable() && $this->hasOptions()):?>
    <?php echo $this->getChildChildHtml('container1', '', true, true) ?>
 <?php endif;?>

… also because my products won't actually have custom options, so $this->hasOptions() would return false and prevent rendering of container1.

2. Replace/overwrite/override 'container1' — the child block (is it a block?) that "contains" the html for the custom options, as shown here:
what needs to be replaced

I've read a few posts that claim that copying view.phtml and editing it directly is not the correct way to do this, but what's the alternative?

Second, I've read I can either remove or unSet the container1 piece — which method should I use, and then how do I correctly substitute my own container1?

Thank you very much!

Best Answer

I've been working on a similar module for some time now, and ran into pretty much the same thing. I have added a custom product type to make this work.

The key is the product_type_data block. This you can override this block without having to modify other template files. In my module's layout XML file, I added:

<PRODUCT_TYPE_myproduct translate="label" module="my_module">
    <reference name="content">
        <reference name="product.info">
            <block type="my_module/product_type_myproduct" name="product.info.myproduct" as="product_type_data" template="my_module/product/type/myproduct.phtml">

            </block>
        </reference>
    </reference>
</PRODUCT_TYPE_myproduct>

From there, I add my form fields in the template. The values will get passed to an observer on the sales_quote_add_item event where I can add the user's selections to additional_options.

Additionally, by using a custom product type, you can use your own _prepareProduct() method where you will be able to set various values that will be passed through to parent::_prepareProduct($buyRequest, $product, $processMode)

(I will probably come back and modify this later with additional details)

Related Topic