5

Hi using info from this site and around the web I have started to add hreflang tags to my magento store. They work and display as they should on the default (American)site, however on the alternate (Canadian)site it does not work, here is the code & how it displays.

<link rel="alternate" href="http://www.example.com<?php 
$urlString = Mage::helper('core/url')->getCurrentUrl();
$url = Mage::getSingleton('core/url')->parseUrl($urlString);
$path = $url->getPath();echo $path 
?>" hreflang="en-us" />
<link rel="alternate" href="http://www.example.com/ca<?php $urlString =
Mage::helper('core/url')->getCurrentUrl();                                                             
$url = Mage::getSingleton('core/url')->parseUrl($urlString);
$path = $url->getPath();echo $path ?>" hreflang="en-ca" />

which on the main site properly displays as (on a product page for example)

<link rel="alternate" href="http://www.example.com/sample-product.html" 
hreflang="en-us" />
<link rel="alternate" href="http://www.example.com/ca/sample-product.html" hreflang="en-ca" />

so far so good, however when you are on the Canadian ca site, it now displays as

<link rel="alternate" href="http://www.example.com/ca/sample-product.html" hreflang="en-us" />
<link rel="alternate" href="http://www.example.com/ca/ca/sample-product.html" hreflang="en-ca" />

as you can see there is an extra (/ca/) on each url. I'm not quite sure how to tackle this problem, I guess what I need is the code to output everything after the base url as opposed to the domain of each site. Any help that you could provide will be greatly appreciated! Thank you.

8 Answers 8

6

In my case, I wanted to do different hreflangs for each website. So to do just for the current one:

$website = Mage::app()->getWebsite()->getStores();
foreach ( $website as $store) {
    $lang = $store->getConfig('general/locale/code');
    echo '<link rel="alternate" href="' . $store->getCurrentUrl() . '" hreflang="' . $lang . '"/>' . "\n";
}

There is one more thing to point out, $lang = $store->getConfig('general/locale/code'); generates language tags like so: "en_GB". As Google states, that is incorrect, it should have been: "en-gb" (dash not underscore, small caps) or "en", depended on what you wan to achieve - link.

I use the code directly in templates, as it each of my website has its own template - it should go to app/design/frontend/yourPackage/yourTemplate/template/page/html/head.phtml

An example of replacing language tags as asked in comments - in most cases we only use "non targeted" language tags (two leter ISO codes):

$lang = $store->getConfig('general/locale/code');
    if (strtolower($lang) == 'en_us'){
        $lang = 'en'; //OR en-gb or any tag you need
    }
    echo '<link rel="alternate" href="' . $store->getCurrentUrl() . '" hreflang="' . $lang . '"/>' . "\n";
3
  • Thanks for this! However is it possible to modify the code to put out the correct language tags?
    – user4517
    Mar 4, 2014 at 17:11
  • Edited my answer appropriately.
    – navotjer
    Mar 11, 2014 at 17:12
  • 1
    if you are getting ?___from_store=XXX in the URLs, use $store->getCurrentUrl(false) to stop that
    – rwired
    Jul 23, 2014 at 14:53
8

You have to loop through your stores and get URL and locale for each:

foreach (Mage::app()->getWebsites() as $website) {
    foreach ($website->getGroups() as $group) {
        $stores = $group->getStores();
        foreach ($stores as $store) {
            echo '<link rel="alternate" href="' . $store->getCurrentUrl() . '" hreflang="' . $store->getConfig('general/locale/code') . '"/>' . "\n";
        }
    }
}
6
  • Thanks for the help, the code almost works perfectly. The only issue is that it adds session id's or the website store code after the urls (?SID=ojcoj808la....etc or ?__store=default&amp;____from_store=default") is there a way to strip those out? Thanks again.
    – user4517
    Dec 30, 2013 at 22:11
  • 1
    Just do preg_replace('/\?.*/', '', ...).
    – user487772
    Dec 31, 2013 at 0:07
  • Apologies, I am new to php and am not sure how to implement that code. Thank you for your help!
    – user4517
    Dec 31, 2013 at 17:17
  • 1
    For the non programmer replace in line 5: $store->getCurrentUrl() with preg_replace('/\?.*/', '', $store->getCurrentUrl()) @Tim thanks for the great answer!
    – BenRoe
    Apr 18, 2014 at 14:24
  • I was having problems with preg_replace and other string manipulations failing whenever BLOCK_HTML cache was turned on, even with a clean cache, refreshed etc. Not sure why exactly. I was able to get rid of ____from_store query strings by using $store->getCurrentUrl(false). Works with the caching enabled.
    – rwired
    Jul 23, 2014 at 14:57
