Magento2 Catgory Filter - filter

How can I filter Magento2 multiple category ?
<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd"><listingToolbar name="listing_top">
<filters name="listing_filters">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="templates" xsi:type="array">
<item name="filters" xsi:type="array">
<item name="select" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/form/element/ui-select</item>
<item name="template" xsi:type="string">ui/grid/filters/elements/ui-select</item>
</item>
</item>
</item>
</item>
</argument>
</filters>
Please Help me how can I add category filter

Recently I got a chance to rewrite Magento’s layered navigation standard functionality. The request was very specific as the client wanted to keep all of the “filters” visible all the time. For example if you wish to filter your results by Color (let’s say you have yellow, green, red, blue and magenta) products are filtered but the layered navigation displays all filters. This way a costumer can re-filter the products in current category without needing to return to the category's view.
Files that are used for layered navigation are situated in app /design/frontend/base/default/template/catalog/layer/ folder. File used for layered navigation is view.phtml – it shows us all of the filters when we click on a category. File used for active state is state.phtml – when we click on one of the filters it is responsible for the results – so we’re gonna edit this one. So copy the state.phtml from base to your package or theme.
This is the original code in state.phtml:
<?php $_filters = $this->getActiveFilters() ?>
<?php if(!empty($_filters)): ?>
<div class="currently">
<p class="block-subtitle"><?php echo $this->__('Currently Shopping by:') ?></p>
<ol>
<?php foreach ($_filters as $_filter): ?>
<li>
<?php echo $this->__('Remove This Item') ?>
<span class="label"><?php echo $this->__($_filter->getName()) ?>:</span> <?php echo $this->stripTags($_filter->getLabel()) ?>
</li>
<?php endforeach; ?>
</ol>
<div class="actions"><?php echo $this->__('Clear All') ?></div>
</div>
<?php endif; ?>
Since we’re going to need url path of current category add this code before “currently” div block
<?php $obj = new Mage_Catalog_Block_Navigation(); ?>
<?php $_current_category=$obj->getCurrentCategory()->getUrlPath(); ?> //getting url path of current category
<?php $subs = $obj->getCurrentCategory()->getAllChildren(true); ?> //getting ids of subcategories of current category
Now we’re going to edit “currently” div, I renamed my to state, since it doesn’t show just current filter state anymore. Experienced Magento developers will notice that not all of the code is programmed Magento-way, but when I programmed it (Magento CE 1.4.2. ) Magento still didn’t have needed functions. I guess they didn’t expect from someone to use layered navigation this way. So, here we go!
<?php if(!empty($_filters)): ?>
<div class="state">
<p class="block-subtitle"><?php echo $this->__('Currently Shopping by:') ?></p>
<dl>
<?php foreach ($_filters as $_filter): ?>
<dd>
<ol>
<?php $attributemodel=$_filter->filter->_data["attribute_model"]; ?> // getting attribute model that has all filter options in it from currently active filter
<?php $attroptions=$attributemodel->getSource()->getAllOptions();?> // getting attribute options (filters) from attribute model
<?php $_categ= Mage::getModel('catalog/category');?> // object containing all categories and their information
<?php foreach($subs as $cat_id): ?>
<?php $_categ->load($cat_id)?> //get the subcategory you need
<?php $collection = $_categ->getProductCollection(); ?> //get the product collection (object containing all product information)
<?php $collection->addAttributeToSelect('color')?> // get the desired attribute
<?php endforeach; ?>
The next thing that needs to be done is to extract the information from attribute model and assemble links. Each of attribute options ($attroptions) contains attribute value (id) and attribute label.
<?php foreach($attroptions as $attr): ?> // get value and label of each attribute
<?php $count=0; ?>
<?php if($attr["value"]!=""): ?>
<?php $val=$attr["value"] ?>
<?php $collection->addFieldToFilter(array(array('attribute'=>'themes','gt'=>10)))?> // collection of attribute values and labels for all values
//greater then 10 (in this case attribute values range was 18-39)
<?php $proddata=$collection->getData() ?> // get product data for all attribute values
<?php if($attr["label"]!= $this->stripTags($_filter->getLabel())): ?> // make a nice looking label
<?php foreach($proddata as $prod):?>
<?php if($prod["type_id"]=="configurable"): ?> // in this store all products were configurable
<?php $split=split(",", $prod["color"]);?> // get the attribute values that correspond with one product (a product may have more
// then one attribute value and they're separated by commas that's why we split the string with "," as deliminator)
Even thought you set your attribute to Filterable(with results) you still have to count the products in order to output only attribute values that have product count >0.
<?php foreach($split as $color): ?> //check out how many products have the same attribute value
<?php if($color==$attr["value"]): ?>
<?php $count++;?>
<?php endif; ?>
<?php endforeach; ?>
<?php endif;?>
<?php endforeach; ?>
<?php if($count>0):?> // check if any product has that attribute value
<li><a href="<?php echo $this->getUrl('').$_current_category ?>?color=<?php echo $attr["value"]?>" ><?php echo $attr["label"]; ?></a></li> // if not currently active filter make a link
<?php endif; ?>
<?php else:?>
<li class="current"> <?php echo $this->stripTags($_filter->getLabel()); ?></li> // if currently active filter write out the label
<?php endif;?>
<?php endif; ?>
<?php endforeach; ?>
<?php endforeach; ?> // ending the first for loop (foreach($filters as $filter))
</ol>
</dd>
</dl>
<a class="all" style="float:right;" href="<?php echo $this->getClearUrl()?>">All</a> // show all products, return from current state back to category view
</div>
<?php endif; ?>
And that’s it. Our task of keeping the filters visible all the time is finished 🙂 . Now where ever you go using layered navigation you’ll be able to simply re-filter the products in current category without the need to go back to category view. And for the end a brief warning – some code here isn’t programmed Magento-way, because needed functions weren’t available. I hope I explained the problem and solution well enough :).
Cheers!

