Some custom Blocks to help you show products
Posted on 07. Oct, 2008 by Fido in Development, Magento, Module
I have a few custom blocks I’ve written / copied and tweaked from various posts on Magento’s forums. I noticed they are pretty universal in how they grab, filter and return a product collection to be used in various template files (.phtml files). The blocks below should all work from List.phtml (app\design\frontend\default\default\template\catalog\product\list.phtml).
These are Block files and are most appropriately used within the Catalog/Product area. (See my post on creating a custom module – these files won’t be overwriting any other class but can stand alone).
Be aware that the code below contains code for custom attributes that I happened to use on a project. They most likely will not be the same your particular instances. (the Bestseller block should not be affected by this issue).
Bestseller.php
//bestseller module - grabs from all products, returns in order of total quantity ordered
class Mage_Catalog_Block_Product_Bestseller extends Mage_Catalog_Block_Product_Abstract
{
public function __construct()
{
parent::__construct();
$storeId = Mage::app()->getStore()->getId();
$products = Mage::getResourceModel(’reports/product_collection’)
->addOrderedQty()
->addAttributeToSelect(array(’name’, ‘price’, ’small_image’, ’short_description’, ‘description’, ‘author’))
->setStoreId($storeId)
->addStoreFilter($storeId)
->setOrder(’ordered_qty’, ‘desc’);
Mage::getSingleton(’catalog/product_status’)->addVisibleFilterToCollection($products);
Mage::getSingleton(’catalog/product_visibility’)->addVisibleInCatalogFilterToCollection($products);
//$products->setPageSize(6)->setCurPage(1);
$this->setProductCollection($products);
}
}
?>
SpecificCategory.php
<?php
//Grab products from a specific category - in this case category 13
class Mage_Catalog_Block_Product_Bookclub extends Mage_Catalog_Block_Product_Abstract
{
public $_collection;
protected function _getProductCollection()
{
$storeId = Mage::app()->getStore()->getId();
$product = Mage::getModel('catalog/product');
$category = Mage::getModel('catalog/category')->load(13); //category whos ID is 13
$visibility = array(
Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG
);
$products = $product->setStoreId($storeId)
->getCollection()
->addAttributeToFilter('visibility', $visibility)
->addCategoryFilter($category)
->addAttributeToSelect(array('name', 'price', 'small_image', 'short_description', 'description', 'author'), 'inner') //example custom attributes
->setOrder('created_at', 'desc')
->addAttributeToSelect(array('special_price', 'special_from_date', 'special_to_date'), 'left')
;
$this->_collection = $products;
return $this->_collection;
}
public function getCurrentCategory() {
return Mage::getModel('catalog/category')->load(13);
}
public function getProductCollection() {
return $this->_getProductCollection();
}
}
?>
SpecificCategoryLayer.php
<?php
/*This is the same as above but grabs the product collection from the 'catalog/layer' singleton.
I've had to use this in some pre-1.1.x Magento builds because the above code version created some
weird errors when users edited any product in the backend (resulting in front end server time outs). That error was probably local to that Magento build, but it resulted in this code.
Note on use: You can only set the category of the layer once per page request, so you CANNOT use
this block of code multiple times on one page unless you want to repeat products from the same
category multiple times on one page.
*/
class Mage_Catalog_Block_Product_Bookclub extends Mage_Catalog_Block_Product_Abstract
{
public $_collection;
protected function _getProductCollection()
{
$storeId = Mage::app()->getStore()->getId();
$product = Mage::getModel('catalog/product');
$layer = Mage::getSingleton('catalog/layer');
$category = Mage::getModel('catalog/category')->load(13); //category by ID
$layer->setCurrentCategory($category);
$visibility = array(
Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG
);
$products = $layer->getProductCollection()
->addAttributeToSelect('author', 'inner') //example custom attributes
->addAttributeToSelect('shelf_talker', 'inner')
->setOrder('created_at', 'desc');
$this->_collection = $products;
return $this->_collection;
}
public function getCurrentCategory() {
return Mage::getModel('catalog/category')->load(13);
}
public function getProductCollection() {
return $this->_getProductCollection();
}
}
?>
These blocks do not represent all there is to making use of them. As mentioned, these should all work with “List.phtml” in the Catalog module design files, but you might want to create your own template.
The easiest way to implement these and make them usable is to add them to a Mage folder within the Local code folder (rather than core):
app/code/local/Mage/Catalog/Block/Product/Bestseller.php
This lets you skip the step of creating a custom module in order to use a simple block who’s only purpose is to list a category of products (or bestsellers in this case).




