Magento - list categories, subcategories, and images in phtml file - image

I'm trying to create a dropdown menu located in header of each of my Magento pages. I want to list all of the categories, the subcategories, and the associated images with each. From scraping and combining code from the Internet, I've come up with a solution that almost works, only the URLs for the subcategories are returning as undefined, and I don't know why. Any ideas? Here's my code:
<?php
$cats = Mage::getModel('catalog/category') -> load(2) -> getChildren();
$catIds = explode(',', $cats);
$categories = array();
foreach ($catIds as $catId) {
$category = Mage::getModel('catalog/category') -> load($catId);
$categories[$category -> getName()] = array('name' => $category -> getName(), 'url' => $category -> getUrl(), 'img' => $category -> getImageUrl(), 'subcategories' => Mage::getModel('catalog/category') -> getCategories($catId));
}
ksort($categories, SORT_STRING);
?>
<ul>
<?php foreach($categories as $name => $data): ?>
<li><?php echo $data['name']; ?>
<a href="<?php echo $data['url']; ?>" title="<?php echo $name; ?>">
<img class="cat-image" src="<?php echo $data['img']; ?>" />
</a>
<ul>
<?php
foreach ($data['subcategories'] as $subcategory) {
echo "<a href='" . $subcategory -> getUrl() . "'><li>" . $subcategory -> getName() . "</li></a>";
}
?>
</ul>
</li>
<?php endforeach; ?>
</ul>

