Getting A Products URL

Updated . Posted . Visible to the public.

Potentially confusing due to the 3 methods you could use, all of which are in Mage_Catalog_Model_Product:

public function getUrlPath($category=null)
public function getUrlInStore($params = array())
public function getProductUrl($useSid = null)

The best way to explain is to simply show the results of several calls. Given a product whose URL key is mondrian-large-coffee-table-set-multicolour on the domain of http://made.local the results are:

$product->getUrlPath();
    'mondrian-large-coffee-table-set-multicolour'

$product->getUrlPath($category);
    'tables/mondrian-large-coffee-table-set-multicolour'

// you cannot stop this method adding ___store to the URL, even by setting _store_to_url to false
$product->getUrlInStore();
    'http://made.local/tables/mondrian-large-coffee-table-set-multicolour?___store=default'

// you cannot stop this method adding ___store to the URL, even by setting _store_to_url to false
// note - see the "using _ignore_category" section below for an arguable bug with using this param
$product->getUrlInStore(array('_ignore_category' => true));
    'http://made.local/mondrian-large-coffee-table-set-multicolour?___store=default'

$product->getProductUrl();
    'http://made.local/tables/mondrian-large-coffee-table-set-multicolour'

$product->getProductUrl(true);
    'http://made.local/tables/mondrian-large-coffee-table-set-multicolour'

To see what other params can be passed to getUrlInStore(), see URL Route Parameters.

Using _ignore_category

The short version - I would not use this param, and instead use Mage::getUrl($product->getUrlPath())

If you first fetch a products URL which includes the category, and then use the same product instance to attempt to fetch a non-category URL, you will instead both times get a URL which contains the category, see the below code:

$product = Mage::getModel('catalog/product');

$product->getUrlInStore();
    'http://made.local/sofas/jonah-2-seater-sofa-berry-red?___store=default'

$product->getUrlInStore(array('_ignore_category' => true));
    'http://made.local/sofas/jonah-2-seater-sofa-berry-red?___store=default'

$product = Mage::getModel('catalog/product');

$product->getUrlInStore(array('_ignore_category' => true));
    'http://made.local/jonah-2-seater-sofa-berry-red?___store=default'

The issue lies with the request_path key on the $product model, which the
Mage_Catalog_Model_Product_Url::getUrl() sets, to act as a cached value for
an otherwise intensive process of resolving a URL rewrite to a product within
a category.

To resolve this, unset request_path first, as below:

$product->unsRequestPath();
$product->getUrlInStore(array('_ignore_category' => true));
    'http://made.local/jonah-2-seater-sofa-berry-red?___store=default'

Note that any method listed at the top of this card which causes the category to be present in the returned URL will have the same effect of caching the category.

Mike Whitby
Last edit
Posted by Mike Whitby to Magento (2012-05-09 16:30)