2

Client wants to show part of product information in category view. Got all descriptions, images and related products, but have problems with reviews and form. Can anyone help me, please?

Code:

In app/design/frontend/catalog/product/list.phtml

<?php echo $this->getChildHtml('review_form')->setProduct($product)->toHtml(); ?>

In local.xml made same changes as ProxiBlue told to make in catalog.xml :

<catalog_category_default>
    <reference name="content">
        <reference name="product_list">
            <block type="review/form" name="product.review.form" as="review_form">
                <block type="page/html_wrapper" name="product.review.form.fields.before" as="form_fields_before" translate="label">
                    <label>Review Form Fields Before</label>
                    <action method="setMayBeInvisible"><value>1</value></action>
                    <action method="setElementClass"><value>rewards</value></action>
                </block>
            </block>
        </reference>
    </reference>
</catalog_category_default>

So, after I made this changes I got error in frontend:

Fatal error: Call to a member function setProduct() on a non-object.

Then I opened app/code/Mage/Review/Block/Form.php and edited getAction() function like this:

public function getAction()
{
    $productId = $this->getProduct()->getId();
    return Mage::getUrl('review/product/post', array('id' => $productId));
}

After that I see text for first product on page 'Write your own review' and that's all, other products doesn't load, but no errors appeared in console or frontend. I guess, I should do smth more in Form.php file.

Also I need to get not only form, but reviews too.

Thanks for any help.

  • What have you tried so far? Do you have any code you can post to see what may be wrong? – philwinkle Aug 7 '13 at 3:14
  • @philwinkle, updated my question. – Alex K Aug 11 '13 at 20:38
  • You are not following the answer/instructions. The updates you done to question, is NOT what I gave, and you clearly do not understand how magento works. I suggest you read up on how blocks/models/layouts work, and how to extend magento via modules. You are also editing core code, big NO NO. – ProxiBlue Aug 12 '13 at 1:37
  • I know that core files should not be touched, I was just testing. – Alex K Aug 12 '13 at 10:31
  • Thats good to hear :) – ProxiBlue Aug 12 '13 at 13:29
3

The below should get you onto the right track. (expanded to explain in more detail, as per comments)

The default behavior for reviews is to do a form post onto the review controller. This form post gets the product id for the product that is to be reviewed.

you can see this variable fetched in the block code Mage_Review_Block_Form::getAction() - $productId = Mage::app()->getRequest()->getParam('id', false);

This is then used to get the product data (for the name), and to build the review form post url.

Since you want to display the form on the category page (per product), you cannot do this, and need another way to set the correct product(id). This is easy, by just passing in the product data, for the current product, via the .phtml using a line like this:

<?php echo $this->getChild('review_form')->setProduct($_product)->toHtml(); ?>

It is best to just pass the entire product object, since you can then use any of the product data in the review block.

To make it all work, you need to create a new block which extends the core review block class Mage_Review_Block_Form (not rewrite, just extend), and adjust functionality to pull the product id from the passed product object.

you want to extend any functions that get the productId to use your given productid (see later in phtml) This is needed to allow each form to be posting for each product, else they will all post for one product.

as an example the method Mage_Review_Block_Form::getAction() looks like this:

public function getAction()
    {
        $productId = Mage::app()->getRequest()->getParam('id', false);
        return Mage::getUrl('review/product/post', array('id' => $productId));
    }

and you will need to change that to pull the productId from $this->getProduct()->getId(); (again, see later in phtml adjustment how that is set)

Next you need to adjust the layouts to include the review form. thus in catalog.xml you need to get the review form layout into the catalog_category layout

You must set the block to your new block, and not the core review block, thus allowing the .phtml to call your methods, which change the behavior to get the product data from the different place.

place this xml block:

<block type="YOUR_MODULE_NAMESPACE/YOUR_BLOCK" name="product.review.form" as="review_form">
 <block type="page/html_wrapper" name="product.review.form.fields.before" as="form_fields_before" translate="label">
                            <label>Review Form Fields Before</label>
                            <action method="setMayBeInvisible"><value>1</value></action>
                            <action method="setElementClass"><value>rewards</value></action>
                        </block>
                    </block>

into the <catalog_category_default translate="label"> layout area, contained within <block type="catalog/product_list" name="product_list" template="catalog/product/list.phtml"> (you may also need to place it in the anchor category layout area)

