
Add Google Rich Snippets to your Prestashop store
Adding Google Rich Snippets to your Prestashop store can definitely enhance your visibility in the SERP, and substantially increase your traffic over time. Want to stand out from the crowd? Read on.
- Version Used: Prestashop 1.5.2
Google Rich Snippets: an Introduction
Since this article is about how to integrate Google Rich Snippets into Prestashop, I will not dive deep into what they are or how they are structured, but in case you don’t have even the vaguest idea on what Rich Snippets are, take a look a the following picture:
See that nifty image in Google’s search results? See the reviews, and the info about the author? That result sure looks better than others, and stands out from the crowd. That’s what Rich Snippets are: richer content about the page linked in the search results. It can display all sort of stuff, increasing over time. At the moment, it’s images, song titles and duration, reviews, author bio and a couple of other things I’ll leave to you to uncover, here: More information about Google Rich Snippets
Adding Google Rich Snippets to Prestashop
Now that you know what Rich Snippets are, can you see their power? Think of your products, and think of how attractive they are in the search results at the moment: you might have added a nifty Meta title, and an intriguing Meta Description. But that’s all there is to it, isn’t it? It’s like many other results. Now think on what they can be with rich snippets! Let’s get started.
First things first: Google only accepts rich snippets for pages which have a single product (for some reason I still have to discover, I didn’t know it before they directly contacted me about my own product list: “Product markup on listing pages is not supported”). Thus, we will be adding them for the product.tpl file only. Then, since you’re probably selling different products than the demo ones, I’ll try to keep it as generic as possible. Feel free to reference yourself at the official Schema for more infomation abouut the type of products you’re selling.
PLEASE NOTE that the syntax highlighter plugin automatically adds ‘=””‘ to the itemscope property. Whenever you find it, just add ‘itemscope’ without the empty value!
Author information
Even though the Product item type actually supports images, they’re not supported by the search results page in Google. Thus, to overcome this, it’s possible to show the author’s logo for each result, provided that you have a Google plus page to link. Open up the header.tpl file of your theme, and add the following snippet inside the <head> tag:
<link rel="author" href="https://plus.google.com/118067945609961636215/posts">
Of course, you will have to use your own Google plus profile for the href property.
The overall container
Open up product.tpl, located in your theme’s folder. regardless of the template you use, you should be able to locate the following code:
<div id="primary_block" class="clearfix">
It may have other stuff attached, depending on the theme you use. If you can’t find it, be sure to locate the product data main container within the file. Now, let’s tell Google that we are dealing with a product. Add the following code to that div.
<div id="primary_block" class="clearfix" itemscope itemtype="http://schema.org/Product">
Adding the product name, image and description
Now, Google knows that everything we put inside that block will be related to that single product. But still, it needs a name, right? Locate the product name. You can find it at about line 222 in the default template for prestashop 1.5.2. In any case, it should be wrapped in an h1 tag, like this:
<h1>{$product->name|escape:'htmlall':'UTF-8'}</h1>
Wrap the name is a span tag the following way:
<h1><span itemprop="name">{$product->name|escape:'htmlall':'UTF-8'}</span></h1>
Right after the product name, if you’re using the default template, you will notice the “short description” block. I suggest you use that for the snippets description: locate <div id=”short_description_content” class=”rte align_justify”>{$product->description_short}</div><, and add itemprop=”description”
<div id="short_description_content" class="rte align_justify" itemprop="description">{$product->description_short}</div>
Ok, our product has a name and description now. Let’s give our snippets some taste by adding the product image! This might a bit tricky for the non savvy: locate <div id=”image-block”>, at about line 176 in the default product.tpl. It should look like this:
<div id="image-block"> {if $have_image} <span id="view_full_size"> <img src="{$link->getImageLink($product->link_rewrite, $cover.id_image, 'large_default')}" {if $jqZoomEnabled}class="jqzoom" alt="{$link->getImageLink($product->link_rewrite, $cover.id_image, 'thickbox_default')}"{else} title="{$product->name|escape:'htmlall':'UTF-8'}" alt="{$product->name|escape:'htmlall':'UTF-8'}" {/if} id="bigpic" width="{$largeSize.width}" height="{$largeSize.height}" /> <span class="span_link">{l s='View full size'}</span> </span> {else} <span id="view_full_size"> <img src="{$img_prod_dir}{$lang_iso}-default-large_default.jpg" id="bigpic" alt="" title="{$product->name|escape:'htmlall':'UTF-8'}" width="{$largeSize.width}" height="{$largeSize.height}" /> <span class="span_link">{l s='View full size'}</span> </span> {/if} </div>
See that first img tag? Add the following property to it: itemprop=”image”, so that it looks this way
<img itemprop="image" src="{$link->getImageLink($product->link_rewrite, $cover.id_image, 'large_default')}" {if $jqZoomEnabled}class="jqzoom" alt="{$link->getImageLink($product->link_rewrite, $cover.id_image, 'thickbox_default')}"{else} title="{$product->name|escape:'htmlall':'UTF-8'}" alt="{$product->name|escape:'htmlall':'UTF-8'}" {/if} id="bigpic" width="{$largeSize.width}" height="{$largeSize.height}" />
Brand and identifier
This is where problems begin. You might have your product’s Brand set as a feature, or manufacturer, or supplier; or none of these. Google strongly recommends that you add brand and identifier information for your product snippets, therefore we have to find a way out of it.
Case 1: manufacturer or supplier
Since Prestashop won’t add manufacturer and supplier information in the product page, we have to add it ourselves. Locate a suitable place for it; if you use the default theme, I’d suggest right after the product name. For manufactuters, add the following code:
{l s="by"}<span itemprop="brand" itemscope itemtype="http://schema.org/Organization"> <span itemprop="name">{$product->manufacturer_name}</span></span>
For suppliers:
{l s="by"}<span itemprop="brand" itemscope itemtype="http://schema.org/Organization"> <span itemprop="name">{$product->supplier_name}</span></span>
You may leave the “by” part out if you don’t want it, of course. You might also need to adjust the h1’s bottom margin, depending on your theme. Note that Google wants you to add a new itemscope (Organization) if you add the brand. Keep it in mind!
Case 2: feature
If, on the other hand, you decided to use a feature to add your product’s brand, things are a bit tricky. Depending on where you’re displaying it, you might need some extra code. if you’re just printing it out alone in some place, you can simply wrap it in a span and add the itemprop=”brand”. If this is not the case, and you’re displaying it in the “data sheet” tab, locate the tab’s position in the product.tpl file (about line 514 in the default template) and change it this way.
{foreach from=$features item=feature} {if isset($feature.value)} {if $feature.name == 'Brand'} <li><span>{$feature.name|escape:'htmlall':'UTF-8'}</span> <span itemprop="brand" itemscope itemtype="http://schema.org/Organization"><span itemprop="name">{$feature.value|escape:'htmlall':'UTF-8'}</span></span></li> {else} <li><span>{$feature.name|escape:'htmlall':'UTF-8'}</span> {$feature.value|escape:'htmlall':'UTF-8'}</li> {/if} {/if} {/foreach}
Please notice that you will need to change that “Brand” in “$feature.name == ‘Brand'” to the name of your brand feature. Now that the brand is settled, we can take care of the identifier.
Depending on what you sell, you might want to use different product properties for this one. The product “reference” should be okay in most cases, so let’s add it as identifier. Luckily, Prestashop already displays the product reference in the page, at about line 317 of the default template. Change it the following way:
<span class="editable" itemprop="sku">{$product->reference|escape:'htmlall':'UTF-8'}</span>
Price and Currency
This is perhaps the most important part, because Google may decide not to add rich snippets for your site, if something is wrongly setup here (as I discovered with my own errors!).
Prices fall under the Offer itemscope, therefore we need to add a new schema reference. Locate the product’s main price, at about line 380 of the default template. It’s a bit messy, but this is what we are looking for:
<p class="our_price_display"> {if $priceDisplay >= 0 && $priceDisplay <= 2} <span id="our_price_display">{convertPrice price=$productPrice}</span> <!--{if $tax_enabled && ((isset($display_tax_label) && $display_tax_label == 1) OR !isset($display_tax_label))} {if $priceDisplay == 1}{l s='tax excl.'}{else}{l s='tax incl.'}{/if} {/if}--> {/if} </p>
And here comes the trouble too. Prestashop currently displays the price as number and currency. This is bad for Google Rich Snippets. We need them split in order to add them to the snippet, both price and currency. Let’s start off by wrapping that item with the itemscope and itemprop:
<p class="our_price_display" itemprop="offers" itemscope itemtype="http://schema.org/Offer"> {if $priceDisplay >= 0 && $priceDisplay <= 2} <span id="our_price_display">{convertPrice price=$productPrice}</span> <!--{if $tax_enabled && ((isset($display_tax_label) && $display_tax_label == 1) OR !isset($display_tax_label))} {if $priceDisplay == 1}{l s='tax excl.'}{else}{l s='tax incl.'}{/if} {/if}--> {/if} </p>
Now, Google knows it’s dealing with an offer (price). But it doesn’t exactly know where the price is yet. We have to use a bit of a trick. Change the previous code as follows:
<p class="our_price_display" itemprop="offers" itemscope itemtype="http://schema.org/Offer"> {$rightPrice = {convertPrice price=$productPrice}} {if $priceDisplay >= 0 && $priceDisplay <= 2} {if $currencyFormat == 1 || $currencyFormat == 3} {$currencySign} <span id="our_price_display">{$rightPrice|regex_replace:"/[\\{$currencySign}]/":""}</span> {else} <span id="our_price_display">{$rightPrice|regex_replace:"/[\\{$currencySign}]/":""}</span> {$currencySign} {/if} <!--{if $tax_enabled && ((isset($display_tax_label) && $display_tax_label == 1) OR !isset($display_tax_label))} {if $priceDisplay == 1}{l s='tax excl.'}{else}{l s='tax incl.'}{/if} {/if}--> {/if} </p>
Explanation: This probably left you more confused than ever. First off, since we need the whole formatted price with currency we assign it to a new variable. Then, the only way to have the price alone is to actually remove the currency using a regular expression (Learn more about Regular Expressions in Smarty), and we achieve it with this function:
{$rightPrice|regex_replace:"/[\\{$currencySign}]/":""}
We are basically telling Smarty: Hey, if you find the currency character in that price, replace it with and empty string. Then, we have to deal with the way Prestashop formats currency. If you check the displayPrice method of the Tools class, you will see Prestashop can handle 5 types of currency formats: 2 with the sign before the price, 3 with the sign after it. We have to deal with this of course. Now, we tell Smarty to check the currency format code, if it’s 1 or 3, it means the format is “currency sign before the price”, else, it’s after.
{if $currencyFormat == 1 || $currencyFormat == 3} {$currencySign} <span id="our_price_display">{$rightPrice|regex_replace:"/[\\{$currencySign}]/":""}</span> {else} <span id="our_price_display">{$rightPrice|regex_replace:"/[\\{$currencySign}]/":""}</span> {$currencySign} {/if}
Lastly, let’s tell Google where the relevant information is:
<p class="our_price_display" itemprop="offers" itemscope itemtype="http://schema.org/Offer"> {if $priceDisplay >= 0 && $priceDisplay <= 2} {if $currencyFormat == 1 || $currencyFormat == 3} <meta itemprop="priceCurrency" content="{$currency->iso_code}" /> {$currencySign} <span id="our_price_display" itemprop="price">{$rightPrice|regex_replace:"/[\\{$currencySign}]/":""}</span> {else} <span id="our_price_display" itemprop="price">{$rightPrice|regex_replace:"/[\\{$currencySign}]/":""}</span> <meta itemprop="priceCurrency" content="{$currency->iso_code}" /> {$currencySign} {/if} <!--{if $tax_enabled && ((isset($display_tax_label) && $display_tax_label == 1) OR !isset($display_tax_label))} {if $priceDisplay == 1}{l s='tax excl.'}{else}{l s='tax incl.'}{/if} {/if}--> {/if} </p>
This way, we finally told big G which part is the price, and which the currency. And I thought this was okay…but! Then, I noticed that I was not getting the proper content for the price itemprop. I was still getting the currency! Why is that? It’s because Prestashop uses a pretty dumb way to replace prices with combination prices: thus, if you have attributes setup for the currenct product, the attribute combination price will be set with Javascript. Not so smart, we have to deal with it!
Open up product.js, which you can find in the /js/ folder of your theme. Locate the following code, at about line 400 on the default template:
$('#our_price_display').text(our_price);
This little brat is causing our currency to appear again. Just before this snippet, add the following:
var re = new RegExp("\\"+currencySign, "g"); var signRemoved = our_price.replace(re, "");
Again, we are dealing with price formatting, but this time with javascript. First, we create a regExp object to use our currencySign variable as a pattern for the regular expression, then we remove it from the actual price. In the end, let’s replace the our_price variable with our new, priceless one, so that we get this:
var re = new RegExp("\\"+currencySign, "g"); var signRemoved = our_price.replace(re, ""); $('#our_price_display').text(signRemoved);
If you refresh the page now, you should still get one currency, instead of having it two times. Everything should look as before, but if you check the page source, you’ll notice our tags have been added.
Conclusion
There is still much left with Google Rich Snippets, and the Product item type. I decided to leave things like “condition” and “lowPrice” behind, because they would have required major (and probably confusing) changes in the template. Think of this tutorial as a starting point to add more and more snippet stuff to your shop. And don’t forget the Product item type also supports Reviews. If you’re using the comments module, or any other module, be sure you add that microformat to your site, too!
In any case, here is the tutorial result on a demo shop, tested with the Rich Snippet Tool.
Note that i didn’t add the author information in the link, simply because I didn’t link my google profile to the page. Here is how it looks with the authorship information correctly added: