2

This is a follow-up to this question:

https://stackoverflow.com/questions/6748730/magento-product-listing-by-category-id

How can I get product lists by categoryid from from within view.phtml, i.e. pass a $categoryid to list.phtml?

View.phtml has

<?php echo $this->getProductListHtml() ?>

And I would like to do something like

<?php echo $this->setCategoryId(id)->getProductListHtml() ?>

This way I can iterate through categories in view.phtml and get the product list for each and have the product list rendering be done for me in list.phtml.

5 Answers 5

2

I have answered here for the exact same problem. It describes in detail how to achieve this. I also provided the complete reference for the module that will help us to achieve it.

EDIT

In my approach, we are going to create a module that mainly add a block on product view page, in which we will display our product list based on category id.

config.xml

our module's configuration file tells to magento that, hey magento I have a module with some blocks and some layouts.

Layout is for defining blocks that we will set to show in product view page and in block area we will add code for load product list based on category Id in the layout block that we are going to define.

Location:app/code/local/Programmerrkt/Listinview/etc/config.xml
<config>
<modules>
    <Programmerrkt_Listinview>
        <version>0.1.0</version>
    </Programmerrkt_Listinview>
</modules>
<frontend>
    <layout>
        <updates>
            <programmerrkt_listinview>
                <file>programmerrkt_listinview.xml</file>
            </programmerrkt_listinview>
        </updates>
    </layout>
</frontend>
<global>
    <blocks>
        <programmerrkt_listinview>
            <class>Programmerrkt_Listinview_Block</class>
        </programmerrkt_listinview>
    </blocks>
</global>
</config>

layout

Our layout file is use to add a custom block in product view page. Later product list is going to show through this custom block.

Location:app/design/<your_package/<your_theme>/layout/programmerrkt_listinview.xml
<layout>  
<catalog_product_view>
       <reference name="content">
            <block type="programmerrkt_listinview/catalog_product_list" name="listinview_list" as="listinview_list" template="programmerrkt/listinview/catalog/product/list.phtml" />
       </reference>
</catalog_product_view>
</layout>

Template

So we have defined a template in our layout file. The location of template in app/design/fronend/<your_package>/<your_theme>/template/programmerrkt/listinview/catalog/product/list.phtml. What is the content in our list.phtml? Can you guess ? Yes we are going to use the exact same content in magento's default product list template. Its cool right ?

So copy paste content in app/design/fronend/<your_package>/<your_theme>/template/catalog/product/list.phtml to our module's list.phtml file.

Block

So in our template, we can see that we are calling products to our template like this

 $_productCollection=$this->getLoadedProductCollection();

For us $_productCollection should hold product collection of our desired category. So let us define a custom getLoadedProductCollection() in backend so that it loads desired collection of products.

 Location: app/code/local/Programmerrkt/Listinview/Block/Catalog/Product/List.php
<?php

class Programmerrkt_Listinview_Block_Catalog_Product_List extends Mage_Catalog_Block_Product_List
{

    /**
     * Default Category that is going to load
     *
     * @var string
     */
    protected $_defaultCategoryId = '12';

    /**
     * Default toolbar block name
     *
     * @var string
     */
    protected $_defaultToolbarBlock = 'catalog/product_list_toolbar';

    /**
     * Product Collection
     *
     * @var Mage_Eav_Model_Entity_Collection_Abstract
     */
    protected $_productCollection;

    /**
     * Retrieve loaded category collection
     *
     * @return Mage_Eav_Model_Entity_Collection_Abstract
     */
    protected function _getProductCollection()
    {
        if (is_null($this->_productCollection)) {

            $layer = $this->getLayer();
            $category = Mage::getModel('catalog/category')->load($this->_defaultCategoryId);
            if ($category->getId()) {
                    $origCategory = $layer->getCurrentCategory();
                    $layer->setCurrentCategory($category);
                    $this->addModelTags($category);
            }

            $this->_productCollection = $layer->getProductCollection();

            $this->prepareSortableFieldsByCategory($layer->getCurrentCategory());

            if ($origCategory) {
                $layer->setCurrentCategory($origCategory);
            }
        }

        return $this->_productCollection;
    }

