Zen Cart is certainly powerful software, but it’s prowess is the dynamic platform of functions in PHP which are usable in many different calls from different areas of the template. Social media has been a challenge for Zen Cart, specifically pointing out the product image properly for social sharing. Because Zen Cart has many different page templates and only one real <head> template… the challenge for making Google + for example select the product image has been a rough road.

However, Microdata, from Schema.org, Good Relations and Rich Snippets opens the door for us. Now Facebook has their own system, but should support Microdata as well. Schema.org is a universal project which provides a collection of markup tags to markup pages in ways recognized by major search engines. Search engines including Bing, Google, Yahoo! and Yandex rely on this system to improve the display of search results, making it easier for people to search and find web pages.

In this post I will show you how to implement the Product Schema Microdata for your product pages. Now this tutorial is for 1.5.0, but if you’re sharp you can easily implement it in other Zen Cart versions.



So the applicable tags we have available currently for Products are as follows:

  • name – name of the product.
  • description – A short description of the item.
  • image – URL of an image of the item.
  • price – The price of the product. A floating point number. You may use either a decimal point (‘.’) or a comma (‘,’) as a separator.
  • currency – The currency used to describe the product price, in three-letter ISO format.
  • quantity – Number in stock
  • availability – out_of_stock, in_stock, instore_only or preorder
  • brand/manufacturer – The brand of the product.
  • condition – new, used or refurbished.
  • identifier – asin, isbn, mpn, sku or upc.
  • breadcrumb – Bread crumbs, path to category
  • category – The product category—for example, “Books-Fiction“, “Tools“, or “Cars“. You can include multiple categories. Any value is accepted, but Google recognizes the categories described in this article.
  • seller – The seller of the product. Can contain a Person or Organization.
  • offer language markup is included via your Zen Cart meta tag (lang=”en“). This is not microdata markup any longer, as it should never have been =)
  • payment methods
  • delivery lead time
  • offer delivery area

!!!!UPDATE   11/30/2016 !!!!!

If you are still using this the breadcrumbs instructions have changed below.

!!!!UPDATE   2/3/2015 !!!!!

I have developed a module that nearly anyone can install that does this and much more. It’s BETA, but give it a shot HERE

!!!!UPDATE   2/3/2015 !!!!!

