2

I have a question about a specific product collection on a cms page

I have an amount X of products which have an attribute A which is set to true.

Now I want to have a cms page with some content and then have a number of X products on that page where the attribute is true.

I thought of creating a block and then in that block load the collection and then go through that collection until a certain number is reached

$collection->addFieldToFilter(array(
    array('attribute'=>'is_set','eq'=='true'),
)); 

Then integrate that block in the cms page

{{block type="custom/list" name="custom_list" template="custom/list.phtml}}

But I want to show X number of products and in 6 columns and wonder how I would achieve this in that way?

Thanks

seb
  • 3,572
  • 3
  • 25
  • 57
  • Do you want to limit the collection size for only 5 products? – mbalparda Apr 06 '15 at 20:38
  • No I want to add a certain amount of products shown in 5 or 6 columns where for each product a certain attribute is true – seb Apr 06 '15 at 20:39
  • So you want to limit the collection size of products for only X numbers where for each product a certain attribute is true? The question is if you know the number X. – mbalparda Apr 06 '15 at 20:42
  • I want let's say 72 products out of all my products and these products have all an attribute which I want to filter to be a specific value. These products I want to show in 6 columns so 12 rows. That's an example. Like the attribute would be visibility "4" – seb Apr 06 '15 at 20:44

2 Answers2

5

This can be done with a widget. You can set the widget in the admin panel on a CMS block or a CMS page.

Creating a Widget in Magento

We will need the following files:

app/etc/modules/Thomas_Widget.xml
app/code/local/Thomas/Widget/etc/config.xml
app/code/local/Thomas/Widget/etc/widget.xml
app/code/local/Thomas/Widget/Block/Widget.php
app/code/local/Thomas/Widget/Helper/Data.php
app/design/frontend/{package}/{theme}/path/to/my/widget.phtml

Define Our Module

<?xml version="1.0"?>
<config>
    <modules>
        <Thomas_Widget>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Mage_Cms/>
            </depends>
        </Thomas_Widget>
    </modules>
</config>

Create a Config File:

<?xml version="1.0"?>
<config>
    <modules>
        <Thomas_Widget>
            <version>1.0.0</version>
        </Thomas_Widget>
    </modules>
    <global>
        <blocks>
            <thomas_widget>
                <class>Thomas_Widget_Block</class>
            </thomas_widget>
        </blocks>
        <helpers>
            <thomas_widget>
                <class>Thomas_Widget_Helper</class>
            </thomas_widget>
        </helpers>
    </global>
</config>

Create a Widget Config

<?xml version="1.0"?>
<widget>
    <thomas_widget_products type="thomas_widget/widget" translate="name description" module="thomas_widget">
        <name>List of Products</name>
        <description>A List of Products</description>
        <parameters>
            <limit translate="label">
                <visible>1</visible>
                <required>1</required>
                <label>Number of Products</label>
                <type>text</type>
                <sort_order>20</sort_order>
            </limit>
        </parameters>
    </thomas_widget_products>
</widget>

Create a Helper

(For translation)

<?php
class Thomas_Widget_Helper_Data 
    extends Mage_Core_Helper_Abstract {

}

Create a Widget Block Class

<?php
class Thomas_Widget_Block_Widget
    extends Mage_Core_Block_Template
    implements Mage_Widget_Block_Interface {

    /**
     * Sets the template file
     */
    protected function _construct() {
        $this->setTemplate('path/to/my/widget.phtml');
        parent::_construct();
    }

    /**
     * Sets the collection with the "limit" value we pass
     */
    protected function _prepareLayout() {
        /** @var Mage_Catalog_Model_Resource_Product_Collection $collection */
        $collection = Mage::getModel('catalog/product')->getCollection();

        $collection->addFieldToFilter( array(
                array( 'attribute' => 'is_set', 'eq' == 'true' )
            )
         );

        $limit = $this->getLimit(); // limit="5" from widget

        $collection->setPageSize($limit);

        $this->setCollection($collection);
    }
}

Create Template File

<?php
/** @var Thomas_Widget_Block_Widget $block */
$block = $this;

$collection = $block->getCollection();

if($collection->getSize() > 0) {
    foreach($collection as $product) {
        // Do something with $product object here
    }
}

Using The Widget

Now, you can go to your admin panel and set the widget directly:

Widget Menu

You can also set the widget directly with this:

{{widget type="thomas_widget/widget" limit="5"}}

Summary

This is a basic example. You can go crazy with widgets. You can even define the attribute to filter with!

I hope this helps. Good luck with your widget making!

Ryan Street
  • 2,020
  • 14
  • 12
  • I will give it a try tonight and see how I go. Thanks for all the effort – seb Apr 08 '15 at 11:13
  • I did all the way you´ve written It but somehow I don´t see the widget in my backend. – seb Apr 13 '15 at 11:32
  • Have you tried flushing your caches? Do you see your module showing up in System -> Configuration -> Advanced -> Advanced? Try ensuring your module is loading the correct components by breaking various configurations with developer mode enabled. – Ryan Street Apr 13 '15 at 14:46
3

According to this, there are several ways to limit the collection. One is

$collection = Mage::getModel('model')->getCollection();
$collection->addFieldToFilter(array(
    array('attribute'=>'is_set','eq'=='true'),
));
$collection->getSelect()->limit(72);

You can also pass the number you want to the method from the CMS block call like this

{{block type="custom/list" product_limit="10" name="custom_list" template="custom/list.phtml}}

and retrieve it like this

$collection = Mage::getModel('model')->getCollection();
$collection->addFieldToFilter(array(
    array('attribute'=>'is_set','eq'=='true'),
));
$collection->getSelect()->limit($this->getData(‘product_limit’));
mbalparda
  • 7,363
  • 3
  • 23
  • 46
  • So can I create a .phtml file and just put that in and then call the block that way and what about the columns then? – seb Apr 06 '15 at 20:54
  • I suggest you to copy a layout from the list.phtml or some layout you like. It might be offtopic if you ask another question regarding that since the columns are 100% CSS/HTML and not Magento specific. – mbalparda Apr 06 '15 at 20:56
  • Ok thanks for that. Just a last thing if I call it in a block don't I have to give a category id? Is it fine if the products are not from one category ? – seb Apr 06 '15 at 20:59
  • Category acts as another filter, that is up to you. If you need products from a certain category you can filter the collection by category id, but it is not mandatory. Remember to mark the question as accepted if this is fixed. – mbalparda Apr 06 '15 at 21:00
  • Yeah that all works fine except the pager and everything is not getting it right. Like i can´t set the pager and everything right. I will update my question with some code tomorrow. – seb Apr 07 '15 at 14:03
  • What you comment seems to be about the layout. I suggest you to open a different question for that. – mbalparda Apr 07 '15 at 14:05
  • But keep in mind that this variant can cause an performace issue. The problem is that magento starts from the catalog_product_entity table and joins into the attributes eav table. As a hint i can tell you that its possible to query first the matching entities from the eav table as subquery and join this result to the entity table. – sqlexception Apr 07 '15 at 16:17