Magento - how to filter categories in phtml - magento

I have been working on the maga menu. I got the collection in phtml like:
<?php $_helper = Mage::helper('catalog/category') ?>
<?php $_categories = $_helper->getStoreCategories() ?>
<?php $currentCategory = Mage::registry('current_category') ?>
Now I have to add the filter to show specific categories. Like I have an array(1,2,3,4) of categories that i want to show. so how can I apply filter to this Helper.
Any one have any suggestion please answer.
Thanks.

The first answer is correct but it's not efficient as it consumes unnecessary database round trips. #Karan's code issues a query to the database for every id. Just imagine if the number of category ids to be filtered were 50 or above.
My example would be this:
<?php
$catIds = array(1,2,3,4);
$catCollection = Mage::getModel('catalog/category')->getCollection()->addAttributeToFilter('id', $catIds)->addAttributeToFilter('is_active',1);
foreach($catCollection as $category){
echo $category->getName()." ";
}
This will reduce the database roundtrip to just one.

use this code
<?php $catids[]=array(1,2,3,4);
foreach($catids as $id):
$_category = Mage::getModel('catalog/category')->load($id);
if($_category->getIsActive()):
echo $_category->getName();
endif;
endforeach;
?>
and don't forget to link my answer if it was helpful

Related

Subcategory list with Magento Flat Catalog

I'm using the code below to get a list of categories on the same level as the current page (by listing the subcategories of this category's parent). It works great when Flat Categories are off. Once I enable Flat Categories, the H2 works correctly, but the list changes to display the root's subcategories instead of this page's parent's subcategories. What am I doing wrong, and why does it act this way?
<?php
$_category = $this->getCurrentCategory();
$parentCategoryId = $_category->getParentId();
$collection = Mage::getModel('catalog/category')->getCategories($parentCategoryId);
$helper = Mage::helper('catalog/category');
$parentCategory = Mage::getModel('catalog/category')->load($parentCategoryId);
?>
<h2><?php echo $parentCategory->getName(); ?></h2>
<ul>
<?php foreach ($collection as $cat):?>
<?php if($_category->getIsActive()): ?>
<li <?php
if ($cat->getId() == $_category->getId()) {
echo 'class="current"';
}
?>>
<?php echo $cat->getName();?>
</li>
<?php endif; ?>
<?php endforeach;?>
</ul>
Yes, I've flushed the cache and indexes.
I don't completely know why ->getCategories($id) is not "flat-safe", but using Stefan's suggestion helped me find an alternate method for this instead.
My new lines at top look like this:
$_category = $this->getCurrentCategory();
$parentCategoryId = $_category->getParentId();
$helper = Mage::helper('catalog/category');
$parentCategory = Mage::getModel('catalog/category')->load($parentCategoryId);
$collection = $parentCategory->getChildrenCategories();
... which works regardless of 'flat catalog' on or off.

How to make second root category navigation in magento?

Other than the normal navigation I get when I add subcategories to the main root category, I want to be able to make a new root category, assign subcategories to it and have it display as a separate menu.
Is this possible?
May this can help you :Link 1Link 2
To retrieve another root category
<?php
echo '<pre>';
$id=9;
$catagory_model = Mage::getModel('catalog/category');
$categories = $catagory_model->load($id); // where $id will be the known category id
if(!empty($categories))
{
echo 'category name->'.$categories->getName(); //get category name
echo '<br>';
echo 'category image url->'.$categories->getImageUrl(); //get category image url
echo '<br>';
echo 'category url path->'.$categories->getUrlPath(); //get category url path
echo '<br>';
}
?>
now $id=9; is my new root category id.
To retrieve sub categories of these new root category ($id=9;) below is the following reference code.Customize it according to your requirements.
<?php $helper = $this->helper('catalog/category') ?>
<?php $categories = $this->getStoreCategories() ?>
<?php foreach($categories as $category): ?>
<?php $subcategories = $category->getChildren() ?>
<?php foreach($subcategories as $subcategory): ?>
<?php $subsubcategories = $subcategory->getChildren() ?>
<?php foreach($subsubcategories as $subsubcategory): ?>
<?php endforeach; ?><!-- end foreach subsubcategories -->
<?php endforeach; ?><!-- end foreach subcategories -->
<?php endforeach; ?><!-- end foreach categories -->
In an ideal world you would have found the answer by now, but in case you didn't I modified Nikhil's answer to work for me to basically do what you describe, minus any convenience at all...
$id=9;
$catagory_model = Mage::getModel('catalog/category');
$categories = $catagory_model->load($id);
if(!empty($categories))
{
$cats = explode(",", $categories->getChildren());
foreach($cats AS $c)
{
$cat = $catagory_model->load(trim($c));
echo ''.$cat->getName().'';
}
}
I'm just pasting what I used. The reality is you will have to build the html to make this do whatever you want it to do. If you have subcategories within your loop, you will have to run another fetch in the foreach part.
I am not familiar with magento enough to know what methods you can run on the $cat object. I did a print_r($cat) to examine the object and made a lucky guess that getUrlKey would be available.
Magento... pfft! you'd think ebay would have higher standards than this.

