40
Implement Rich Snippets in Your Webshop

Implement rich snippets in your webshop

Embed Size (px)

Citation preview

Implement Rich Snippetsin Your Webshop

Arjen Miedematwitter.com/arjenmiedema_nl | linkedin.com/in/arjenmiedemanl

Let’s see how it works!

Extension vs. Template

Installing an extension is easy (most of the times)

You can manage everything in your Magento backend

You don’t want to be able to enable or disable rich snippets in your Magento backend

The extension needs to make changes to your template files as well

Extension

You don’t know if the extension works out-of-the-box with your custom template

Extension vs. Template

You can set all rich snippets you want in your own, custom template

No unnecessary configuration options are added

You’ll need some knowledge of HTML

It will take some time to implement and check the rich snippets

Template

It’s free (if you know how to implement them yourself)

Easy to extend in the future with additional information

Requirements

Google’s Structured Data Testing Tool

Basic Magento Theming experience

These slides :-)

<div> <h1>The Minions</h1> <ul> <li> <span class="label">Directors:</span> <span class="value">Pierre Coffin, Kyle Balda</span> </li> <li> <span class="label">Duration:</span> <span class="value">1:31</span> </li> <li> <span class="label">Genre:</span> <span class="value">Animation</span> </li> </ul> <div class="description"> The movie before Despicable Me, which tells you more about the Minions. </div></div>

Example

<div itemscope itemtype="http://schema.org/Movie"> <h1 itemprop="name">The Minions</h1> <ul> <li> <span class="label">Directors:</span> <span class="value"> <span itemprop="director">Pierre Coffin</span>, <span itemprop="director">Kyle Balda</span> </span> </li> <li> <span class="label">Duration:</span> <span class="value">1:31</span> </li> <li> <span class="label">Genre:</span> <span class="value" itemprop="genre">Animation</span> </li> </ul> <div class="description" itemprop="description"> The movie before Despicable Me, which tells you more about the Minions. </div> <meta itemprop="duration" content="T1H31M"/></div>

Example

We can do that!

Open file: app/design/frontend/[package]/[theme]/template/page/1column.phtml

Find:

<body<?php echo $this->getBodyClass()?' class="'.$this->getBodyClass().'"':'' ?>>

Replace with:

<?php$action = Mage::app()->getFrontController()->getAction()->getFullActionName();$itemtype = ($action == 'catalog_product_view') ? 'http://schema.org/Product' : 'http://schema.org/WebPage';?><body<?php echo $this->getBodyClass()?' class="'.$this->getBodyClass().'"':'' ?> itemscope itemtype="<?php echo $itemtype; ?>">

Repeat this for all page templates (2 columns and 3 columns)

Set Content Type

Open file: app/design/frontend/[package]/[theme]/template/page/html/breadcrumbs.phtml

Find:

<li class="<?php echo $_crumbName ?>">

Replace with:

<li class="<?php echo $_crumbName ?>"<?php if($_crumbInfo['link']):?> itemscope itemtype="http://data-vocabulary.org/Breadcrumb"<?php endif; ?>>

Breadcrumbs

Open file: app/design/frontend/[package]/[theme]/template/page/html/breadcrumbs.phtml

Find:

<a href="<?php echo $_crumbInfo['link'] ?>" title="<?php echo $this->escapeHtml($_crumbInfo['title']) ?>"><?php echo $this->escapeHtml($_crumbInfo['label']) ?></a>

Replace with:

<a href="<?php echo $_crumbInfo['link'] ?>" title="<?php echo $this->escapeHtml($_crumbInfo['title']) ?>" itemprop="url"><span itemprop="title"><?php echo $this->escapeHtml($_crumbInfo['label']) ?></span></a>

Breadcrumbs

Open file: app/design/frontend/[package]/[theme]/template/catalogsearch/form.mini.phtml

Add to the end of the file:

