Whenever I search a product using the search box, on the left side there is a filter by category. The code that creates this filter is this one:
<dl id="narrow-by-list">
<?php $_filters = $this->getFilters() ?>
<?php foreach ($_filters as $_filter): ?>
<?php if($_filter->getItemsCount()): ?>
<?php if($_filter->getName() != "Category"){ ?>
<dt><?php echo $this->__($_filter->getName()) ?></dt>
<dd>
<?php echo $_filter->getHtml() ?>
</dd>
<?php } endif; ?>
<?php endforeach; ?>
</dl>
This shows only the main category in the filter, and I'd like to show its subcategories. I tried to set another category programmatically with this code:
<?php
$layer = Mage::getSingleton('catalog/layer');
$_categ = Mage::getModel('catalog/category')->load(5);
$layer->setCurrentCategory($_categ);
?>
... but nothing changed. Any thoughts?
When you try to set the other category on the layer singleton from a template, it's too late as all the treatments were already applied.
What you can do is to copy the file app/code/core/Mage/CatalogSearch/Model/Layer.php into app/code/local/Mage/CatalogSearch/Model/ and to add a modified version of the base Mage_Catalog_Model_Layer::getCurrentCategory() method, looking like this :
public function getCurrentCategory()
{
$category = $this->getData('current_category');
if (is_null($category)) {
if ($category = Mage::registry('current_category')) {
$this->setData('current_category', $category);
}
else {
$category = Mage::getModel('catalog/category')->load(5); // Put here the ID of the category you want to use as basis for category filtering
$this->setData('current_category', $category);
}
}
return $category;
}
Related
Display custom options on product category page and also change the price according to options change. So user can easily select option from category page and addtocart.
Put the code in category page in product collection
<?php
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customOptions = $objectManager->get('Magento\Catalog\Model\Product\Option')->getProductOptionCollection($_product); ?>
<?php
foreach($customOptions as $option) {
$values = $option->getValues();
if (empty($values)) {
continue;
}
?>
<div class="cusome-option">
<?php foreach($values as $value) : ?>
<span><?php echo $value->getTitle(); ?></span>
<?php endforeach; ?>
</div>
<?php } ?>
custome option willl show on dropdown , select , multiselect , etc...
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; ?>
I'm having some troubles figuring out how to change the order of the totals in the transactional email templates (In Magento).
Basicly I want the 'Tax' row to be at the very bottom - below 'Grand total incl. tax'.
I know that this is the code, that prints the rows. But I can't seem to figure out how to change the order of the rows.
<?php foreach ($this->getTotals() as $_code => $_total): ?>
<?php if ($_total->getBlockName()): ?>
<?php echo $this->getChildHtml($_total->getBlockName(), false); ?>
<?php else:?>
<tr class="<?php echo $_code?>">
<td <?php echo $this->getLabelProperties()?>>
<?php if ($_total->getStrong()):?>
<?php echo $this->escapeHtml($_total->getLabel());?>
<?php else:?>
<?php echo $this->escapeHtml($_total->getLabel());?>
<?php endif?>
</td>
<td <?php echo $this->getValueProperties()?>>
<?php if ($_total->getStrong()):?>
<?php echo $this->formatValue($_total) ?>
<?php else:?>
<?php echo $this->formatValue($_total) ?>
<?php endif?>
</td>
</tr>
<?php endif?>
Could anyone be of help with this problem?
Thanks and have a wonderful day!
Method 1: Modifying the theme template file.
Copy app/design/frontend/base/sales/order/totals.phtml to your theme file and open it.
Add the following to the top of it.
if($tax = $this->getTotal('tax'))
{
$this->removeTotal('tax');
$this->addTotal($tax, 'grand_total');
}
This code will remove the tax from the totals list, then re-add it below the Grand Total. You should move the totals.phtml file into your custom theme folder so upgrades won't override it.
Method 2: Overriding the core block file.
You can do the same patch by overriding the core Totals block by doing the following:
Copy app/code/core/Mage/Sales/Block/Order/Totals.php to app/code/local/Mage/Sales/Block/Order/Totals.php
Open app/code/local/Mage/Sales/Block/Order/Totals.php and change the getTotals() function to the following:
public function getTotals($area=null)
{
//Move tax below grand_total
if($tax = $this->getTotal('tax'))
{
$this->removeTotal('tax');
$this->addTotal($tax, 'grand_total');
}
$totals = array();
if ($area === null) {
$totals = $this->_totals;
} else {
$area = (string)$area;
foreach ($this->_totals as $total) {
$totalArea = (string) $total->getArea();
if ($totalArea == $area) {
$totals[] = $total;
}
}
}
return $totals;
}
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 } ?>
?>
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>