Magento - Filter Category list by category attribute

I have a list of store categories, and everything is working well except for one thing. I would like the list of categories to omit any that are set as 'Include in Navivation Menu = No'.
I can tell at this point that this attribute is not being loaded, but I'm having a difficult time figuring out where to place the filter. Currently, I am getting my category list via:
<?php $_helper = Mage::helper('catalog/category') ?>
<?php $_categories = $_helper->getStoreCategories() ?>
Followed by:
<?php foreach ($_categories as $_category) : ?>
<?php $_category = Mage::getModel('catalog/category')->load($_category->getId()) ?>
...
...
At this point, I have my category objects how I want them. But if I run a debug on these objects, the 'include_in_menu' attribute is not listed.
So for some reason:
<?php $_subCategory->getIncludeInMenu() ?>
Was not working for me after I ran:
<?php foreach($_parentCategory->getChildrenCategories() as $_subCategory) : ?>
The object was still the same model, but ['include_in_menu'] was no longer part of the object. I don't like this solution, but I just reconverted the object back:
<?php $_subCategory = Mage::getModel('catalog/category')->load($_subCategory->getId()) ?>
And then it worked fine. Not sure why getting the children would strip down the object, but it does.

Sorting categories in Magento according to the position in admin

I would like to know how to sort this list of categories (I followed this tutorial here http://www.devinrolsen.com/magento-custom-category-listing-block/) in magento by position in the admin panel? Currently it is sorted by id
<?php
$cats = Mage::getModel('catalog/category')->load(3)->getChildren();
$catIds = explode(',',$cats);
?>
<ul>
<?php foreach($catIds as $catId): ?>
<li>
<?php
$category = Mage::getModel('catalog/category')->load($catId);
echo '<a href="' . $category->getUrl() . '">';
echo $category->getName() . '</a>';
?>
</li>
<?php endforeach; ?>
</ul>
You're making way too much work for yourself trying to deal with IDs and stuff. The following is already sorted by position as standard.
<?php
$cats = Mage::getModel('catalog/category')->load(3)->getChildrenCategories();
?>
<ul>
<?php foreach($cats as $category): ?>
<li>
<?php echo $category->getName() ?>
</li>
<?php endforeach; ?>
</ul>
If you want to sort the categories by the position created in adminhtml you can then, since catalog/category is an instance of Mage_Catalog_Model_Resource_Category_Collection, make a query where you specify what you want to select, filter and/or sort.
The case here is getting categories from catalog_category_entity select only the name, filtering after the id and sort the query on the position.
<?php
$subcategories = Mage::getModel('catalog/category')->getCollection()
->addAttributeToSelect('name')
->addFieldToFilter('parent_id', $categoryId)
->addAttributeToSort('position', ASC);
?>
This is what I did:
$allCategories = Mage::getModel('catalog/category');
$CategoriesTree = $allCategories->getTreeModel()->load();
$categoriesIds =
$CategoriesTree->getCollection()->addAttributeToSort('position', 'asc')->getAllIds();
after to retrieve the categories:
$categoryChildren = array();
if ($categoriesIds) {
foreach ($categoriesIds as $categoryId){
$category = Mage::getModel('catalog/category')->load($categoryId);
$categoryChildren[] = $category;
}
}
and then:
// Sort by position
function comparePosition($a, $b) {
if ($a->position == $b->position)
return 0;
return ($a->position > $b->position) ? 1 : -1;
}
usort($categoryChildren, 'comparePosition');
Inverting the return (1 and -1) would obviously change the order.
It worked just fine for me.
Hope it helps someone.
I strongly suggest to lok here first http://www.magentocommerce.com/knowledge-base/entry/magento-for-dev-part-8-varien-data-collections and also other articles in knowledge base are a must read for any magento dev.
<?php
$cats = Mage::getModel('catalog/category')->addAttributeToSort('yourfield', 'desc')->getCollection()->getChildren();
$catIds = explode(',',$cats);
?>
<?php
$model_category = Mage::getModel('catalog/category')->load($_category->getEntityId());
$sub_categories = $model_category->getCollection();
$sub_categories -> addAttributeToSelect('url_key')
-> addAttributeToSelect('name')
-> addAttributeToFilter('is_active',1)
-> addIdFilter($model_category->getChildren())
-> setOrder('position', 'ASC')
-> load();
?>
<?php foreach($sub_categories->getData() as $each_subcat): ?>
<?php $model_subcat = Mage::getModel('catalog/category')->load($each_subcat['entity_id']); ?>
<?php endforeach; ?>

MAGENTO getting the descriptions from a sub category

Hi I'm new to magento and have been trying to set up a static block that displays a list of sub categories within a category. I've been succesfull a grabbing the sub-category images and names, but for some reason I can't seem to get the descriptions to show.
Here's the code can't anyone explain why it won't work and how I can fix it?
I've commented out a few lines because I was trying different things to get it to work.
helper('catalog/output');
$category = $this->getCurrentCategory();
getCurrentChildCategories();
?>
<?php foreach ($_categories as $_category): ?> <?php echo
$this->htmlEscape($_category->getCategoryDescription());?>
<?php if($_category->getIsActive()): ?>
<div class="subcategory-image">
<a href="<?php echo $_category->getURL()
?>" title="htmlEscape($_category->getName())
?>">
</a>
<?php /* echo "Find this item->" */ ?>
</div> <div class="sub-category-container">
<h2><a href="<?php echo $_category->getURL()
?>" title="htmlEscape($_category->getName())
?>">htmlEscape($_category->getName())
?>
getURL() ?>"
class="moreLink">[MORE...]
getDescription() ?>-->
getDescription()):
?>
categoryAttribute($_category, $_description, 'description'); ?>
-->
This is one of those cases where Varien decided that they should call "load" on the data collection before returning it when that really isn't necessary and makes the utility function utterly useless.. If you trace the code down for Mage_Catalog_Block_Navigation->getChildrenCategories() you will eventually find this in Mage_Catalog_Model_Resource_Eav_Mysql4_Category:
public function getChildrenCategories($category)
{
$collection = $category->getCollection();
/* #var $collection Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection */
$collection->addAttributeToSelect('url_key')
->addAttributeToSelect('name')
->addAttributeToSelect('all_children')
->addAttributeToSelect('is_anchor')
->addAttributeToFilter('is_active', 1)
->addIdFilter($category->getChildren())
->setOrder('position', 'ASC')
->joinUrlRewrite()
->load();
return $collection;
}
The next to last line ->load(); means that the query is executed and the collection is loaded so it is too late to modify the query. So what you will want to do is copy and paste that in place of calling getChildrenCategories and then add the additional attributes you want to use like so:
$_categories = $category->getCollection()
->addAttributeToSelect(
array('url_key','name','all_children','is_anchor','description')
)
->addAttributeToFilter('is_active', 1)
->addIdFilter($category->getChildren())
->setOrder('position', 'ASC')
->joinUrlRewrite()
;
Now the collection will include the description attribute so that getDescription() will work. Notice that you do not need to call load(), it happens automatically when you start using the iterator (the foreach loop triggers this). This is why it is pointless for the load() call to be included in that function because otherwise you could have just added one line below the function call:
$categories->addAttributeToSelect('description');
But instead you have to copy the contents of the function to tweak the query.
Change:
$_category->getCategoryDescription()
To this:
$_category->getDescription()

Resources