Reputation: 235
I am trying to find a solution for making sure that Magento always shows the complete URL of every product including the category path. I want the complete url to also be there in search results also. For this i have put every product in only one category.
Can this be done by Url Rewrite custom through magento? Is 301 redirect using .htaccess, for /product.html to category/subcategory/product.html a good idea?
Thanks Moody
Upvotes: 0
Views: 14014
Reputation: 1704
What we do to get full category in products url is using a helper that'll try to get you a product URL with the category. You could also rewrite the product method but its kind of a pain whenever another module rewrites some product stuff, this is why we use the helper approach.
Here's our method:
public static function getFullUrl (Mage_Catalog_Model_Product $product ,
Mage_Catalog_Model_Category $category = null ,
$mustBeIncludedInNavigation = true ){
// Try to find url matching provided category
if( $category != null){
// Category is no match then we'll try to find some other category later
if( !in_array($product->getId() , $category->getProductCollection()->getAllIds() )
|| !self::isCategoryAcceptable($category , $mustBeIncludedInNavigation )){
$category = null;
}
}
if ($category == null) {
if( is_null($product->getCategoryIds() )){
return $product->getProductUrl();
}
$catCount = 0;
$productCategories = $product->getCategoryIds();
// Go through all product's categories
while( $catCount < count($productCategories) && $category == null ) {
$tmpCategory = Mage::getModel('catalog/category')->load($productCategories[$catCount]);
// See if category fits (active, url key, included in menu)
if ( !self::isCategoryAcceptable($tmpCategory , $mustBeIncludedInNavigation ) ) {
$catCount++;
}else{
$category = Mage::getModel('catalog/category')->load($productCategories[$catCount]);
}
}
}
$url = (!is_null( $product->getUrlPath($category))) ? Mage::getBaseUrl() . $product->getUrlPath($category) : $product->getProductUrl();
return $url;
}
/**
* Checks if a category matches criteria: active && url_key not null && included in menu if it has to
*/
protected static function isCategoryAcceptable(Mage_Catalog_Model_Category $category = null, $mustBeIncludedInNavigation = true){
if( !$category->getIsActive() || is_null( $category->getUrlKey() )
|| ( $mustBeIncludedInNavigation && !$category->getIncludeInMenu()) ){
return false;
}
return true;
}
If a category is specified it tries to get a url relative to this one.
If no category is specified or couldn't find a url with provided one, the method tries to get the product URL relative to the first category that the product is attached to, and checks if it's acceptable (active, with a url key and matching navigation criteria).
Finally if it falls back to original $product->getProductUrl()
Magento method.
You'll have to use it in templates (categories, cart products, recently viewed etc....) with this call :
echo $this->helper('yourcompany/yourmodule')::getFullProductUrl($_product);
Edit:
I took Zachary's remarks into account and tweaked it up a little by adding some checks and options. Hope it's cool now. Examples :
echo $this->helper('yourcompany/yourmodule')::getFullProductUrl($_product, $aCategory);
will try to find a product url in $aCategory then fall back to other category urls and finally product base url
echo $this->helper('yourcompany/yourmodule')::getFullProductUrl($_product, someCategory, false);
will also consider categories that are not included in navigation.
Upvotes: 4