Customizing Google Snippets with Microdata


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.

 

newsnippets

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

Implementation

————————————————————————————————————

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) . ‘”‘;

to

$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.

find

$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”>
<?php
// 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’]);
?></h2>

Now we will wrap it in the price property

<h2 id=”productPrices”>
<?php
// 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>’;
?></h2>

—————————–

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.

Find

<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

Find

<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>’ : ”) . “\n”; ?>

—————————–

Using the quantity identifier. Locate your quantity line.

<?php echo (($flag_show_product_info_quantity == 1) ? ‘<li>’ . $products_quantity . TEXT_PRODUCT_QUANTITY . ‘</li>’  : ”) . “\n”; ?>

Now we will wrap it in the quantity property

<?php echo (($flag_show_product_info_quantity == 1) ? ‘<li>’ . ‘<span itemprop=”quantity”>’ . $products_quantity . ‘</span>’ .  TEXT_PRODUCT_QUANTITY . ‘</li>’  : ”) . “\n”; ?>

—————————–

Using the Availability property

Just a quick way to dynamically deliver the value of in stock our not from quantity.

In the list you just edited for model and such locate the closing </ul> tag and on the line right above it add the following. Acceptable values are (in_stock, out_of_stock, instore_only or preorder)

<?php if ($products_quantity > 0) { ?><li><span itemprop=”availability” content=”in_stock”>In Stock</span></li><?php }?><?php if ($products_quantity == 0) { ?><li><span itemprop=”availability” content=”out_of_stock”>Out of Stock</span></li><?php }?>

—————————–

Using the Condition property

We will fake this for a vanilla Zen Cart as well by adding another line just above the closing </ul> as in the previous instruction. Values which can be used are (new, used and refurbished)

<li><span itemprop=”condition” content=”new”>New</span></li>

Lastly to make this markup most flexible for search engines and other platforms to understand locate the opening div for your product content in tpl_product_info_display.php

—————————–

Using Rich Snippets to identify the category

the section marked details, find

</ul>
<br />
<?php
}
?>
<!–eof Product details list –>

Just before this line add

<li>Category: <?php echo ‘<span itemprop=”category” content=”‘ . $categories->fields[‘categories_name’] . ‘”>’ . $categories->fields[‘categories_name’] ; ?></li>

—————————–

Using Rich Snippets to identify the payment methods you accept. The syntax provided is for Visa, MasterCard, Discover and PayPal. Other methods can be found here (http://www.heppnetz.de/ontologies/goodrelations/v1#PaymentMethod)

the section marked details, find

</ul>
<br />
<?php
}
?>
<!–eof Product details list –>

Just before this line add

<li>Payments Accepted: <span itemprop=”http://purl.org/goodrelations/v1#acceptedPaymentMethods” href=”http://purl.org/goodrelations/v1#PayPal” />PayPal</span>, <span itemprop=”http://purl.org/goodrelations/v1#acceptedPaymentMethods” href=”http://purl.org/goodrelations/v1#VISA” />Visa</span>, <span itemprop=”http://purl.org/goodrelations/v1#acceptedPaymentMethods” href=”http://purl.org/goodrelations/v1#MasterCard” />MasterCard</span>, <span itemprop=”http://purl.org/goodrelations/v1#acceptedPaymentMethods” href=”http://purl.org/goodrelations/v1#Discover” />Discover</span></li>

—————————–

Using Rich Snippets to identify the general delivery lead time for your products

the section marked details, find

</ul>
<br />
<?php
}
?>
<!–eof Product details list –>

Just before this line add

<li>Delivery Lead Time: <span itemprop=”deliveryLeadTime”>21 days</span></li>

—————————–

Using Rich Snippets to identify the seller (you) for your products. Unless you are running a multi-seller product catalog, this is unnecessary and redundant

the section marked details, find

</ul>
<br />
<?php
}
?>
<!–eof Product details list –>

Somewhere in this list add

<li><b>Available at:</b> <span itemprop=”seller”>Your Name</span></li>

or

<li><b>Available at:</b> <span itemprop=”seller”><?php echo (STORE_NAME );  ?></span></li>

—————————–

Using Rich Snippets to identify the shipping region(s) for your products. Note that the proper 2 letter country code must be used for the content=””, but the text following can be express however you like.

the section marked details, find

</ul>
<br />
<?php
}
?>
<!–eof Product details list –>

Just before this line add

<li>Shipping to: <span itemprop=”eligibleRegion” content=”US”>United States</span> &amp; <span itemprop=”eligibleRegion” content=”CA”>Canada</span></li>

—————————–

Setting up the container for the product schema

Find

<div id=”productGeneral”>

and add this to it

itemscope itemtype=”http://data-vocabulary.org/Product”