    /*
        Calling method from view
    */
    public function getLoadedProductCollection()
    {
        return $this->_getProductCollection();
    }
}

What we did here is, we define a protected $_defaultCategoryId(here I set it to 12) and using that Id we are loading product collection. You put your category id here.

For more details GITHUB

Now clear all cache. load any product view page. Did you see our product list at the bottom of our page ?

Play with this module. Thanks.

7
  • feel free to share your answer in full here, or add this link as a comment rather than a complete answer Commented Jun 23, 2014 at 8:22
  • @DavidManners : I will surely do it. I dont have time right now. I will do it today itself. Commented Jun 23, 2014 at 8:26
  • @DavidManners : I have edited my answer. Thanks for your valuable comment Commented Jun 23, 2014 at 10:35
  • This is useful in some context, but what I want to do is send list.phtml one category id after another as I iterate through categories...I'm not seeing how to do this given your solution. do I send it $this->setDefaultCategoryId(id)->getLoadedProductCollection? Am I missing something?
    – blisstdev
    Commented Jun 23, 2014 at 17:32
  • If you are using above provided method inside module's list.phtml, you will achieve what you need. If it didnt work, you can try $this->_defaultCategoryId = 1;$this->getLoadedProductCollection();. In any case, you may need to change our variable from protected to public Commented Jun 24, 2014 at 1:41
2

NOTE: view.phtml is ambiguous. I'm assuming you want to display the list on the product page.


Magento has an "upsell" feature, where you specify other products to show as a list on the product page in a "you might also be interested in.." manner.

By default you have to select the upsell products for each product individually, but it's built in a way that you can extend it with your own logic.

So if you don't already use upsells, this is the way to go:

Observe catalog_product_upsell

Create an observer for the catalog_product_upsell event. It uses the product collection provided by the product's category.

In the following example I keep existing upsell products if there were any manually configured and fill them up with products from the same category. Adjust the logic as needed:

use Mage_Catalog_Model_Product as Product;
use Mage_Catalog_Model_Product_Link as RelatedProduct;
use Mage_Catalog_Model_Resource_Product_Link_Product_Collection as RelatedProductCollection;

class IntegerNet_AutoUpsell_Model_Observer
{
    /**
     * @see event catalog_product_upsell
     * @param Varien_Event_Observer $observer
     * @throws Mage_Core_Exception
     */
    public function fillUpsellCollection(Varien_Event_Observer $observer)
    {
        $collection = $observer->getCollection();
        if ($collection instanceof RelatedProductCollection
            && $collection->getLinkModel()->getLinkTypeId() === RelatedProduct::LINK_TYPE_UPSELL
            && $collection->count() < $observer->getLimit('upsell')
        ) {
            $this->addItemsFromCategory($collection, $observer->getLimit('upsell') - $collection->count(), $observer->getProduct());
        }
    }
    protected function addItemsFromCategory(RelatedProductCollection $collection, $numberOfItems, Product $product)
    {
        /** @var Mage_Catalog_Model_Resource_Product_Collection $productsToAdd */
        $productsToAdd = $this->_getProductCategory($product)->getProductCollection();
        $productsToAdd
            ->addStoreFilter()
            ->addIdFilter(array_merge([$product->getId()], $collection->getAllIds()), true)
            ->setVisibility(Mage::getSingleton('catalog/product_visibility')->getVisibleInCatalogIds());
            ->addMinimalPrice()
            ->addFinalPrice()
            ->addTaxPercents()
            ->setPageSize($numberOfItems)
            ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
            ->addUrlRewrite();
        foreach ($productsToAdd as $product) {
            $collection->addItem($product);
        }
    }

