3

I am working in related.phtml in app/design/frontend/[package]/default/template/catalog/product/list/. Here there is a foreach loop: <?php foreach($this->getItems() as $_item): ?> which loops through and outputs the related items of the main product on the page.

I have modified the contents of the loop to display the drop-down configurable options for each related product (if it is a configurable product). See image below: Configurable Related Products Unfortunately, the <option>'s in the <select> drop-downs do not have any value attribute, so when the form is submitted, they have no effect.

The code from configurable.phtml found in app/design/frontend/[package]/default/template/catalog/product/view/type/options/ which loads the configurable options for the main product on the page, uses these lines which runs some JavaScript to add the value's:

<script type="text/javascript">
    var spConfig = new Product.Config(<?php echo $_jsonConfig ?>);
</script>

But adding this directly to my code in related.phtml doesn't have any effect and would probably conflict with the main product, as suggested here. I have followed their advice and used this code

 <script type="text/javascript">
    var spConfig_<?php echo $_item->getId()?> = new Inchoo_Product.Config(<?php echo $this->getJsonConfig() ?>);
 </script>

and made a new namespace with the product.js as suggested, but still this has no effect, and the <option>'s still have no value attribute.

I think the issue is with the $this in the above code, because it is pointing to the wrong class, because this code was originally intended for configurable.phtml NOT related.phtml.

So my question is, how do I change where $this is pointing?

3

In the context of any given block, $this is defined as the block type so in your theme or module definition layout updates, you would need to update the block type to point to the correct block.

<block type="sales/order_info" as="info" name="sales.order.info"></block>

This is an example block from the Mage_Sales module so when that blocks being rendered, the context of $this should resolve to Mage_Sales_Block_Order_Info.

<block type="module/block" as="info" name="sales.order.info"></block>

Updating to the above, asuming it should now look for the handler of module, which we shall assume was defined in Your_Module, and look for the block "block"

Your_Module_Block_Block

Hope that makes helps.

| improve this answer | |
  • Yes, I do need to change the block to a different one, but I cannot change the block related.phtml points to because other code in related.phtml relies on the block being as it already is. So is it possible to change the block after that code, like halfway through? – Weddar Thork May 17 '15 at 19:51
  • In that case you have two options: extend the block you are relying upon functionality from and implement your requirements into the new block then update, this way will keep the functions you are relying on. Alternatively, configure it so that your custom requirements are implemented as a child block. – John Cuthbert May 18 '15 at 6:59
3

As John pointed out $this references the block object in Magento itself. All templates are rendered with a block. But I want to give you a little more information:

Block types

There are two main types of blocks - those that utilize a template and those that do not.

All template rendering block types inherit from Mage_Core_Block_Template and all others inherit from Mage_Core_Block_Abstract directly.

Other types of blocks exist as well, such as Mage_Core_Block_Text which uses the value set by the setText method for output.

Rendering a block

A block is rendered when you echo the block's toHtml method. E.g.:

<?php echo $this->getChildHtml('child.block.name')->toHtml(); ?>

Magento has a few ways of creating blocks:

  • Layout XML
  • PHP

Both of those methods are valid and both are used in Magento for different purposes.

"Changing" the block type

And now to answer your real question. Generally if you want to change which block is handling your template's rendering you'll want to unset or remove the existing block.

<remove name="my.block"/>

OR:

<reference name="content">
    <action method="unsetChild"><name>my.block</name></action>
</reference>

Which one do you use? If you're merely relocating a block you'll want to unset it because the block isn't destroyed. You can still insert it elsewhere later. If you want to reset its type you'll want to remove it.

So we'll use remove.

<remove name="my.block"/>

Then all that's left to do is to recreate the block with our new custom type:

<block type="my/related" name="my.block" template="original/template/to/render.phtml" />

How does it know what my/related is?

Creating your new block class

You'll need to make a new block class. But we don't need to reinvent the wheel! We can inherit from the block class we're attempting to rewrite. For your example:

        <block type="catalog/product_list_related" name="catalog.product.related" before="-" template="catalog/product/list/related.phtml"/>

The original block is Mage_Catalog_Block_Product_List_Related.

You'll want to inherit from that, then, in the creation of your new block:

class My_Module_Block_Related extends Mage_Catalog_Block_Product_List_Related

For more information on creating your own blocks visit this blog:

https://www.yireo.com/tutorials/magebridge/administration/600-adding-a-custom-magento-block

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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