*** Update 1/29/2013 to remove (itemscope itemtype=”http://schema.org/Product“) from html_header.php and move more towards Microdata markup more suitable for products and added breadcrumbs and category tags.

*** Update 3/21/2013 Added offer language and submission tool for Google

*** Update 4/17/2013 Added Payments Accepted, Delivery Lead Time and Delivery Area

***Update 10/25/2013 solved specials issue for pricing



Using the identifier for your product’s image.

This method, while imperfect will include all additional images and attribute images. The imperfect part is that it will include cross sell images (if installed) and also purchased etc. The second optional method will include ONLY the main product image, but no additional product images AND has some struggle with Image Handler (if installed). They both work fine with Zen Lightbox (if installed). The second option produces results less than desirable, and for now we encourage you to use the first.

First Option In includes/functions/html_output.php line 199

change the 2cnd image tag

$image = ‘<img src=”‘ . zen_output_string($src) . ‘” alt=”‘ . zen_output_string($alt) . ‘”‘;


$image = ‘<img itemprop=”image” src=”‘ . zen_output_string($src) . ‘” alt=”‘ . zen_output_string($alt) . ‘”‘;

Second Option In includes/templates/your_template/tpl_modules_main_product_image.php

find 2 instances of  

<span class=”imgLink”>

and change to

<span  itemprop=”image” class=”imgLink”>

If you are using Zen Lightbox you can do the following with a little better results for option 2.


$rel . ‘” title=”‘ . addslashes($products_name) . ‘”>

and change to

$rel . ‘” title=”‘ . addslashes($products_name) . ‘” itemprop=”image”>


Using the identifier for your product’s name.

In includes/templates/your_template/templates/tpl_product_info_display.php

Locate your product name

<h1 id=”productName”><?php echo $products_name; ?></h1>

Now wrap it in the property name tag

<h1 id=”productName”><span itemprop=”name“><?php echo $products_name; ?></span></h1>


This method is the OLD way, and perfectly acceptable if you don’t use a great deal of specials.

Using the identifier for your product’s price & currency type. Note: We have added only 1 currency value, not multiple.

Locate your price

<h2 id=”productPrices”>
// base price
if ($show_onetime_charges_description == ‘true’) {
$one_time = ‘<span >’ . TEXT_ONETIME_CHARGE_SYMBOL . TEXT_ONETIME_CHARGE_DESCRIPTION . ‘</span><br />’;
} else {
$one_time = ”;
echo $one_time . ((zen_has_product_attributes_values((int)$_GET[‘products_id’]) and $flag_show_product_info_starting_at == 1) ? TEXT_BASE_PRICE : ”) . zen_get_products_display_price((int)$_GET[‘products_id’]);

Now we will wrap it in the price property

<h2 id=”productPrices”>
// base price
if ($show_onetime_charges_description == ‘true’) {
$one_time = ‘<span >’ . TEXT_ONETIME_CHARGE_SYMBOL . TEXT_ONETIME_CHARGE_DESCRIPTION . ‘</span><br />’;
} else {
$one_time = ”;
echo $one_time . ((zen_has_product_attributes_values((int)$_GET[‘products_id’]) and $flag_show_product_info_starting_at == 1) ? TEXT_BASE_PRICE : ”) . ‘<span itemprop=”offerDetails” itemscope itemtype=”http://data-vocabulary.org/Offer”><meta itemprop=”currency” content=”USD”/><span itemprop=”price”>’ . zen_get_products_display_price((int)$_GET[‘products_id’]) . ‘</span></span>’;


Prices markup NEW way, no errors. Before you do this, to better understand, please read this post 

So I have been struggling with this for NO good reason. There is NO good reason to include the specials prices at all! Google caches this information, so we should be just giving them the product’s regular price anyhow.


<ul id=”productDetailsList” style=”font-size:11px;”>

And somewhere in your list add this list item.

<li>Products Regular Price: $<span itemprop=”offerDetails” itemscope itemtype=”http://data-vocabulary.org/Offer”><meta itemprop=”currency” content=”USD”/><span itemprop=”price”><?php echo $products_price = zen_get_products_base_price($product_info->fields[‘products_id’]); ?></span></span></li>


Only accept 1 currency? You can use a Meta Tag to set your currency markup.

In includes/templates/your_template/common/html_header.php


<meta http-equiv=”imagetoolbar” content=”no” />

and on the next line add

<meta itemprop=”currency” content=”USD” />


Using the identifier for your product’s description.

 Locate your product description

<div id=”productDescription”><?php echo stripslashes($products_description); ?></div>

and wrap it in the description property tag

<div id=”productDescription”><span itemprop=”description”><?php echo stripslashes($products_description); ?></span></div>


Using the identifier for your product’s brand/manufacturer.

Locate the manufacturer’s function

<?php echo (($flag_show_product_info_manufacturer == 1 and !empty($manufacturers_name)) ? ‘<li>’ . TEXT_PRODUCT_MANUFACTURER . $manufacturers_name . ‘</li>’ : ”) . “\n”; ?>

now you will wrap it in either the brand or manufacturer property tag, whichever is most appropriate for your cart

<?php echo (($flag_show_product_info_manufacturer == 1 and !empty($manufacturers_name)) ? ‘<li>’ . TEXT_PRODUCT_MANUFACTURER . ‘<span itemprop=”brand”>’ . $manufacturers_name . ‘</span></li>’ : ”) . “\n”; ?>


Using the identifier model. Locate your model number line.

<?php echo (($flag_show_product_info_model == 1 and $products_model !=”) ? ‘<li>’ . TEXT_PRODUCT_MODEL . $products_model . ‘</li>’ : ”) . “\n”; ?>

Now we will wrap it in the mpn (manufacturers part number) identifier property

<?php echo (($flag_show_product_info_model == 1 and $products_model !=”) ? ‘<li>’ . TEXT_PRODUCT_MODEL . ‘<span itemprop=”identifier” content=”mpn:’  .  $products_model . ‘”>’ . $products_model . ‘</span></li>’ : ̶