1

If you have several websites selling different things and only want to include all storeviews of one website:

<?php
$groupId = Mage::app()->getStore()->getGroupId();
$collection = Mage::getModel('core/store')->getCollection()->addFieldToFilter('group_id', $groupId);
foreach ($collection as $store) {
        echo '<link rel="alternate" href="' . preg_replace('/\?.*/', '', $store->getCurrentUrl()) . '" hreflang="' . $store->getCode() . '"/>' . "\n";
        }
?>
0

This outputs urls like this for category and product details pages:

<link rel="alternate" hreflang="en" href="https://www.example.com/product-catagory.html"/>
<link rel="alternate" hreflang="es" href="https://www.example.com/es/categoria-de-producto.html"/>
<link rel="alternate" hreflang="x-default" href="https://www.example.com/product-catagory.html"/> 

and this:

<link rel="alternate" hreflang="en" href="https://www.example.com/product-catagory/product-detail-for-sale.html"/>
<link rel="alternate" hreflang="es" href="https://www.example.com/es/categoria-de-producto/detalles-del-producto-para-la-venta.html"/>
<link rel="alternate" hreflang="x-default" href="https://www.example.com/product-catagory/product-detail-for-sale.html"/>

Here's the code, I'm sure it could be better but it works just past it in your head.phtml template and change the number 1 in this code for your default store code. Oh yeah almost forgot it works in PHP 7 too.

<?php foreach (Mage::app()->getWebsites() as $website) {
    foreach ($website->getGroups() as $group) {
        $stores = $group->getStores();
        foreach ($stores as $store) {
            $storeId = $store->getId();
            $storeCode = substr(Mage::getStoreConfig('general/locale/code', $storeId),0,2);
            if (Mage::registry('product')) {
                $productId  = Mage::registry('product')->getId();
                $base_url = Mage::app()->getStore($storeId)->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK);
                $url = Mage::getModel('catalog/product')->setStoreId($storeId)->load($productId)->getProductUrl();
                $url = preg_replace('/\?.*/', '', $url); 
                echo '<link rel="alternate" hreflang="' . $storeCode . '" href="' . $url . '"/>';}
            elseif(Mage::registry('current_category')) { 
                $categoryId = Mage::registry('current_category')->getId();
                $base_url = Mage::app()->getStore($storeId)->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK);
                $url = Mage::getModel('catalog/category')->setStoreId($storeId)->load($categoryId)->getUrlPath();
                echo '<link rel="alternate" hreflang="' . $storeCode . '" href="' . $base_url . $url . '"/>' . "\n";
                }}}} 
?>
<?php 
            $storeId = 1;
            if (Mage::registry('product')) {
                $productId  = Mage::registry('product')->getId();
                $base_url = Mage::app()->getStore($storeId)->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK);
                $url = Mage::getModel('catalog/product')->setStoreId($storeId)->load($productId)->getProductUrl();
                $url = preg_replace('/\?.*/', '', $url); 
                echo '<link rel="alternate" hreflang="x-default" href="' . $url . '"/>';
}
            elseif(Mage::registry('current_category')) { 
                $categoryId = Mage::registry('current_category')->getId();
                $base_url = Mage::app()->getStore($storeId)->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK);
                $url = Mage::getModel('catalog/category')->setStoreId($storeId)->load($categoryId)->getUrlPath();
                echo '<link rel="alternate" hreflang="x-default" href="' . $base_url . $url . '"/>' . "\n";
            }
?>  
0

