CMS – Show Products with Specific Attribute on CMS Page

cms

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

Best Answer

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!