Related

Magento: How to show custom attribute on product page below description

I have a custom attribute for products in which I add a video URL.
I made this Embed video responsive using css.
Now I want to call the custom attribute on the product page, so it shows the video.
The file responsible for this is: description.phtml
I've tried the following:
?>
<?php $_description = $this->getProduct()->getDescription(); ?>
<?php if ($_description): ?>
<h2><?php echo $this->__('Details') ?></h2>
<div class="std">
<?php echo $this->helper('catalog/output')->productAttribute($this->getProduct(), $_description, 'description') ?>
</div>
<div class="std">
<?php echo $_product->getAttributeText('video') ?>
</div>
<?php endif; ?>
But I get the error:
Fatal error: Call to a member function getAttributeText() on a non-object in /data/web/public/app/design/frontend/base/default/template/catalog/product/view/description.phtml on line 40
The video does show however. I'm probably doing this all wrong. Can I fix this with a simple edit of the code, or do I have to use an entirely different approach?
Thanks.
<?php echo $this->getProduct()->getAttributeText('video'); ?>
Try this. Or on top of document add this
<?php $_product = $this->getProduct(); ?>

Magento: textbox instead of multi select in layered navigation

Is there a possibility in Magento to have a multi-select attribute, for which I would use a textbox in layered navigation instead of showing all items from multi-select?
I have an attribute where I will have hundreds of options and need to use it in layered navigation.
When customer uses invalid value, an error should show up.
Edit: After the help from FlorinelChis I have folowing code in filter.phtml:
<ol>
<?php foreach ($this->getItems() as $_item): ?>
<?php
$attributeModel = $this->getAttributeModel();
$attribute_code = $attributeModel->getAttributeCode();
?>
<li>
<?php if ($attribute_code != 'available_zip'): ?>
<?php if ($_item->getCount() > 0): ?>
<?php echo $_item->getLabel() ?>
<?php else: echo $_item->getLabel() ?>
<?php endif; ?>
<?php if ($this->shouldDisplayProductCount()): ?>
(<?php echo $_item->getCount() ?>)
<?php endif; ?>
<?php endif; ?>
</li>
<?php endforeach ?>
</ol>
<?php
if ($attribute_code == 'available_zip'):
$cat = Mage::registry('current_category')->getUrlPath() ;
$url = Mage::getBaseUrl();
/*$sendUrl = $this->urlEscape($_item->getUrl()).'+'.$url.$cat.'?'.$attribute_code.'='.$_item->getValue();*/
echo '<form action="" method="get">';
echo '<input type="text" size="5" maxlength="5" name="'.$attribute_code.'" />';
echo '<button type="submit">OK</button>';
echo '</form>';
endif; ?>
I have one more thing now:
how to send the form with attribute id instead of value?
First, let's find out how Magento displays the filters in left hand navigation
1) Enable Template Path Hints:
and here is the result:
2) Let's take a look at app/design/frontend/base/default/template/catalog/layer/filter.phtml (you should copy this file in your theme folder structure)
3) The block ($this in the template file is an instance of Mage_Catalog_Block_Layer_Filter_Attribute which extends Mage_Catalog_Block_Layer_Filter_Abstract)
4) You can see that in Mage_Catalog_Block_Layer_Filter_Abstract a getName() method exists, so you could rely on this function to identify when you attribute is displayed. Don't! The label can change and your code won't be useful any more.
Back to our template file, you can get the attribute_code (which is reliable)
//$this is instance of Mage_Catalog_Block_Layer_Filter_Attribute
$attributeModel = $this->getAttributeModel();
$attribute_code = $attributeModel->getAttributeCode();
5) On your template you can have a check based on attribute code, so you display either the standard list or your custom html code with a textarea instead of a huge list.