I have tried to couple above posted answers to get the right result, but in each instance the result is either not complete or it`s not giving me the result I need. I have been trying for days unsuccessfully.

This is what worked for me on the end... This way i think google is satisfied... If anybody can make the bellow code nicer it would be appreciated.

<?php
foreach (Mage::app()->getWebsites() as $website) {
    foreach ($website->getGroups() as $group) {
        $stores = $group->getStores();
        foreach ($stores as $store) {
               $lang = $store->getConfig('general/locale/code');

               //gets the store language and region in native xx_XX format
             if(Mage::getStoreConfig("web/alternatelinks/hreflang_value") == 'language') {

                        // Strips locale string down to th first 2 characters - matching the ISO 639-1 format
                        $lang = substr($lang, 0, 2);
                    } elseif(Mage::getStoreConfig("web/alternatelinks/hreflang_value") == 'language-region') {

                        // Replaces the native Magento '_' with a '-' to match the ISO 3166-1 Alpha 2 format
                        $lang = preg_replace("/[\s_]/", "-", $lang);
                    }

            echo '<link rel="alternate" hreflang="' . $lang . '" href="' . $store->getCurrentUrl(false) . '" />' . "\n";
        }
    }
}

                    ?>

<?php if(Mage::registry('current_product')): ?>
 <?php $product = Mage::registry('current_product'); ?>
  <link rel="alternate" hreflang="x-default" href="<?php 
    $newurl = $this->helper('core/url')->getCurrentUrl();
    $newurl = preg_replace('/\/(si|it|de|en)\//', '/si/', $this->helper('core/url')->getCurrentUrl());
    echo $newurl;
?>" />


  <?php elseif(Mage::registry('current_category')): ?>
    <link rel="alternate" hreflang="x-default" href="<?php 
    $newurl = $this->helper('core/url')->getCurrentUrl();
    $newurl = preg_replace('/\/(si|it|de|en)\//', '/si/', $this->helper('core/url')->getCurrentUrl());
    echo $newurl;
?>" />

<?php elseif((Mage::getSingleton('cms/page')->getIdentifier() == 'home' &&
 Mage::app()->getFrontController()->getRequest()->getRouteName() == 'cms')) : ?>
     <link rel="alternate" hreflang="x-default" href="<?php 
    $newurl = $this->helper('core/url')->getCurrentUrl();
    $newurl = preg_replace('/\/(si|it|de|en)\//', '/si/', $this->helper('core/url')->getCurrentUrl());
    echo $newurl;
?>" />
 <?php else: ?>
      <link rel="alternate" hreflang="x-default" href="<?php 
    $newurl = $this->helper('core/url')->getCurrentUrl();
    $newurl = preg_replace('/\/(si|it|de|en)\//', '/si/', $this->helper('core/url')->getCurrentUrl());
    echo $newurl;
?>" />


<?php endif; ?> 
0

The code works for me but the URLs contain also the category:

www.example.com/language_code/category/product.html

Is it possible to get only this:

www.example.com/language_code/product.html

Regards, Marcus

0

I had the same problem that there was an output of the category in the URL. That's not good for me because in the canonical URL the path is displayed without category. So referencing to 2 different URLs would only be confusing for google and waste our crawl budget.

I use getUrlPath instead of getProductUrl

This outputs the filename then I have to add the domain.tld in front Mage::getModel('catalog/product')->setStoreId($storeId)->load($productId)->getUrlPath()

0

Having the same issue as above; category path is included in the url for product page links. Would like to remove. Would anyone be so kind to modify the code I'm using from above to remove the product url category path? Thanks in advance!!

    <?php foreach (Mage::app()->getWebsites() as $website) {
foreach ($website->getGroups() as $group) {
    $stores = $group->getStores();
    foreach ($stores as $store) {
        $storeId = $store->getId();
        $storeCode = substr(Mage::getStoreConfig('general/locale/code', $storeId),0,2);
        if (Mage::registry('product')) {
            $productId  = Mage::registry('product')->getId();
            $base_url = Mage::app()->getStore($storeId)->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK);
            $url = Mage::getModel('catalog/product')->setStoreId($storeId)->load($productId)->getProductUrl();
            $url = preg_replace('/\?.*/', '', $url); 
            echo '<link rel="alternate" hreflang="' . $storeCode . '" href="' . $url . '"/>';}
        elseif(Mage::registry('current_category')) { 
            $categoryId = Mage::registry('current_category')->getId();
            $base_url = Mage::app()->getStore($storeId)->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK);
            $url = Mage::getModel('catalog/category')->setStoreId($storeId)->load($categoryId)->getUrlPath();
            echo '<link rel="alternate" hreflang="' . $storeCode . '" href="' . $base_url . $url . '"/>' . "\n";
            }}}} 

?>

getId(); $base_url = Mage::app()->getStore($storeId)->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK); $url = Mage::getModel('catalog/product')->setStoreId($storeId)->load($productId)->getProductUrl(); $url = preg_replace('/\?.*/', '', $url); echo ''; } elseif(Mage::registry('current_category')) { $categoryId = Mage::registry('current_category')->getId(); $base_url = Mage::app()->getStore($storeId)->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK); $url = Mage::getModel('catalog/category')->setStoreId($storeId)->load($categoryId)->getUrlPath(); echo '' . "\n"; } ?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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