    /**
     * @param Mage_Catalog_Model_Product $product
     * @return Mage_Catalog_Model_Category
     */
    protected function _getProductCategory(Product $product)
    {
        $category = $product->getCategoryCollection()
            ->setPageSize(1)
            ->getFirstItem();
        return $category;
    }
}

Some parts that I'd like to highlight:

->addIdFilter(array_merge($product->getId(), $collection->getAllIds()), true)

This excludes the product itself and the products that are already manually defined as upsell products (as stated above, I leave them and only fill the blanks)

->addMinimalPrice()
->addFinalPrice()
->addTaxPercents()
->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
->addUrlRewrite();

This prepares the product collection to load the necessary data to display prices, the product link and any attributes configured as "used in product listing", but not more.

1

The best answer for me was a combination of other answers:

I replaced echo $this->getProductListHtml() in view.phtml with sivakumar's method:

 $this->getChild('product_list')->setData('category_id',$cat->getId());
 echo $this->getChildHtml('product_list',false);

Then, I copied the Grid mode section of list.phtml (line 87 onward) to a new template list_category.phtml, and put this at the top to get the product collection:

<?php 
$_helper = $this->helper('catalog/output'); 
$_columnCount = $this->getColumnCount();
$cat = Mage::getModel('catalog/category')->load($this->getData('category_id'));
$_productCollection = $cat->getProductCollection()
    ->addAttributeToSelect('*')
    ->addAttributeToFilter('status',1)
    ->addAttributeToFilter('visibility',array('neq' => 1))
    ->load();
?>

Finally, enabled it using local.xml:

 <catalog_category_layered>
    <reference name="product_list">
        <action method="setTemplate">
            <template>catalog/product/list_category.phtml</template>
        </action>
        <action method="setColumnCount"><count>3</count></action>
    </reference>
 </catalog_category_layered>
1
  • This worked well, best answer. Commented Apr 9, 2015 at 18:27
0

I'm giving just idea.not a complete solution.

in view.php

public function getProductListHtml()
    {
    return $this->getChildHtml('product_list')
    }

So you can modify like this

public function getProductListHtml($category_id)
    {
 $this->getChild('product_list')->setData('category_id', $category_id);
    return  $this->getChildHtml('product_list', false);

    }

You can get the category id in list.phtml with $this->getCategoryId()

second solution with out modifying core block(view.php): remove echo $this->getProductListHtml() and directly you can put below lines in view.phtml

$this->getChild('product_list')->setData('category_id', $category_id);
    echo  $this->getChildHtml('product_list', false);
1
  • The only problem with this is once I call it once, it gets the same product list over and over, i.e. it doesn't seem to matter what $category_id I pass after the first one...?
    – blisstdev
    Commented Jun 22, 2014 at 17:43
0

Please follow the below approach you find the all product list based on the category ID's you pass as:

$categoryIds = 2;//category id

$porduct_collection = Mage::getModel('catalog/product')
                             ->getCollection()
                             ->joinField('category_id', 'catalog/category_product', 'category_id', 'product_id = entity_id', null, 'left')
                             ->addAttributeToSelect('*')
                             ->addAttributeToFilter('category_id',  $categoryIds)
                             ->getData();

Where $product_collection contains all the product listing data array associated with above CategoryIDs

You can use this array as you like in your view.phtml page file. Hope this will help you.

4
  • I appreciate this, but I was looking for a solution which allowed the HTML formatting to be done for me in list.phtml. Still useful solution though. Thanks!
    – blisstdev
    Commented Jun 22, 2014 at 17:21
  • Okay Fine, but put this array make sort and get the design . It's very simple
    – Ami Kamboj
    Commented Jun 22, 2014 at 17:27
  • is there a way to "get the design" from list.phtml? List.phtml gets a $_productCollection, is there any way to pass the $product_collection as you have shown to list.phtml?
    – blisstdev
    Commented Jun 22, 2014 at 17:45
  • You want listing page design and product on product detail page ??
    – Ami Kamboj
    Commented Jun 23, 2014 at 0:58

Your Answer

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

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