Try changing
'subcategories' => Mage::getModel('catalog/category') -> getCategories($catId)
to
'subcategories' => $category->getChildrenCategories()
See How To Get Sub Categories in Magento ?`

Related

Subcategories in layered navigation filter

I have a category with simple two-level structure like this:
Category #1
- Subcategory
- Subcategory
- ...
Category #2
- Subcategory
- Subcategory
- ...
Currently to filter by subcategories - you have to select top-level category first.
How to show subcategories of all top-level categories in layered navigation filter?
Note: Subcategories should by effected by other selected attribute filter.
While experimenting with Magento files I've found the answer to my question.
Copy app/code/core/Mage/Catalog/Model/Layer/Filter/Category.php to app/code/local/Mage/Catalog/Model/Layer/Filter/Category.php
Open copied file. And replace _getItemsData with code below:
/**
* Get data array for building category filter items
*
* #return array
*/
protected function _getItemsData()
{
$key = $this->getLayer()->getStateKey().'_SUBCATEGORIES';
$data = $this->getLayer()->getAggregator()->getCacheData($key);
if ($data === null) {
// Get root category
$root_category = Mage::getModel('catalog/category')->load(2);
// Get main categories
$data = array();
$main_categories = $root_category->getChildrenCategories();
foreach ($main_categories as $main_category) {
if (!$main_category->getIsActive()) continue; // Ommit inactive
// Get sub categories to list
$sub_categories = $main_category->getChildrenCategories();
// Add count to subcategories
$this->getLayer()->getProductCollection()
->addCountToCategories($sub_categories);
foreach ($sub_categories as $sub_category) {
// Ommit inactive and zero product count sub categories
if ($sub_category->getIsActive() || !$sub_category->getProductCount()) continue;
// Output subcategories
$data[] = array(
'label' => Mage::helper('core')->htmlEscape($sub_category->getName()),
'value' => $sub_category->getId(),
'count' => $sub_category->getProductCount(),
'parent' => $main_category->getName(), // Store parent name to group in template
);
}
}
$tags = $this->getLayer()->getStateTags();
$this->getLayer()->getAggregator()->saveCacheData($data, $key, $tags);
}
return $data;
}
You might be interested in rewriting some other functions such as getResetValue, etc.
I had to rewrite template to group subcategories by main categories.
Result (sorry cant post images directly):
Before:
http://i.stack.imgur.com/skZpi.png
After:
http://i.stack.imgur.com/QxPhq.png
you can use the below code to show all subcategories of a current category in your sidebar or wherever
<?php $_helper = Mage::helper('catalog/category') ?>
<?php $_categories = $_helper->getStoreCategories() ?>
<?php $currentCategory = Mage::registry('current_category') ?>
<?php if (count($_categories) > 0): ?>
<ul>
<?php foreach($_categories as $_category): ?>
<li>
<a href="<?php echo $_helper->getCategoryUrl($_category) ?>">
<?php echo $_category->getName() ?>
</a>
<?php $_category = Mage::getModel('catalog/category')->load($_category->getId()) ?>
<?php $_subcategories = $_category->getChildrenCategories() ?>
<?php if (count($_subcategories) > 0): ?>
<ul>
<?php foreach($_subcategories as $_subcategory): ?>
<li>
<a href="<?php echo $_helper->getCategoryUrl($_subcategory) ?>">
<?php echo $_subcategory->getName() ?>
</a>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>

Very slow product list issue with magento

I have a category called new arrivals which has 5 subcategories. I created a custom view called new-arrivals.phtml. I created custom Static Block with the following code in magento
{{block type="core/template" template="custom/new-arrivals.phtml"}}
then from Category setting I changed the display setting>CMS Block to the this cms block that I created. And the display mode is static block only
This view bring all the subcategories of New Arrivals(Bags, Tops, Shoes etc..) with it's products.. Like on this website As you can see on this website it is very fast but on my website with my code it is not. Here it is...
How can I make this load faster. Cache and everything is enabled. I assume that there is something wrong with my code. thank you for your help.
and this is new-arrivals.phtml content:
Magento CE 1.8.1
<?php
//I load all the subcategories here
$category = Mage::getSingleton('catalog/layer')->getCurrentCategory();
$categories = $category->getCollection()
->addAttributeToSelect(array('name', 'thumbnail'))
->addAttributeToFilter('is_active', 1)
->addIdFilter($category->getChildren())
?>
<?php foreach ($categories as $category): ?>
<div class="page-title category-title">
<h1>
<a href="<?php echo $category->getUrl() ?>">
<span><?php echo $category->getName() ?></span>
</a>
</h1>
<?php
// here I load all the products for each category
$_helper = $this->helper('catalog/output');
$category = Mage::getModel('catalog/category')->load($category->getId());
$_productCollection = $category->getProductCollection()->addCategoryFilter($category)
->addAttributeToSelect('*') // add all attributes - optional
->addAttributeToFilter('status', 1) // enabled
->addAttributeToFilter('visibility', 4) //visibility in catalog,search
->addAttributeToSort('date_added', 'ASC');
?>
<div class="product-count"><?php echo $count; ?> <?php echo $this->__('Products'); ?></div>
<?php if(!$_productCollection->count()): ?>
<p class="note-msg"><?php echo $this->__('There are no products matching the selection.') ?></p>
<?php else: ?>
<div class="category-products">
<?php // Grid Mode ?>
<?php
$_span = 'span3';
$_grid_pro = 4;
?>
<?php $_collectionSize = $_productCollection->count() ?>
<?php $_columnCount = $_grid_pro; //$this->getColumnCount(); ?>
<?php $i=0; foreach ($_productCollection as $_product): ?>
<?php if ($i++%$_columnCount==0): ?>
<?php // all the others stuff ....... ?>
Load this file using ajax or jquery.
Second one you run your code on footer and make one variable then using jquery or java script, you will show your all data in particular div, for example like this
if (count($_subcategories) > 0){
$top_menu .= '<ul>';
foreach($_subcategories as $_subcategory){
$prodCollection = Mage::getModel('catalog/category')- >load($_subcategory->getId())
->getProductCollection()
->addAttributeToSelect('*')
->addAttributeToFilter('type_id', array('eq' => 'grouped'))
->addAttributeToFilter('no_to_show', array('F' => 78));
if($prodCollection->count() !=0){
$top_menu .= '<li'; if($current_category == $_subcategory->getId()){$top_menu .= ' id="activesub"';}$top_menu .= '>'.$_subcategory->getName().'';
$_subcategories = Mage::getModel('catalog/category')->load($_subcategory->getId());
$_childsub = $_subcategories->getChildrenCategories();
$CatTotalCount = count($_childsub);
if($cntr == 0){
$firstCount = $CatTotalCount;
}
if($firstCount >= 7){
$loopCount = ($firstCount-1);
}else{
$loopCount = 6;
}
if($CatTotalCount >0){
$top_menu .= '<ul>';
$secCntr = 0;
foreach($_childsub as $_child_subcat){
$prodCollection2 = Mage::getModel('catalog/category')->load($_child_subcat->getId())->getProductCollection()->addAttributeToSelect('*')->addAttributeToFilter('type_id', array('eq' => 'grouped'))->addAttributeToFilter('no_to_show', array('F' => 78));
if( $secCntr>$loopCount){
$secCntr = 0;
$top_menu .= '</ul><ul>';
}
$secCntr++;
if($prodCollection2->count() !=0):
$top_menu .= '<li'; if($current_category == $_child_subcat->getId()){$top_menu .= ' id="activesub"';}$top_menu .= '>'.$_child_subcat->getName().'</li>';
endif;
} }
}
$top_menu .= '</ul></li>';
$cntr++;
}
$top_menu .= '</ul>';
}
jQuery(document).ready(function() {
document.getElementById('top_menus').innerHTML = '';
jQuery('#mega-menu-8').dcMegaMenu({
rowItems: '3',
speed: 'fast',
effect: 'fade'
});
});

Get specific category level

How can I get a specific category level from Magento, my category setup looks like this now.
root_catalog
|-Shop
|-Shoes
|-T-shirts
|-Brands
|-Nike
|-Womens
|-Mens
|-Adidas
|-Asics
<?php if( $category = Mage::getModel('catalog/category')->load( $categories[1]) ): ?>
<?php echo $category->getName(); ?>
<?php endif ?>
When calling $category->getName(); I would like to only display the Brand Name, is that possible?
You can get category level from
$category = Mage::getModel('catalog/category')->load( $categories[1]) )->getLevel()
and then check with your brand name category level, if match then display name.
e.g. suppose brand category level is 3
<?php if( $category = Mage::getModel('catalog/category')->load( $categories[1]) ): ?>
<?php if($category->getLevel() == 3)
echo $category->getName(); ?>
<?php endif ?>
<?php endif ?>
ANKIT's answer is good, but it could be improved by actually query-ing the specific levels instead of loading the whole collection and doing a conditional. Take for example if you want to get all categories in a specific level:
<ul>
<?php $categories = Mage::getModel('catalog/category')
->getCollection()
// magic is prepared here..
->addAttributeToSelect('*')
// then the magic happens here:
->addAttributeToFilter('level', array('eq'=>2))
->load();
foreach($categories as $category):
?>
<li>$category->getName()</li>
<?php endforeach; ?>
</ul>
<?php
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$product = $objectManager->get('Magento\Framework\Registry')->registry('current_product');
$categories = $product->getCategoryIds(); /*will return category ids array*/
foreach($categories as $category){
$cat = $objectManager->create('Magento\Catalog\Model\Category')->load($category);
if ($cat->getLevel() == 2) {
$catName = $cat->getName().","; ?>
<div class="brand_bg">
<label><?php /* #escapeNotVerified */ echo __('Category :') ?></label>
<?php echo $catName; ?>
</div>
<?php } ?>
<?php } ?>
?>

I need to get a list of sibling categories in magento 1.7

So far I think i am working at something like this
<?php
$parentId = $_category->getParentId();
$cats = Mage::getModel('catalog/category')->load($parentId)->getChildred();
$catIds = explode(',',$cats);
?>
<ul>
<?php foreach($catIds as $catId): ?>
<li>
<?php
$category=Mage::getModel('catalog/category')->load($catId)
echo $category->getName();
?>
</li>
<?php endforeach; ?>
</ul>
I am trying to have lateral movement in subcategories without having to go up a layer.
Let me know if that made sense.
The below code will helps you to load 2nd level (sub)category. you can set the $_rootCatId as dynamic also by Mage::app()->getStore()->getRootCategoryId();.
$_rootCatId = 2;//Root Category
$_rootCategory = Mage::getModel('catalog/category')->load($_rootCatId);
$_catName = $_rootCategory->getName();
if($_rootCategory->hasChildren())
{
$_collection = Mage::getResourceModel('catalog/category_collection')
->addAttributeToFilter('is_active', 1)
->addAttributeToSort('position', 'asc')
->joinUrlRewrite()
->addIdFilter($_rootCategory->getChildren())
->load();
foreach($_collection AS $_sub)
{
$_subCat = Mage::getModel('catalog/category')->load($_sub->getId());
if($_subCat->hasChildren())
{
echo '<li class="leve10 nav-'. $_subCat->getId() .'">';
echo '<a id="subCatLink">';
echo '<span>'. $this->htmlEscape($_subCat->getName()) .'</span>
</a>
</li>';
echo '<ul id="subCatUl" class="no-display" style="padding:0px 13px;">';
$__collection = Mage::getResourceModel('catalog/category_collection')
->addAttributeToFilter('is_active', 1)
->addAttributeToSort('position', 'asc')
->joinUrlRewrite()
->addIdFilter($_subCat->getChildren())
->load();
foreach($__collection AS $__sub)
{
$__subCat = Mage::getModel('catalog/category')->load($__sub->getId());
echo '<li class="leve20 nav-'. $__subCat->getId() .'">
<a href="'. $this->getCategoryUrl($__subCat) .'">
<span>'. $this->htmlEscape($__subCat->getName()) .'</span>
</a>
</li>';
}
echo '</ul>';
}
else
{
echo '<li class="leve10 nav-'. $_subCat->getId() .'">
<a href="'. $this->getCategoryUrl($_subCat) .'">
<span>'. $this->htmlEscape($_subCat->getName()) .'</span>
</a>
</li>';
}
}
}
else
echo 'No Categories Found...';
Assuming that your $_category is a valid instance of Mage_Catalog_Model_Category:
<?php $_siblings = $_category->getParentCategory()->getChildrenCategories(); ?>
<ul>
<?php foreach($_siblings as $_sibling): ?>
<li>
<?php echo $_sibling->getName(); ?>
</li>
<?php endforeach; ?>
</ul>

Displaying Specific Magento Categories From Category ID

As of yet, I haven't managed to find anything online that already caters for what I'm trying to achieve. I simply want to call in specific categories to a list but I want to be able to define which categories by ID, so for example, I would like to be able to call them in like something such as the below:-
{{block type="catalog/navigation" name="catalog.category" template="developer/extension/script.phtml" ids="3,6,17,143,57"}}
I'm already displaying a list of sub categories in various places based on the parent category ID but in instances where there are hundreds of sub categories, it isn't always practical to display all of them, so I'm wondering if the existing script can possibly be tweaked to only include specific categories as per above?
<?php
//gets all sub categories of parent category 'cat-id-4'
$cats = Mage::getModel('catalog/category')->load(4)->getChildren();
$catIds = explode(',',$cats);
$categories = array();
foreach($catIds as $catId) {
$category = Mage::getModel('catalog/category')->load($catId);
$categories[$category->getName()] = array(
'url' => $category->getUrl(),
'img' => $category->getImageUrl()
);
}
ksort($categories, SORT_STRING);
?>
<ul>
<?php if($category->getIsActive()): ?>
<?php foreach($categories as $name => $data): ?>
<li>
<?php echo $name; ?>
</li>
<?php endforeach; ?>
<?php endif; ?>
</ul>
If anyone could advise how I could possibly achieve this please, that would be fantastic - Thanks in advance.
This should work with your given CMS block code:
<?php
$catIds = explode(',', $this->getIds()); //<-- ONLY CHANGE MADE
$categories = array();
foreach($catIds as $catId) {
$category = Mage::getModel('catalog/category')->load($catId);
$categories[$category->getName()] = array(
'url' => $category->getUrl(),
'img' => $category->getImageUrl()
);
}
ksort($categories, SORT_STRING);
?>
<ul>
<?php if($category->getIsActive()): ?>
<?php foreach($categories as $name => $data): ?>
<li>
<?php echo $name; ?>
</li>
<?php endforeach; ?>
<?php endif; ?>
</ul>

Resources