https://www.blueclaw.co.uk/blog/2013/08/12/fix-category-url-filter-in-magento-layered-navigation/


Arguably one of the best features of Magento from a usability perspective is its powerful layered navigation system, which allows the customer to filter down the products presented to them from a category, enabling them to find the best products specific to their needs.



A major downside to this filtering is in the URLs generated. Magento will append a query string containing filter parameters to the current category URL, resulting in rather unhelpful (not to mention non-SEO friendly) URLs such as www.yoursite.com/electronics.html?manufacturer=120.



Under normal circumstances, and for attributes such as “price” or “manufacturer”, this isn’t such a major issue. However, when it comes to the category filter it can present rather a large problem. To access, for example, the “Camera” category in the sample Magento installation, you could visit either of:



www.yoursite.com/electronics/cameras.html

www.yoursite.com/electronics.html?cat=12

Obviously the latter here is an issue both for SEO (duplicate URL for the same content) and also for usability. By default, the title and description would still be that of the parent category (in this instance “Electronics”) which could cause confusion to the user.



This can be fixed quite easily by overriding the getUrl() method in theMage_Catalog_Model_Layer_Filter_Item class (Accessible at:/app/code/core/Mage/Catalog/Model/Layer/Filter/Item.php)



As a developer who adheres to Magento best practices, I’d never recommend directly editing the core Magento code pool; so either create a local copy of this file in the “local” code pool, or create your own Magento extension which rewrites the model.




The code

Right, down to the fun part! Locate the function at line 57, it should look like this:



public function getUrl()
{
$query = array(
$this->getFilter()->getRequestVar()=>$this->getValue(),
Mage::getBlockSingleton('page/html_pager')->getPageVarName() => null // exclude current page from urls
);
return Mage::getUrl('*/*/*', array('_current'=>true, '_use_rewrite'=>true, '_query'=>$query));
}

Now you need to edit this code and put in a condition to check for the presence of the category filter (“cat” request variable). With this we first load the category object using its ID, and then retrieve the correct category URL.



The next section below (lines 7-12) checks if the current request includes any other query string parameters, and builds a new query string accordingly.



Finally, this query string is added to the category URL and returned.



public function getUrl()
{
if($this->getFilter()->getRequestVar() == "cat"){
$category_url = Mage::getModel('catalog/category')->load($this->getValue())->getUrl();
$return = $category_url;
$request = Mage::getUrl('*/*/*', array('_current'=>true, '_use_rewrite'=>true));
if(strpos($request,'?') !== false ){
$query_string = substr($request,strpos($request,'?'));
}
else{
$query_string = '';
}
if(!empty($query_string)){
$return .= $query_string;
}
return $return;
}
else{
$query = array(
$this->getFilter()->getRequestVar()=>$this->getValue(),
Mage::getBlockSingleton('page/html_pager')->getPageVarName() => null // exclude current page from urls
);

return Mage::getUrl('*/*/*', array('_current'=>true, '_use_rewrite'=>true, '_query'=>$query));
}
}

A nice quick but effective fix which will help improve your SEO and user experience.



If you are looking for more advanced features for improving your Magento SEO and layered navigation, our Blueclaw SEO for Magento Extension deals with this and many further issues.