So it looks like this

<div id=”productGeneral” itemscope itemtype=”http://data-vocabulary.org/Product”>

————————————————————————————————————

Adding the breadcrumb identifier for Rich Snippets

In includes/classes/breadcrumb.php on line 57

Find

if ($this->_trail[$i][‘title’] == HEADER_TITLE_CATALOG) {
$trail_string .= ‘  <a href=”‘ . HTTP_SERVER . DIR_WS_CATALOG . ‘”>’ . $this->_trail[$i][‘title’] . ‘</a>’;
} else {
$trail_string .= ‘  <a href=”‘ . $this->_trail[$i][‘link’] . ‘”>’ . $this->_trail[$i][‘title’] . ‘</a>’;

and change it to

if ($this->_trail[$i]['title'] == HEADER_TITLE_CATALOG) {
          $trail_string .= '  <span vocab="http://schema.org/" typeof="BreadcrumbList"><span property="itemListElement" typeof="ListItem"><a href="' . HTTP_SERVER . DIR_WS_CATALOG . '">' . $this->_trail[$i]['title'] . '</a></span></span>';
        } else {
          $trail_string .= '  <span property="itemListElement" typeof="ListItem"><a property="item" typeof="WebPage" href="' . $this->_trail[$i]['link'] . '"><span property="name">' . $this->_trail[$i]['title'] . '</span></a></span>';

This is no longer required, reverse it in your file and just use the edit right above.

Then in includes/templates/your_template/common/tpl_main_page.php

Find

<div id=”navBreadCrumb”><?php echo $breadcrumb->trail(BREAD_CRUMBS_SEPARATOR); ?></div>

and change it to

<div id=”navBreadCrumb” itemscope itemtype=”http://data-vocabulary.org/Breadcrumb”><?php echo $breadcrumb->trail(BREAD_CRUMBS_SEPARATOR); ?></div>

————————————————————————————————————

Now go over here and let Google see if they can read your changes properly using the Structured Data Testing Tool. Check our testing site here in the tool. Once you have tested your snippets Google now provides a means to let them know you are using rich snippets by submitting this form. The nice part is that they will respond and note any issues they find to better help you come to completeness.

There are more formats for the product schema that we will be looking to incorporate such as review, aggregateRating and offers. Stay tuned, we will update when this project has changes. These items weren’t initially included as they require a module to display in the product page or the data output is wrong for the Schema, so there will be some core changes and such to incorporate these additional properties for Zen Cart.


55 responses to “Customizing Google Snippets with Microdata”

  1. So I tried this and when used the Structured Data Testing Tool, I got the following messages happening:
    For type: http://schema.org/product
    I got these messages:
    Warning: Missing required field “name (fn)”.
    Warning: Incomplete microdata with schema.org.

    For type: http://data-vocabulary.org/product
    I got this message:
    Warning: In order to generate a preview with rich snippets, either price or review or availability needs to be present.

    What did I possibly miss/do wrong??

  2. I saw that post too.. but I am not sure how that translates to correcting it in Zen Cart.. What am I not seeing here??

  3. Well, two things… I read about it being a bug, in fact Google does not support “organization”… yet, but mostly I read that it’s to be ignored for products as it’s not applicable.

  4. That’s what I thought.. I just wanted to check first though before I start putting this in to practice on a client’s site.. I don’t want to cause more harm than good.. Awesome article.. Was wondering if you will you cover a way to manage condition and availability without having to “fake” it in a future article??

  5. Am actually working on it. Condition not being native is harder for people to do for themselves, but I have it working with custom product fields I added. Availability, category and a few more are actually native and in progress already =)

  6. Thanks Melanie.. 🙂 I follow your blog pretty regularly so I will be on the look out for those articles.. (have a special bookmarks folder JUST for your site) You always post such GOOD information.. I quote VERBATIM regularly from two of your articles to help set my client’s SEO expectation in order..

  7. This post was updated on 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. Also, cleaned up for a bit more clarity =)

  8. Hi, merci beaucoup pour ce tuto, je viens de tester sur google et c’est parfait!

    Hi, thank you very much for this tutorial, it’s clear, simple and it works!! i add you in my favorites!

  9. Hi Melanie… I should visit more often. Diva just alerted me to this information and it’s interesting to see that it matches the approach I was busy with. I have elected to abandon my efforts and carry on with yours, and have already added the tags to the relevant files.

    Thanks for all your hard work (on this and a lot more besides). I am sure the ZC community will be very grateful for this… I certainly am.

  10. Hi Melanie,
    Thank you for this info. I embedded it in one of my test shops, and it works great.
    One small point of improvement maybe. the currency code is hardcoded as USD. My change is te make it the same as the current session value.
    See below:

    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’] . ”);

  11. I actually considered that. The issue is then the data can be available differently on each page. People will link out to a page in another language or currency and then we have duplication of content and such.

  12. I made a slight change to show in_stock/out_of_stock in the quantity in stock line to avoid 2 separate list items, one saying “180 units in stock” then the next line saying “in stock”. Seemed redundant and not smooth. Here’s my code, omitting your new snippet for the stock line:

    0) { ?>
    <?php echo (($flag_show_product_info_quantity == 1) ? '’. ” . $products_quantity . ” . ” .TEXT_PRODUCT_QUANTITY . ” : ”) . “\n”; ?>

    Out of Stock

  13. I did also on many shops, but left it 2 line items in the tutorial so that people could turn off qty in stock as many do more easily.

  14. Hi,

    Thanks for sharing the code!

    I have checked https://outdoorcountrydecor.com/rugged-cross-memorial-plaque in the testing tool and it looks like for specials, the price isn’t working anymore and becomes: $84.60 $83.00 Save: $1.60 off. Is there any way to fix that?

    Also, I found that on product pages with other images, such as also purchased images, the itemprop=”image” attribute is added to those images as well.

  15. Specials is still an issue, has been… Working on it in my downtime, but it’s not completed yet. Specials needs to have reg price, special price, beginning date and ending date minimum but should also have eligibleQuantity and eligibleRegion, which is a genuine struggle I am finding. and The image issue is only an issue with also purchased products, but again.. a work in progress. Dynamic ability is so very powerful and yet so very “set in it’s ways” at times =)

  16. I posted a second method I have been working on for images, but it’s not without it’s own issues including custom template struggles.

  17. Hello,

    Thanks for the great post. I followed your instructions which are very well laid out. But I ran into a few problems.

    1) When I attempt to edit the breadcrumb.php I receive a blank page on my website
    2) It seems that all meta data no longer shows up. Not sure if this is suppose to happen or not

    Any help is greatly appreciated.

    Thanks

  18. The blank page is likely an error editing, check your logs to find the error. Post it and i will be glad to help you sort it

  19. Melanie – thanks for your informative post! I have implemented this on my site at http://www.tjsattic.com and did the check, but get the following error:
    Error: In order to generate a preview with rich snippets, either price or review or availability needs to be present.

    Also – I have Image handler installed and the links to the images are the bmz_cache images. Wondering if there is a way to get it to display the actual image NAME that I uploaded into Image handler instead of the bmz_cache image name? Or does that not make any difference SEO wise? I always name my images to match up with what my product is.

    THANKS!!

    Judy

  20. Thanks for this really useful and informative post, thanks to this guide I was able to successfully implement microdata.

    Would you consider expanding on GoodRelations, how we can start using it, like the GR generator to append store information to ….

    Is what you’ve already provided sufficient for both RDFa, Schema.org, GoodRelations & Microdata? Also what about covering Microformats as well? Surely it’s possible to cover all of these.

    Rich

  21. Sure it’s possible, but the nesting is a nightmare and cannot be done in a “Vanilla” format such as this because of different template product page layouts. This is intended to be both sufficient data to help merchants and be vanilla enough for layman implementation.

  22. Thank you so much for this great post. I modified the availability to cover In Stock, Out of Stock and Preorder with this minor change:

    <?php if (($products_date_available 0) { ?>Availability: In StockAvailability: Out of Stock date(‘Y-m-d H:i:s’)) && $products_quantity > 0) { ?>Availability: Preorder
    Processing Time: 1-3 Business Days

    Not sure if this is the best way to go about it but it works.

    Thanks!

  23. Two things…
    1. my previous comment was incomplete, not sure what happened. 2. I will greatly appreciate your assistance as the markup on our page is NOT validating in Google Structured Data Testing Tool. The error message is: “Error: In order to generate a preview with rich snippets, either price or review or availability needs to be present.” You can take a look at our site (if needed) to see that the data there: http://www.clevershoppers.com/index.php?main_page=product_info&products_id=65420

    Thank you!

  24. Tour itemscope itemtype=”http://data-vocabulary.org/Product” is added as needed but your template is missing a div. To the itemscope itemtype=”http://data-vocabulary.org/Product” nest only has name and price within it. The opening tag is on line 293 and the ending 344 in your generated source.

  25. Hi, thank you SO much for this informative and amazing information! Have you addressed the image issue with the Image Handler module?

  26. Very welcome! I think the easiest way is to install NUMINIX’s Facebook Opengraph (because this is good for your site too) and bring the correct image in another way. I am currently using the cache image on our sites.

    img src=”bmz_cache/7/7d65368ffc75253fc8c1d758cb8ebb46.image.250×250.jpg” alt=”Established Sunshine Building Plaque” title=”Established Sunshine Building Plaque ” width=”250″ height=”250″ itemprop=”image”

    It is also my understanding that this, all of it, will be addressed in Zen Cart 1.6.0

  27. Ok that NUMINIX solution sounds interesting, I’ll definitely check into it since as you say, it creates external traffic! As far as self contained operation, I was able to specify only the single product image for the itemprop and have the itemprop=”image” command ignore the cross sell, featured products, etc. images. I know basically nothing about php or this stuff so it was quite painful and I think I almost died from this one hurdle lol

    It seems like this would be useful instead of specifying all images on the page as “the” image for the product’s structured listing. Let me know if you would like the code, I’d love to contribute something useful back to the ZC community (if this indeed is actually something unique and useful). Maybe it’s ho hum and has been done before, I’m not sure??? =-\

    Thanks again for all of your great information and have a Happy New Year!! =o)

  28. That’s not the problem. The problem is you have an unclosed div — probably div id=”mainWrapper” from the looks of it. This is causing the div for the product offer div id=”productGeneral” itemscope itemtype=”http://data-vocabulary.org/Product” to be completed and closed before the product prices. The product prices are then nested incorrectly and not within the offer.

  29. Hey Melanie..

    Updating my test site with all the changes you made since the last time I stopped by.. No errors (whoo hoo) and everything looks good. I did move the quantity in stock display below the Availability and added labels for Availability and Condition. I also added a condition so that the quantity n stock won’t display if the Availability is “Out of Stock”. Seemed redundant to show a stock amount of 0 if the Availability is “Out of Stock”.

    ‘ 0) { ?>Availability: In StockOut of Stock
    0) { ?><?php echo (($flag_show_product_info_quantity == 1) ? '’ . ” . $products_quantity . ” . TEXT_PRODUCT_QUANTITY . ” : ”) . “\n”; ?>
    Condition: New’

    ONE minor thing..

    In the preview I see the following:
    “$250,000.00 – ‎In stock”

    The actual product price is $25. Though I copied and pasted directly from this article, I’ve double checked my edits anyway.. All is my changes/edits match the article.. How can I fix this??

    Here’s the link: http://zentestcart.overthehillweb.com/index.php?main_page=product_info&cPath=53&products_id=117

  30. Updating my test site with all the changes you made since the last time I stopped by.. No errors (whoo hoo) and everything looks good. I did move the quantity in stock display below the Availability and added labels for Availability and Condition. I also added a condition so that the quantity n stock won’t display if the Availability is “Out of Stock”. Seemed redundant to show a stock amount of 0 if the Availability is “Out of Stock”.

    While this may seem logical it causes indexing problems as a value is expected by the search engines.

    The price is probably the PHP math or version issue on the server… try this instead

    php echo $products_price = (round(zen_get_products_base_price($product_info->fields[‘products_id’]),2));

  31. One more thing.. Seems like I am getting the “In order to generate a preview with rich snippets, either price or review or availability needs to be present” error for the Document Product Type. This has me stumped since the Product General Type info page is identical to Document Product Type with the only difference being the CSS classes. You can see here:

    http://www.google.com/webmasters/tools/richsnippets?q=http%3A%2F%2Fzentestcart.overthehillweb.com%2Findex.php%3Fmain_page%3Ddocument_product_info%26cPath%3D64%26products_id%3D171

    Compare to Product General Type
    http://www.google.com/webmasters/tools/richsnippets?q=http%3A%2F%2Fzentestcart.overthehillweb.com%2Findex.php%3Fmain_page%3Dproduct_info%26cPath%3D64%26products_id%3D168

  32. While this may seem logical it causes indexing problems as a value is expected by the search engines.

    So are you saying that it would it be better to just turn off the stock display using the Product Type settings in the admin?? Or will this too cause issues with the search engines?

    php echo $products_price = (round(zen_get_products_base_price($product_info->fields[‘products_id’]),2));

    Thanks this did the trick..

  33. Re:

    One more thing.. Seems like I am getting the “In order to generate a preview with rich snippets, either price or review or availability needs to be present” error for the Document Product Type. This has me stumped since the Product General Type info page is identical to Document Product Type with the only difference being the CSS classe

    You can delete this post if you like.. It appears as if the price fix solved this issue..

  34. What I’m saying is whether they are in stock or not the stock number (level) is an indexed value. So it should always be present.

    Google crawls finds the data indexes all of it including say, 4 in stock.

    They come back and instead of zero in stock the value is missing even though they have it indexed.

    So they remove it from the index, then when they come back the page has to re-index its values again, from fresh if its back in stock.

  35. Ahhh was the less than a whole dollar… I was thinking that one had me stumped until I did a file compare on the generated source