<?php if(Mage::getBlockSingleton('page/html_header')->getIsHomePage()): ?><script type="application/ld+json">{ "@context": "http://schema.org", "@type": "WebSite", "url": "<?php echo Mage::getBaseUrl(); ?>", "potentialAction": { "@type": "SearchAction", "target": "<?php echo $this->getUrl('search?q={q}'); ?>", "query-input": "required name=q" }}</script><?php endif; ?>

Search Box

Product Information

Product name, description, image, SKU

Prices

Stock information

Reviews

Related products and similar (upsell) products

Product ratings

Open file: app/design/frontend/[package]/[theme]/template/catalog/product/view.phtml

Find:

<div class="product-name"> <h1><?php echo $_helper->productAttribute($_product, $_product->getName(), 'name') ?></h1></div>

Replace with:

<div class="product-name"> <h1 itemprop="name"><?php echo $_helper->productAttribute($_product, $_product->getName(), 'name') ?></h1> <meta itemprop="sku" content="<?php echo $_product->getSku() ?>"/></div>

Product Name & SKU

Open file: app/design/frontend/[package]/[theme]/template/catalog/product/view.phtml

Find:

<div class="short-description"> <h2><?php echo $this->__('Quick Overview') ?></h2> <div class="std"><?php echo $_helper->productAttribute($_product, nl2br($_product->getShortDescription()), 'short_description') ?></div></div>

Replace with:

<div class="short-description"> <h2><?php echo $this->__('Quick Overview') ?></h2> <div class="std" itemprop="description"><?php echo $_helper->productAttribute($_product, nl2br($_product->getShortDescription()), 'short_description') ?></div></div>

Product Description

Open file: app/design/frontend/[package]/[theme]/template/catalog/product/view.phtml

Find:

<div class="price-info"> <?php echo $this->getPriceHtml($_product); ?>

Replace with:

<div class="price-info"<?php if(!$_product->isGrouped()): ?> itemprop="offers" itemscope itemtype="<?php echo ($_product->getTypeId() == 'giftcard' || $_product->getTypeId() == 'bundle') ? 'http://schema.org/AggregateOffer' : 'http://schema.org/Offer'; ?>"<?php endif; ?>> <?php if(!$_product->isGrouped()): ?> <meta itemprop="priceCurrency" content="<?php echo Mage::app()->getStore()->getCurrentCurrencyCode(); ?>"/> <?php endif; ?> <?php echo $this->getPriceHtml($_product); ?>

Prices

Open file: app/design/frontend/[package]/[theme]/template/catalog/product/view/media.phtml

Find:

<img id="image-main" class="gallery-image visible" src="<?php echo $this->helper('catalog/image')->init($_product, 'image') ?>" alt="<?php echo $this->escapeHtml($this->getImageLabel()) ?>" title="<?php echo $this->escapeHtml($this->getImageLabel()); ?>" />

Replace with:

<img id="image-main" itemprop="image" class="gallery-image visible" src="<?php echo $this->helper('catalog/image')->init($_product, 'image') ?>" alt="<?php echo $this->escapeHtml($this->getImageLabel()) ?>" title="<?php echo $this->escapeHtml($this->getImageLabel()); ?>" />

Product Image

Open file: Open file: app/design/frontend/[package]/[theme]/template/catalog/product/view.phtml

Find:

<?php echo $this->getTierPriceHtml() ?></div>

Replace with:

<?php echo $this->getTierPriceHtml() ?>

<?php if ($_product->isAvailable()): ?> <link itemprop="availability" href="http://schema.org/InStock"/> <?php else: ?> <link itemprop="availability" href="http://schema.org/OutOfStock"/> <?php endif; ?></div>

Stock Information

Open file: app/design/frontend/[package]/[theme]/template/review/helper/summary.phtml

Find:

<?php if ($this->getReviewsCount()): ?> <div class="ratings"> <?php if ($this->getRatingSummary()):?>

Replace with:

