Does anyone know how I can get a list of products belonging to a specific category from within a view file in Magento?
8 Answers
You can use magento object to filter.
Example:
$categoryId = 123; // a category id that you can get from admin
$category = Mage::getModel('catalog/category')->load($categoryId);
$products = Mage::getModel('catalog/product')
->getCollection()
->addCategoryFilter($category)
->load();
print_r($products);
It all depends on which view you're in. ;-)
First off, I hope you stayed within your template set (default in my example).
Use this as an example:
<?php
$_cat = $this->getCurrentCategory();
$_parent = $_cat->getParentCategory();
$_categories = $_parent->getChildren();
/* @var $category Mage_Catalog_Model_Category */
$collection = Mage::getModel('catalog/category')->getCollection();
/* @var $collection Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection */
$collection->addAttributeToSelect('url_key')
->addAttributeToSelect('name')
->addAttributeToSelect('is_anchor')
->addAttributeToFilter('is_active', 1)
->addIdFilter($_categories)
->setOrder('position', 'ASC')
->joinUrlRewrite()
->load();
$productCollection = Mage::getResourceModel('catalog/product_collection');
$layer = Mage::getSingleton('catalog/layer');
$layer->prepareProductCollection($productCollection);
$productCollection->addCountToCategories($collection);
// $productCollection should be ready here ;-)
?>
I'm using the above code to display sister categories in my template - it's not ideal but it works.
It's sort of a hack because I did not yet have time to learn all the layout XML madness. Otherwise if you use the XMLs you need to keep in mind - it all depends on where you are at. Where means the template file and essentially also the layout (in terms of app/design/frontend/default/default/layout/*).
I know it's not much, but I hope it helps to get you started.
Here is the code to get products from any particular category. You can use this in view file as well.
// if you want to display products from current category
$category = Mage::registry('current_category');
// if you want to display products from any specific category
$categoryId = 10;
$category = Mage::getModel('catalog/category')->load($categoryId);
$productCollection = Mage::getResourceModel('catalog/product_collection')
->addCategoryFilter($category);
// printing products name
foreach ($productCollection as $product) {
echo $product->getName();
echo "<br />";
}
<?php
$c_id = 2;
$category = new Mage_Catalog_Model_Category();
$category->load($c_id);
$collection = $category->getProductCollection();
$collection->addAttributeToSelect('*');
foreach ($collection as $_product) { ?>
<a href="<?php echo $_product->getProductUrl(); ?>"><?php echo $_product->getName(); ?></a>
<?php } ?>
I pretty much needed the same. Here is how I have done it:
$prod_whole = array();
if(!empty($_menu)) //$_menu = array of Categories with some basic info
foreach($_menu as $v)
{
if($v['name']=='HOME')
continue;
$cat_id = $v['id'];
#/ Setup Products
$category = Mage::getModel('catalog/category')->load($cat_id);
$collection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect('*') // select all attributes
->addCategoryFilter($category)
->setPageSize(8) // limit number of results returned
->setCurPage(0)
->load()
;
$prod_collection = array();
foreach ($collection as $product)
{
$prod_collection_1 = array();
#/ Basic Info
$prod_collection_1['id'] = $product->getId();
$prod_collection_1['name'] = $product->getName();
$prod_collection_1['price'] = (float) $product->getPrice();
//$prod_collection_1['desc'] = $product->getDescription();
//$prod_collection_1['short'] = $product->getShortDescription();
$prod_collection_1['type'] = $product->getTypeId();
$prod_collection_1['status'] = $product->getStatus();
$prod_collection_1['special_price'] = $product->getSpecialPrice();
$prod_collection_1['direct_url'] = $product->getProductUrl();
#/ getCategoryIds(); returns an array of category IDs associated with the product
foreach ($product->getCategoryIds() as $category_id)
{
$category = Mage::getModel('catalog/category')->load($category_id);
$prod_collection_1['parent_category'] = $category->getParentCategory()->getName();
$prod_collection_1['category'] = $category->getName();
//$prod_collection_1['category_idx'] = preg_replace('/[\s\'\"]/i', '_', strtolower(trim($prod_collection_1['category'])));
$prod_collection_1['category_id'] = $category->getId();
}
#/gets the image url of the product
$prod_collection_1['img'] = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA).'catalog/product'.$product->getImage();
$prod_collection[] = $prod_collection_1;
}//end foreach.....
$prod_whole[$cat_id] = $prod_collection;
}//end foreach categories.......
//var_dump('<pre>', $prod_whole);
Hope this helps.
<?php
$category_id = 10; // if you know static category then enter number
$catagory_model = Mage::getModel('catalog/category')->load($category_id); //where $category_id is the id of the category
$collection = Mage::getResourceModel('catalog/product_collection');
$collection->addCategoryFilter($catagory_model); //category filter
$collection->addAttributeToFilter('status',1); //only enabled product
$collection->addAttributeToSelect(array('name','url','small_image')); //add product attribute to be fetched
//$collection->getSelect()->order('rand()'); //uncomment to get products in random order
$collection->addStoreFilter();
if(!empty($collection))
{
foreach ($collection as $_product):
echo $_product->getName(); //get product name
endforeach;
}else
{
echo 'No products exists';
}
?>
You should always avoid putting code like this into a view, it's very bad practice. You can also run into issues as views can be cached, leading to unexpected behaviour.
you should override the block you are using, placing code there. you can then call any new methods inside your view files.
for example, you could copy Mage_Catalog_Block_Product_List
from: app/code/core/Catalog/Block/Product/List.php
to: app/code/local/Catalog/Block/Product/List.php
you could then add a new method, possibly using some of the code mentioned in the above posts. your new method would then be available inside your view file (list.phtml or any view using this block)
Here is a code to export all product with it's category into csv
<?php
set_time_limit(0);
ini_set("memory_limit",-1);
ini_set('max_execution_time','1800000000');
require_once '../app/Mage.php';
Mage::app();
$category = Mage::getModel('catalog/category');
$tree = $category->getTreeModel();
$tree->load();
$ids = $tree->getCollection()->getAllIds();
$fp = fopen('category-product-export.csv', 'w');
$field = array('Product SKU','Category Name');
fputcsv($fp, $field);
$_productCollection = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect('*')
->addFieldToFilter('visibility', Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH)
->load();
foreach ($_productCollection as $_product){
$cats = $_product->getCategoryIds();
$cnt = 0;
$catName = '';
foreach($cats as $id) {
$category->load($id);
$root = 'Root Catalog';
$isRoot = strtolower($root);
$categoryName = strtolower($category->getName());
if($categoryName == $isRoot){
continue;
}
$categories[$id]['name'] = $category->getName();
$categories[$id]['path'] = $category->getPath();
$path = explode('/', $categories[$id]['path']);
$len = count($path);
$string = '';
if($id > 2){
foreach ($path as $k=>$pathId)
{
$separator = '';
if($pathId > 2){
$category->load($pathId);
if($k != $len-1){ $separator = ' || ';}
$string.= $category->getName() . $separator;
}
}
if($cnt > 0) {
$catName.= ','.$string;
} else {
$catName = $string;
}
$cnt++;
}
}
//echo $catName;
$field = array($_product->getSku(),$catName);
fputcsv($fp, $field);
}
?>
<a href="category-product-export.csv">Download</a>