3

I want Magento to always generate product urls in the format:

www.example.com/catalog/product/view/id/123/s/product-name.html

instead of the rewritten

www.example.com/product-name.html

The reason for this is mainly so that I don't have to worry if something happens to all my rewrites, or so I can feel free to truncate and rebuild core_url_rewrite if something goes wrong and it gets too big.

I don't want to stop using rewritten urls entirely. I like them for categories. I have fewer categories, and I very rarely change the names. I hate feeling like I can't change the name of a product because it will make the core_url_rewrite table grow and mess up any backlinks I've generated if I lose my rewrites. Also, I still want my current urls to work for as long as possible along with the /product/view/id urls.

Is there an easy way to do this without rewriting methods that I'm missing?

Or do I have to override some getProductUrl method? It looks like the answer lies in the getProductUrl() method in Mage_Catalog_Model_Product? That class seems to use the getProductUrl() method in Mage_Catalog_Model_Product_Url.

But again, if there's some simple configuration setting that would do the trick, I'd rather do that.

Edit: I haven't had a chance to dig through this yet, but on a related matter while working on something else, I accidentally found that there is something called getCategoryIdUrl() that does for categories what I want to done for products. I searched for the obvious getProductIdUrl and came up with nothing.

Edit:

The accepted answer given by fschmengler works really well and answers the question. But it turns out that the urls for the sitemap aren't generated with the getProductUrl() method. The sitemap is made in Mage_Sitemap_Model_Sitemap by the generateXml() method.

/**
 * Generate categories sitemap
 */
$changefreq = (string)Mage::getStoreConfig('sitemap/category/changefreq', $storeId);
$priority   = (string)Mage::getStoreConfig('sitemap/category/priority', $storeId);
$collection = Mage::getResourceModel('sitemap/catalog_category')->getCollection($storeId);
foreach ($collection as $item) {
    $xml = sprintf(
        '<url><loc>%s</loc><lastmod>%s</lastmod><changefreq>%s</changefreq><priority>%.1f</priority></url>',
        htmlspecialchars($baseUrl . $item->getUrl()),
        $date,
        $changefreq,
        $priority
    );
    $io->streamWrite($xml);
}
unset($collection);

I overrode it with something like this:

/**
 * Generate products sitemap
 */
$changefreq = (string)Mage::getStoreConfig('sitemap/product/changefreq', $storeId);
$priority   = (string)Mage::getStoreConfig('sitemap/product/priority', $storeId);
//$collection = Mage::getResourceModel('sitemap/catalog_product')->getCollection($storeId);

$rootCatId = Mage::app()->getStore($storeId)->getRootCategoryId();
$product_collection = Mage::getModel('catalog/category')->load($rootCatId)->getProductCollection()->setStoreId($storeId);
//Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($product_collection);
$product_collection->addFieldToFilter('visibility', Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH)
->addAttributeToFilter('status',Mage_Catalog_Model_Product_Status::STATUS_ENABLED)
->addAttributeToSelect('url_key')
;

foreach ($product_collection as $item) {
    $url = $baseUrl.'catalog/product/view/id/'.$item->getId().'/s/'.$item->getData('url_key').'/';
    $xml = sprintf(
        '<url><loc>%s</loc><lastmod>%s</lastmod><changefreq>%s</changefreq><priority>%.1f</priority></url>',
        htmlspecialchars($url),
        $date,
        $changefreq,
        $priority
    );
    $io->streamWrite($xml);
}

//unset($collection);

It's not the most elegant solution, but it seems to work so far.

  • You may have already asked yourself this, but how often are you changing products and how many products do you have? – Jerry Lopez Mar 6 '16 at 5:41
  • ~20,000 skus and adding products all the time. – The Phil Lee Mar 7 '16 at 3:49
2

You have to rewrite the product URL model.

This is the relevant method in Mage_Catalog_Model_Product_Url

protected function _getProductUrl($product, $requestPath, $routeParams)
{
    if (!empty($requestPath)) {
        return $this->getUrlInstance()->getDirectUrl($requestPath, $routeParams);
    }
    $routeParams['id'] = $product->getId();
    $routeParams['s'] = $product->getUrlKey();
    $categoryId = $this->_getCategoryIdForUrl($product, $routeParams);
    if ($categoryId) {
        $routeParams['category'] = $categoryId;
    }
    return $this->getUrlInstance()->getUrl('catalog/product/view', $routeParams);
}

$requestPath is the path from the URL rewrite - you see that if a rewrite is found, this is used directly as URL, if not, the catalog/product/view URL is used.

Remove the first part to always get non-rewritten URLs:

//if (!empty($requestPath)) {
//    return $this->getUrlInstance()->getDirectUrl($requestPath, $routeParams);
//}
  • My products url like www.example.com/catalog/product/view/id/123/s/product-name.html how to change like www.example.com/name.html @Fabian Schmengler – zus Sep 13 at 9:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.