This then sets the review form to be a child block of catalog/product_list

now, to make it display, you need to edit the list.phtml file (.../template/catalog/product/list.phtml) to include the review form and then pass it the current product

This is done simply by using

<?php echo $this->getChild('review_form')->setProduct($_product)->toHtml(); ?>

For completeness, the full layout xml section:

<catalog_category_default translate="label">
        <label>Catalog Category (Non-Anchor)</label>
        <reference name="left">
            <block type="catalog/navigation" name="catalog.leftnav" after="currency" template="catalog/navigation/left.phtml"/>
        </reference>
        <reference name="content">
            <block type="catalog/category_view" name="category.products" template="catalog/category/view.phtml">
                <block type="catalog/product_list" name="product_list" template="catalog/product/list.phtml">
                    <block type="catalog/product_list_toolbar" name="product_list_toolbar" template="catalog/product/list/toolbar.phtml">
                        <block type="page/html_pager" name="product_list_toolbar_pager"/>
                        <!-- The following code shows how to set your own pager increments -->
                        <!--
                            <action method="setDefaultListPerPage"><limit>4</limit></action>
                            <action method="setDefaultGridPerPage"><limit>9</limit></action>
                            <action method="addPagerLimit"><mode>list</mode><limit>2</limit></action>
                            <action method="addPagerLimit"><mode>list</mode><limit>4</limit></action>
                            <action method="addPagerLimit"><mode>list</mode><limit>6</limit></action>
                            <action method="addPagerLimit"><mode>list</mode><limit>8</limit></action>
                            <action method="addPagerLimit" translate="label"><mode>list</mode><limit>all</limit><label>All</label></action>
                        -->
                    </block>
                    <action method="addColumnCountLayoutDepend"><layout>empty</layout><count>6</count></action>
                    <action method="addColumnCountLayoutDepend"><layout>one_column</layout><count>5</count></action>
                    <action method="addColumnCountLayoutDepend"><layout>two_columns_left</layout><count>4</count></action>
                    <action method="addColumnCountLayoutDepend"><layout>two_columns_right</layout><count>4</count></action>
                    <action method="addColumnCountLayoutDepend"><layout>three_columns</layout><count>3</count></action>
                    <action method="setToolbarBlockName"><name>product_list_toolbar</name></action>
                    <block type="YOUR_MODULE_NAMESPACE/YOUR_BLOCK" name="product.review.form" as="review_form">
                        <block type="page/html_wrapper" name="product.review.form.fields.before" as="form_fields_before" translate="label">
                            <label>Review Form Fields Before</label>
                            <action method="setMayBeInvisible"><value>1</value></action>
                            <action method="setElementClass"><value>rewards</value></action>
                        </block>
                    </block>
                </block>
            </block>
        </reference>
    </catalog_category_default>

the above in action, ugly, as the design does not allow for a form, but I am sure your's will ;)

Screen-grab-of-this-in-action

  • Thanks for answer, but I am not sure that I understood what to do in Form.php file, because I got text 'write your own review' and that's all. :D Do you have idea what I did wrong? – Alex K Aug 7 '13 at 17:22
  • Hi, well, without seeing what you did, no ;) I will expand on my answer to five a bit more clarification. – ProxiBlue Aug 8 '13 at 4:28
  • You are most likely not calling your custom block, or you have some kind of error (have you checked the logs?) Have you checked the value of $this? Is it your custom block? Do you have all the methods extended that depends on the posted param id? – ProxiBlue Aug 8 '13 at 4:45
  • Do you use a debugger? If not I highly suggest you take some time to get some kind of debugger working in your IDE (I use/prefer xdebug) - you will cut down hours of frustration by using a real debugger, as you can actually 'see' what the code is up to. For example, I would have put a breakpoint on the 'Write Your Own Review' line, and step through the code to find the error. It really blows my mind that some people don't use a debugger for magento coding ;) – ProxiBlue Aug 8 '13 at 4:46
  • Hi @ProxiBlue. I have updated my question with code, hope it will helps me and you. About debugger..No, I don't use it. Most of time I use var_dump() or Zend_Debug::dump(); and die; function. – Alex K Aug 11 '13 at 20:34

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.