<?php if ($this->getReviewsCount()): ?> <div class="ratings" itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating"> <?php if ($this->getRatingSummary()):?> <meta itemprop="ratingValue" content="<?php echo $this->getRatingSummary()/10; ?>"/> <meta itemprop="reviewCount" content="<?php echo $this->getReviewsCount(); ?>"/> <meta itemprop="bestRating" content="10"/> <meta itemprop="worstRating" content="0"/>

Product Ratings

Open file: app/design/frontend/[package]/[theme]/template/review/product/view/list.phtml

Find:

<dd> <?php $_votes = $_review->getRatingVotes(); ?>

<?php echo nl2br($this->escapeHtml($_review->getDetail())) ?>

Replace with:

<dd itemprop="review" itemscope itemtype="http://schema.org/Review"> <meta itemprop="url" content="<?php echo $this->getReviewUrl($_review->getId()) ?>"/> <meta itemprop="name" content="<?php echo $_review->getTitle() ?>"/> <?php $_votes = $_review->getRatingVotes(); ?>

<div itemprop="description"><?php echo nl2br($this->escapeHtml($_review->getDetail())) ?></div>

Reviews

Open file: app/design/frontend/[package]/[theme]/template/review/product/view/list.phtml

Find:

<td> <div class="rating-box"> <div class="rating" style="width:<?php echo $_vote->getPercent() ?>%;"></div> </div></td>

Replace with:

<td> <div class="rating-box" itemprop="reviewRating" itemscope="itemscope" itemtype="http://schema.org/Rating"> <meta itemprop="worstRating" content="1" /> <meta itemprop="ratingValue" content="<?php echo $_vote->getPercent() / 10; ?>" /> <meta itemprop="bestRating" content="10" /> <div class="rating" style="width:<?php echo $_vote->getPercent() ?>%;"></div> </div></td>

Reviews

Open file: app/design/frontend/[package]/[theme]/template/review/product/view/list.phtml

Find:

<span class="review-meta"> <?php echo $this->__('Review by %s', $this->escapeHtml($_review->getNickname())) ?> / <?php echo $this->__('(Posted on %s)', $this->formatDate($_review->getCreatedAt()), 'long') ?></span>

Replace with:

<span class="review-meta"> <meta itemprop="datePublished" content="<?php echo Mage::app()->getLocale()->date(strtotime($_review->getCreatedAt()))->get('YYYY-MM-dd'); ?>"> <meta itemprop="author" content="<?php echo $this->escapeHtml($_review->getNickname()); ?>"> <?php echo $this->__('Review by %s', $this->escapeHtml($_review->getNickname())) ?> / <?php echo $this->__('(Posted on %s)', $this->formatDate($_review->getCreatedAt()), 'long') ?></span>

Reviews

Open file: app/design/frontend/[package]/[theme]/template/catalog/product/list/related.phtml

Find:

<ol class="mini-products-list" id="block-related"><?php foreach($this->getItems() as $_item): ?> <li class="item">

Replace with:

<ol class="mini-products-list" id="block-related"><?php foreach($this->getItems() as $_item): ?> <li class="item" itemprop="isRelatedTo" itemscope itemtype="http://schema.org/Product">

Related Products

Open file: app/design/frontend/[package]/[theme]/template/catalog/product/list/related.phtml

Find:

<div class="product"> <a href="<?php echo $_item->getProductUrl() ?>" title="<?php echo $this->escapeHtml($_item->getName()) ?>" class="product-image"><img src="<?php echo $this->helper('catalog/image')->init($_item, 'thumbnail')->resize(75) ?>" width="75" height="75" alt="<?php echo $this->escapeHtml($_item->getName()) ?>" /></a>

Replace with:

<div class="product"> <a href="<?php echo $_item->getProductUrl() ?>" itemprop="url" title="<?php echo $this->escapeHtml($_item->getName()) ?>" class="product-image"><img src="<?php echo $this->helper('catalog/image')->init($_item, 'thumbnail')->resize(75) ?>" width="75" height="75" alt="<?php echo $this->escapeHtml($_item->getName()) ?>" /></a>

Related Products

Open file: app/design/frontend/[package]/[theme]/template/catalog/product/list/related.phtml