20 Comments
Run Magento Code Outside of Magento | Explore Magento
03. Nov, 2008
[...] grabs a product collection. In this case, we are able to set the category id to 3. (See the post on custom blocks to help you get a feel for what this might look [...]
Rem
17. Nov, 2008
Hi,
Nice post, could have a lot of potential but can you advice please on how to further use the Bestseller class after you save it on /app/code/local/Mage/Catalog/Block/Product/Bestseller.php ?
Thanks a lot!
Fido
17. Nov, 2008
The blocks should all work from List.phtml (app\design\frontend\default\default\template\catalog\product\list.phtml).
You can then set this block anywhere, using something like:
or within the system CMS:
{{block type=”catalog/bestseller” template=”catalog/product/list.phtml”}}
Note that the “type” and “template” attributes will change depending on where you save your block and template.
Richard
22. Jan, 2009
I’m trying to get this to work but I’m not sure if I’m doing this correctly.
ok, I created a used.php in directory (local/Mage/Catalog/Block/Product/)
Then I copied and pasted your code for “specificcategory.php” into used.php and edited lines:
class Mage_Catalog_Block_Product_Bookclub
to read
class Mage_Catalog_Block_Product_Used
and inputed my category id in the two lines
Then I attempted to set the block in a static block reading:
{{block type=”catalog/product_used” template=”catalog/product/list.phtml”}}
I thought that would do the trick but I’m getting a sql error basically saying it didn’t find the category.
Fatal error: Call to a member function count() on a non-object in C:\webserver\htdocs\lovetheprice\app\design\frontend\default\blank\template\catalog\product\list.phtml on line 35
What do you think?
Fido
22. Jan, 2009
It looks like we need to look at list.phtml and see where the “count” function is being call (and on what). List.phtml might be expecting that function to be available when it is not in your “used.php” block
matt
09. Feb, 2009
Thanks for sharing this code. Any tips on how to extend it to filter through more than one category? I have items in two categories (neither of which are sub-categories), and I’m trying to call addCategoryFilter two times on the same product collection but get an SQL error …
cheers
Fido
09. Feb, 2009
Matt, have you attempted: “->addCategoryFilter(array(’cat1′, ‘cat2′))” ?
Passing an array might give you the results you want if you have not tried this already (versus using “addCategoryFilter” twice).
I also suggest looking at the newest blog post here as it gives a more in depth look using one of these blocks (using the Magento toolbar)
matt
09. Feb, 2009
Hi Fido,
Thanks for the idea. Unfortunately ->addCategoryFilter(…) doesn’t take an array. There’s even a second parameter to create an aliased indexing name so that a clash doesn’t occur, and I’ve managed to call the function with any errors, but the results don’t change so I’m not sure if it’s even working or not.
This “filter by multiple categories” issue seems to be a popular one in the Magento forums. I’ll take a look at your newest post, but if you have time to address multi-category filtering, I know many will appreciate it!
Thanks again.
Fariz
12. Apr, 2009
Hello. Magento has everything but a latest products block/module. Can this be implemented to make a latest products block/module?
Thank you and it would be nice if you can email me if you replied.
Fido
12. Apr, 2009
Hi Fariz – This functionality actually does exist
In a fresh install of Magento, there is some commented out XML in the CMS area for the homepage’s “Custom Design” Update Layout XML field. (CMS > Manage Pages > Home Page > Custom Design tab > Layout Update XML field).
This points to a block which displays new products.
If you want to integrate that code into another block of your creation, you can reuse that code – the file for the Block is located in app/code/core/Mage/Catalog/Block/Product/New.php
Monica Olinescu
29. Apr, 2009
Hi Fido!
Thanks a lot for this post, the bestseller example worked great for me.
Just one comment, in the post the code for this example is not displayed in the code box, ’cause you forgot to close the quote. :p
[code='php]
Shaun Butler
13. May, 2009
Fido, am I doing this correctly?
Like Richard I did the same;
- Saved the code you posted as catspec.php in
app/code/core/mage/catalog/block/catspec.php
- Changed the two instances of the category numbers.
- Changed class Mage_Catalog_Block_Product_Bookclub to class Mage_Catalog_Block_Product_Catspec
- Added {{block type=”catalog/Catspec” template=”catalog/product/list.phtml”}} to to my static block on CMS.
On the page in which I included the above mentioned static block, I see the text I included in the static block, but not my “catspec” block.
Am I doing something wrong?
- Kind regrads,
Shaun
Zeke
19. May, 2009
Regarding the member function error. Add this:
public function getLoadedProductCollection() {
return $this->_getProductCollection();
}
x4hai
22. May, 2009
I use Free CMS module, it’s very useful. You can see the demo here: http://demo.hello-magento.com/freecms/furniture.html
Pixxa
27. May, 2009
Im also getting:
Fatal error: Call to a member function count() on a non-object
When flat catalog is enabled.
Please advise, as the developer wont give support and only wants to see $$$
Name
22. Jul, 2009
Fatal error: Call to a member function isStatic() on a non-object in D:\xampp\htdocs\magento\app\code\core\Mage\Eav\Model\Entity\Collection\Abstract.php on line 373
Name
22. Jul, 2009
I m getting
Fatal error: Call to a member function isStatic() on a non-object in D:\xampp\htdocs\magento\app\code\core\Mage\Eav\Model\Entity\Collection\Abstract.php on line 373
Oren Yomtov
05. Aug, 2009
Fatal error: Call to a member function isStatic() on a non-object in D:\xampp\htdocs\magento\app\code\core\Mage\Eav\Model\Entity\Collection\Abstract.php on line 373
Magento Developer
05. Aug, 2009
I found the solution!
Replace the line
->addAttributeToSelect(array(’name’, ‘price’, ’small_image’, ’short_description’, ‘description’, ‘author’), ‘inner’)
with
->addAttributeToSelect(array(’name’, ‘price’, ’small_image’, ’short_description’, ‘description’), ‘inner’)
or just remove the
, ‘author’
dinesh
16. Sep, 2009
Thanks buddy …………
Leave a reply