Magento product custom options to be positioned below the price

I would like my Magento product custom options to be positioned below the price. I tried moving the blocks in catalog.xml file but nothing worked.
I did flush all cache every time.
This can be done from within the manage product section in admin. Under design, set "Display Product Options In" > "Product Info Column"
This function can be found in
/app/design/frontend/your_package/your_theme/template/catalog/product/view.phtml
or, if it's not there, look in
/app/design/frontend/your_package/default/template/catalog/product/view.phtml
If the file is not present, then create it by copying from
/app/design/frontend/base/default/template/catalog/product/view.phtml
or, if you are on the Enterprise Edition, from:
/app/design/frontend/enterprise/default/template/catalog/product/view.phtml
Remember not to touch anything in the /app/design/frontend/enterprise/default/
The code responsible for showing prices is:
<?php echo $this->getChildHtml('tierprices') ?>
You have to move the code responsible for showing the options, that looks like this:
<?php if (!$this->hasOptions()):?>
<div class="add-to-box">
<?php if($_product->isSaleable()): ?>
<?php echo $this->getChildHtml('addtocart') ?>
<?php endif; ?>
<?php echo $this->getChildHtml('addto') ?>
</div>
<?php else:?>
<?php if ($_product->isSaleable() && $this->hasOptions() && $this->getChildChildHtml('container1') ):?>
<div class="options-container-small">
<?php echo $this->getChildChildHtml('container1', '', true, true) ?>
</div>
<?php else: ?>
<?php echo $this->getChildHtml('addto') ?>
<?php endif;?>
<?php endif; ?>
directly below the code that's responsible for prices. Remember that the code above is an example, it may look different in your template, so don't copy-paste it.
Anyway, the file responsible for showing prices is usually /app/design/frontend/your_package/your_theme/template/catalog/product/view/tierprices.phtml (with the same fallbacks as usual), but you shouldn't modify it in your case.
You can change them by edit template (.phtml) file:
app/design/frontend/{default}/{default}/catalog/product/view.phtml
Modify the template Or ovverride it in your theme !
/app/design/frontend/base/default/template/catalog/product/view.phtml
This is where the price is :
<?php echo $this->getTierPriceHtml() ?>
This means customer options showing between this if (){}
<?php if (!$this->hasOptions()):?>
So you can move them as you like in the template file ! or you can style them with CSS to put them at custom position !

Magento: display multi-selection as a list with unique ID' s so list item can be changed to an image using CSS

I figured out how to display my custom multiselection attributie as a list but havent been able to figure out how to add an ID or class to every list item. This would allow me to display an image using CSS instead of text.
Hope you guys can help me. By the way, this is the code I use to display my custom attribute "rating" as a list:
<?php if($_product->getResource()->getAttribute('rating')->getFrontend()->getValue($_product)): ?>
<ul><li><?php
$_comma = ",";
$_list = "</li><li>";
echo str_replace($_comma,$_list,$_product->getResource()->getAttribute('rating')->getFrontend()->getValue($_product)) ?>
</li></ul>
<?php endif; ?>
</div>
Without knowing the exact format of the return of your function, I can't be 100% sure, but I think this would do the trick:
<div>
<?php if($_product->getResource()->getAttribute('rating')->getFrontend()->getValue($_product)):?>
<ul>
<?php $i=0?>
<?php foreach(explode(',', $_product->getResource()->getAttribute('rating')->getFrontend()->getValue($_product)) as $value) : ?>
<li id="value_<?php echo $i?>"><?php echo $value ?></li>
<?php $i++ ?>
<?php endforeach ?>
</ul>
<?php endif; ?>
</div>
It would probably be a little easier to just modify your return to give you back an array, but if the return is a comma separated list and not easy to change, then explode should do the trick.

Magento - Display Attribute Admin Title

How do I modify the following code block so that it will display ‘Plant Genus’ instead of the text ‘[hide]’
The relevant code is at:
\app\design\frontend\enterprise\style\template\catalog\layer\view.phtml
<?php $_filters = $this->getFilters() ?>
<?php foreach ($_filters as $_filter): ?>
<?php if($_filter->getItemsCount()): ?>
<dt><?php echo $this->__($_filter->getName()) ?></dt>
<dd><?php echo $_filter->getHtml() ?></dd>
<?php endif; ?>
<?php endforeach; ?>
Here is the attribute from the admin panel:
#Lucasnus - I dont think this is in the front end, but he has placed the attribute for us to see in a screen shot, the code he quoted is from the front end view.
However I think you are quite close to a solution, since this looks like a store attribute visibility issue.
In the admin panel if you change to the "Garden Store" scope, can you try to then change the attribute value to "Plant Genus" ?
If that does not work, maybe try the Main Website scope.
Do you have this problem with other products attributes?

Resources