Get rewritten product url in a different store

Copyright: zimmytws / 123RF Stock Photo

It was pointed out to me in one of the preceding articles that getting a product’s URL in a different store can get pretty complicated if the URL you want to get is rewritten. I decided to come up with a solution to that problem, as it could be useful in the future.

I came up with a method that returns a rewritten part (i.e. after rewrite) of a product’s URL. You’ll need to add base URL of a store to this return value to get a full URL (as shown on languages.phtml example).

Note that this is useful only if you have a scope of URL key attribute set to store view. This means that you could have different URL of a product in different stores – for example if you have a product with an URL key ‘nokia-blue‘ in english store view, and ‘nokia-blau‘ in german store view. This will work for rewrites that you when editing your product. If you decide to add URL rewrites yourself in ‘URL rewrite management’, you probably have a very good reason, but we won’t be covering that case.

I won’t be going through creating and registering a module this time.

Lets start by adding this method to your module’s helper.

app/code/community/Inchoo/Rewrites/Helper/Data.php

<?php
class Inchoo_Rewrites_Helper_Data extends Mage_Core_Helper_Abstract
{
    public function rewrittenProductUrl($productId, $categoryId, $storeId)
    {
        $coreUrl = Mage::getModel('core/url_rewrite');
        $idPath = sprintf('product/%d', $productId);
        if ($categoryId) {
            $idPath = sprintf('%s/%d', $idPath, $categoryId);
        }
        $coreUrl->setStoreId($storeId);
        $coreUrl->loadByIdPath($idPath);
 
        return $coreUrl->getRequestPath();
    }
}
?>

Now, we’ll do a little walk-through. As you can see, this method accepts $productId, $categoryId and $storeId as arguments. To understand how URLs look before they’re rewritten, let’s take a look at core_url_rewrite table in our database.

rewritten-product-url-example

A id_path of a product that’s not in any category appears in form of product/productId, and if it belongs to any of the categories, it’s appears as product/productId/categoryId.

Let’s get back to our method. We’ll recreate the structure of id_path using data we already have in Magento registry. Then, we need to setStoreId() to the model we’re using before we look for a rewrite. After that, we’ll use loadByIdPath() to load our rewritten URL row. All that’s left now is getting a request path, i.e. the rewritten part of a product’s URL. We’ll doing all that using Magento’s core/url_rewrite model.

One use case for this would be language (store) switcher that redirects you to the same product you’re looking at, but in different store. Just place the following code in your languages.phtml file.

app/design/base/default/template/page/html/switch/languages.phtml

<?php if(count($this->getStores())>1): ?>
    <?php
    $helper = Mage::helper('inchoo_rewrites');
    $prod = Mage::registry('current_product');
    $categ = Mage::registry('current_category');
    $categId = $categ ? $categ->getId() : null;
 
    ?>
    <div class="form-language">
        <label for="select-language"><?php echo $this->__('Your Language:') ?></label>
        <select id="select-language" title="<?php echo $this->__('Your Language') ?>" onchange="window.location.href=this.value">
            <?php foreach ($this->getStores() as $_lang): ?>
                <?php $_selected = ($_lang->getId() == $this->getCurrentStoreId()) ? ' selected="selected"' : '' ?>
                <option value="<?php
                    if($prod) {
                        echo $_lang->getBaseUrl() . $helper->rewrittenProductUrl($prod->getId(), $categId, $_lang->getId()) . '?___store=' . $_lang->getCode();
                    }else{
                        echo $_lang->getCurrentUrl(false);
                    }
                ?>"<?php echo $_selected ?>><?php echo $this->escapeHtml($_lang->getName()) ?></option>
            <?php endforeach; ?>
        </select>
    </div>
<?php endif; ?>

Your language switcher’s source code should look something like this (provided you have different URL set for your product in at least one store)
rewritten-product-url-example-2

Hope this will help some of you to master the concept of URL rewrites in multilingual stores.


9 comments

  1. Hi, You can do the same with the categories urls with this function into the helper:

        public function rewrittenCategoryUrl($categoryId, $storeId)
        {
            $coreUrl = Mage::getModel('core/url_rewrite');
            $idPath = sprintf('category/%d', $categoryId);
            $coreUrl->setStoreId($storeId);
            $coreUrl->loadByIdPath($idPath);
    
            return $coreUrl->getRequestPath();
        }

    and this on the flags.phtml template file:

    if($prod) {
                            echo $_lang->getBaseUrl() . $helper->rewrittenProductUrl($prod->getId(), $categId, $_lang->getId()) . '?___store=' . $_lang->getCode();
    else if($categ) {
                            echo $_lang->getBaseUrl() . $helper->rewrittenCategoryUrl($categId, $_lang->getId()) . '?___store=' . $_lang->getCode();
    
                        }else{
                            echo $_lang->getCurrentUrl(false);
                        }
  2. Hi Petar,

    Thank you for this article.
    What about when we are accessing a page that is not a product or a category? I.E. customer/account/create

  3. Petar, thanks for the clear instructions. I have used them on Magento 1.7.0.2, but the $prod and $categ variables are empty. Would you know what may cause that?

  4. Hi Peter, looks good! What about if we wanted to get a page that isn’t a product page, but is still within Magento (i.e. a category page)?

  5. @MagePsycho
    As far as I can see, in EE 1.3.0.2., enterprise_url_rewrite is not all that different from core_url_rewrite table.

    All you need to do is take the code above and replace loadByIdPath with loadByIdentifier (since the id_path column in CE has the same content as identifier column in EE).

    Also, be sure to use enterprise UrlRewrite module instead of Core Rewrite in your model calls.

  6. @MagePsycho
    I’ll take a look and get back to you. We needed this solution for a store based on CE we’re currently working on, so I’ll need to check databases on a EE installation.

    @Todor
    It’s a bit hard to understand, since cyrillic gets lost in the translation. What result do you get using the code written in the article?

    @Tomislav
    Because I totally overlooked that I wrote it in a different syntax, the code should look the way you wrote it. It’s fixed now, thanks 🙂

  7. Do you have the similar solution for Magento Enterprise Edition? As you know Magento EE doesn’t use the core_url_rewrite table but enterprise_url_rewrite* tables.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.