Find:

<div class="product-details"> <p class="product-name"><a href="<?php echo $_item->getProductUrl() ?>"><?php echo $this->escapeHtml($_item->getName()) ?></a></p> <?php echo $this->getPriceHtml($_item, true, '-related') ?>

Replace with:

<div class="product-details"> <p class="product-name" itemprop="name"><a href="<?php echo $_item->getProductUrl() ?>"><?php echo $this->escapeHtml($_item->getName()) ?></a></p> <div class="price-info" itemprop="offers" itemscope itemtype="<?php echo ($_item->isGrouped() || $_item->getTypeId() == 'giftcard' || $_item->getTypeId() == 'bundle') ? 'http://schema.org/AggregateOffer' : 'http://schema.org/Offer'; ?>"> <meta itemprop="priceCurrency" content="<?php echo Mage::app()->getStore()->getCurrentCurrencyCode(); ?>"/> <?php echo $this->getPriceHtml($_item, true, '-related') ?> </div>

Related Products

Open file: app/design/frontend/[package]/[theme]/template/catalog/product/list/upsell.phtml

Find:

<h3 class="product-name"><a href="<?php echo $_link->getProductUrl() ?>" title="<?php echo $this->escapeHtml($_link->getName()) ?>"><?php echo $this->escapeHtml($_link->getName()) ?></a></h3><?php echo $this->getPriceHtml($_link, true, '-upsell') ?><?php echo $this->getReviewsSummaryHtml($_link) ?>

Replace with:

<h3 class="product-name" itemprop="name"><a href="<?php echo $_link->getProductUrl() ?>" title="<?php echo $this->escapeHtml($_link->getName()) ?>"><?php echo $this->escapeHtml($_link->getName()) ?></a></h3><div class="price-info" itemprop="offers" itemscope itemtype="<?php echo ($_link->isGrouped() || $_link->getTypeId() == 'giftcard' || $_link->getTypeId() == 'bundle') ? 'http://schema.org/AggregateOffer' : 'http://schema.org/Offer'; ?>"> <meta itemprop="priceCurrency" content="<?php echo Mage::app()->getStore()->getCurrentCurrencyCode(); ?>"/> <?php echo $this->getPriceHtml($_link, true, '-upsell') ?></div><?php echo $this->getReviewsSummaryHtml($_link) ?>

Upsells

Open file: app/design/frontend/[package]/[theme]/template/catalog/product/list/upsell.phtml

Find:

<li> <a href="<?php echo $_link->getProductUrl() ?>" title="<?php echo $this->escapeHtml($_link->getName()) ?>" class="product-image"> <img src="<?php echo $this->helper('catalog/image')->init($_link, 'small_image')->resize(280) ?>" alt="<?php echo $this->escapeHtml($_link->getName()) ?>" /> </a>

Replace with:

<li class="item" itemprop="isSimilarTo" itemscope itemtype="http://schema.org/Product"> <a href="<?php echo $_link->getProductUrl() ?>" itemprop="url" title="<?php echo $this->escapeHtml($_link->getName()) ?>" class="product-image"> <img itemprop="image" src="<?php echo $this->helper('catalog/image')->init($_link, 'small_image')->resize(280) ?>" alt="<?php echo $this->escapeHtml($_link->getName()) ?>" /> </a>

Upsells

Open file: app/design/frontend/[package]/[theme]/template/catalog/product/price.phtml

Download the code from this page and replace the existing code:

gist.github.com/ArjenMiedema/1877ce02e02e0aaedb60

Product Price

Test Your Rich Snippets

Open a product page in your webshop

View the source code

Copy the entire source code

Go to the Google Structured Data Testing Tool

Paste your source code in the left column and validate

Check the result in the right column

Repeat with different product and product types

Extend Your Data

Send the product condition (used, new, etc.)

Add attribute related data (manufacturer, color, etc.)

Extend it with other rich snippets (Organization, blog)

It’s easy to extend the data you send to Google

Questions?