Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Implementing rich snippets on your WebSphere Commerce site to improve search engine results

A step-by-step tutorial using WebSphere Commerce V7 FEP3

Naomi Wan (nylwan@ca.ibm.com), Staff Software Developer, IBM
Photo of Naomi Wan
Naomi Wan is a Staff Software Developer at the IBM Toronto Software Lab, Canada. She has been part of the WebSphere Commerce team since 2001. She has extensive experience in WebSphere Commerce starter stores and Web 2.0 technologies.

Summary:  Learn how to mark up data for product reviews and other product information for the Madisons starter store that comes with WebSphere® Commerce V7.

Date:  24 Aug 2011
Level:  Intermediate PDF:  A4 and Letter (780 KB | 14 pages)Get Adobe® Reader®

Comments:  

Marking up the product detail page

Once you identify what information to mark up for your product, find and update the JSPs. This section will provide pointers on how to update the Madisons store JSPs to mark up the product name, description, price, availability, and rating of a product in microdata format.

Defining the itemscope attribute

  1. First, define the itemscope attribute to tell you are using microdata on this page and you are marking up a product in this case. A URL that you can use for the item type is http://data-vocabulary.org/Product.
  2. Open CachedProductOnlyDisplay.jsp and locate the following block of code shown in Listing 3. Add the line highlighted in bold to the JSP.

    Listing 3. Adding itemscope to CachedProductOnlyDisplay.jsp
                    
    <%-- remove double quote from shortdescription --%>
    <c:set var="search" value='"'/>
    <c:set var="replaceStr" value="'"/>
    <c:set var="prodShortDesc" 
    value="${fn:replace(product.description.shortDescription, search, replaceStr)}"/>
    
    <div id="body588">
      <div itemscope="itemscope" itemtype="http://data-vocabulary.org/Product">
        <div id="product">
          <div class="product_images" id="WC_CachedProductOnlyDisplay_div_1">
            <c:if test="${addProductDnD eq 'true'}">
              <div dojoType="dojo.dnd.Source" jsId="dndSource" 
              id="DndItem_<c:out value='${dnd_catalogEntryID}'/>" copyOnly="true" 
              dndType="<c:out value='${dragType}'/>">
                <div class="dojoDndItem" dndType="<c:out value='${dragType}'/>" 
                id="WC_CachedProductOnlyDisplay_div_2">
            </c:if>

    To close the div, go to the end of the file and locate the following block of code shown in Listing 4. Add the line highlighted in bold to the JSP.



    Listing 4. Adding itemscope to CachedProductOnlyDisplay.jsp
                    
          <%-- End - Added for Coremetrics Intelligent Offer --%>	
        </flow:ifEnabled>
        </div>
      </div>
    </div>
    <!-- END CachedProductOnlyDisplay.jsp -->

Defining the itemprop name

  1. Next, you can add an itemprop attribute to mark up the name of the product.
  2. From CachedProductOnlyDisplay.jsp, locate the following block of code shown in Listing 5. Add the code highlighted in bold to the JSP.

    Listing 5. Adding name itemprop to CachedProductOnlyDisplay.jsp
                    
    <div class="product_options" id="WC_CachedProductOnlyDisplay_div_3">
      <h1 id="catalog_link" class="catalog_link">
        <span itemprop="name">
          <c:out value="${product.description.name}" escapeXml="false"/>
        </span>
      </h1>
      
      <%-- in Elite, we do not want to show the price because the price may be different 
      depending on the contract that is selected --%>
      <c:if test="${displayListPriceInProductPage == 'true'}">	
       <div id="WC_CachedProductOnlyDisplay_div_4">
        <span class="price bold"><fmt:message key="PRICE" bundle="${storeText}"/></span>
        <c:set var="catalogEntryDB" value="${product}" />
        <c:set var="displayPriceRange" value="true"/>
        <c:set var="priceHighlightable" value="true"/>
        <%@ include file="../../../Snippets/ReusableObjects/
         CatalogEntryPriceDisplay.jspf"%>
       </div>
      </c:if>

Defining the itemprop description

  1. You can also add an itemprop attribute to mark up the description of the product.
  2. From CachedProductOnlyDisplay.jsp, locate the following block of code shown in Listing 6. Add the code highlighted in bold to the JSP.

    Listing 6. Adding description itemprop to CachedProductOnlyDisplay.jsp
                    
    <p>
      <fmt:message key="SKU" bundle="${storeText}" />: 
      <c:out value="${product.partNumber}" escapeXml="false"/>
    </p>
    <p>
      <c:out value="${product.description.shortDescription}" escapeXml="false"/>
    </p>
    <br />
    <p>
      <span itemprop="description">
        <c:out value="${product.description.longDescription}" escapeXml="false"/>
      </span>
    </p>
    <br />

Note that in this example, you are using the long description as a description of the product. You can choose to use the product short description instead.

Defining the itemprop offer

  1. Next, add the itemprop offer, which specifies the price and availability of the product.
  2. To add the itemprop offer from CachedProductOnlyDisplay.jsp, locate the following block of code shown in Listing 7. Add the code highlighted in bold to the JSP.

    Listing 7. Adding offer itemprop to CachedProductOnlyDisplay.jsp
                    
      <%@ include file="CachedProductOnlyImageExt.jspf"%>
    </div>
    
    <span itemprop="offerDetails" itemscope itemtype="http://data-vocabulary.org/Offer">
    <div class="product_options" id="WC_CachedProductOnlyDisplay_div_3">
      <h1 id="catalog_link"  class="catalog_link">
        <span itemprop="name">
          <c:out value="${product.description.name}" escapeXml="false"/>
        </span>
      </h1>
      
      <%-- in Elite, we do not want to show the price because the price may be different 
      depending on the contract that is selected --%>
      <c:if test="${displayListPriceInProductPage == 'true'}">	
       <div id="WC_CachedProductOnlyDisplay_div_4">
        <span class="price bold"><fmt:message key="PRICE" bundle="${storeText}"/></span>
        <c:set var="catalogEntryDB" value="${product}" />
        <c:set var="displayPriceRange" value="true"/>
        <c:set var="priceHighlightable" value="true"/>
        <%@ include file="../../../Snippets/ReusableObjects/
         CatalogEntryPriceDisplay.jspf"%>
       </div>
      </c:if>

  3. To close the span, locate the following block of code shown in Listing 8. Add the code highlighted in bold to the JSP.

    Listing 8. Adding offer itemprop to CachedProductOnlyDisplay.jsp
                    
      <%out.flush();%>
      <c:import url="${jspStoreDir}Snippets/Catalog/CatalogEntryDisplay/
      CatalogEntryInventoryStatus.jsp">
        <c:param name="fromPage" value="${fromPage}"/>
        <c:param name="catalogEntryID" value="${catalogEntryID}"/>
        <c:param name="catentryId" value="${forInventoryCatentryId}"/>
        <c:param name="numberOfSKUs" value="${numberOfSKUs}"/>
      </c:import>
      <%out.flush();%>
      <%@ include file="CatalogEntryInventoryStatusEIExt.jspf"%>
    	
    </div>
    </span>
    <br />

  4. Next, specify the price itemprop for the product. To do so from CatalogEntryPriceDisplay.jspf, locate the following block of code shown in Listing 9. Add the code highlighted in bold to the JSP.

    Listing 9. Adding price itemprop to CatalogEntryPriceDisplay.jspf
                    
      <%-- If the price string has been set, then we simply print it out. --%>
      <c:when test="${!empty priceString}">
        <span itemprop="price">
          <span <c:if test="${not empty priceHighlightable}">id="price"</c:if> 
          class="price bold"><c:out value="${priceString}" escapeXml="false" /></span>
        </span>
      </c:when>
    	
      <%-- If the list price does not exist or is smaller than the offer price, 
      print out both the offer price only. --%>
      <c:when test="${dataBean && (!listPriced || displayPrice.amount 
         <= offerPrice.amount)}">
        <span <c:if test="${not empty priceHighlightable}">id="price"</c:if> 
        class="price bold">
          <span itemprop="price">
            <fmt:formatNumber value="${offerPrice.amount}" type="currency" 
            currencySymbol="${CurrencySymbolToFormat}" 
            maxFractionDigits="${currencyDecimal}"/>
            <c:out value="${CurrencySymbol}"/>
          </span>
        </span>
      </c:when>
    	
      <c:otherwise>
        <span <c:if test="${not empty priceHighlightable}">id="listPrice"</c:if> 
        class="price listPrice bold">
         <fmt:formatNumber value="${displayPrice.amount}" type="currency" 
         currencySymbol="${CurrencySymbolToFormat}" maxFractionDigits=
          "${currencyDecimal}"/>
         <c:out value="${CurrencySymbol}"/>
        </span>
        <div <c:if test="${not empty priceHighlightable}">id="offerPrice"</c:if> 
        class="price offerprice bold">
          <span itemprop="price">
            <fmt:formatNumber value="${offerPrice.amount}" type="currency" 
            currencySymbol="${CurrencySymbolToFormat}" 
            maxFractionDigits="${currencyDecimal}"/>
            <c:out value="${CurrencySymbol}"/>
          </span>
        </div>
      </c:otherwise>
    </c:choose>

  5. To specify the availability itemprop for the product from CatalogEntryInventoryStatus.jsp, locate the following block of code shown in Listing 10. Add the code highlighted in bold to the JSP.

    Listing 10. Adding availability itemprop to CatalogEntryInventoryStatus.jsp
                    
    <c:otherwise>
    
      <c:set var="invStatus" value="NA"/>
      <fmt:message key="INV_INV_NA" bundle="${storeText}" var="invStatusDisplay"/>
    </c:otherwise>
    </c:choose>
    <c:choose>
    	<c:when test="${invStatus == 'Available'}">
    		<c:set var="richSnippetContent" value="in_stock"/>
    	</c:when>
    	<c:otherwise>
    		<c:set var="richSnippetContent" value="out_of_stock"/>
    	</c:otherwise>
    </c:choose>
    <p class="stock_status" id="online_availability_inventory_section_${htmlIdentifier}" 
    style="<c:out value="${defaultDisplayStyle}"/>"><
    img id="onlinestore_inventory_status_image_${htmlIdentifier}" 
    src="${jspStoreImgDir}images/${invStatus}.gif" alt="<c:out 
    value="${invStatusDisplay}"/>" border="0" />&nbsp;<span 
    id="onlinestore_inventory_status_${htmlIdentifier}" 
    itemprop="availability" content="${richSnippetContent}"><c:out 
     value="${invStatusDisplay}"/>
    </span></p>
    
    <flow:ifEnabled feature="StoreLocator">
    <p class="instore_availability" id="instore_availability_message_${htmlIdentifier}" 
    style="<c:out value="${defaultDisplayStyle}"/>">
    <fmt:message key="PRODUCT_INV_STORE" bundle="${storeText}"/></p>
    
    <p class="stock_status" id="store_inv_status_p_0_${htmlIdentifier}" 
     style="display:none">
    <img alt="" border="0" id="store_inv_status_img_0_${htmlIdentifier}"/>
    &nbsp;<a href="#" class="bopis_link" id="store_inv_status_link_0_${htmlIdentifier}">
    </a>&nbsp;<span id="store_inv_status_0_${htmlIdentifier}"></span></p>
    <p class="stock_status" id="store_inv_status_p_1_${htmlIdentifier}" 
     style="display:none">
    <img alt="" border="0" id="store_inv_status_img_1_${htmlIdentifier}"/>
    &nbsp;<a href="#" class="bopis_link" id="store_inv_status_link_1_${htmlIdentifier}">
    </a>&nbsp;<span id="store_inv_status_1_${htmlIdentifier}"></span></p>
    <p class="stock_status" id="store_inv_status_p_2_${htmlIdentifier}" 
     style="display:none">
    <img alt="" border="0" id="store_inv_status_img_2_${htmlIdentifier}"/>
    &nbsp;<a href="#" class="bopis_link" id="store_inv_status_link_2_${htmlIdentifier}">
    </a>&nbsp;<span id="store_inv_status_2_${htmlIdentifier}"></span></p>
    <p class="stock_status" id="store_inv_status_p_3_${htmlIdentifier}" 
     style="display:none">
    <img alt="" border="0" id="store_inv_status_img_3_${htmlIdentifier}"/>
    &nbsp;<a href="#" class="bopis_link" id="store_inv_status_link_3_${htmlIdentifier}">
    </a>&nbsp;<span id="store_inv_status_3_${htmlIdentifier}"></span></p>
    <p class="stock_status" id="store_inv_status_p_4_${htmlIdentifier}" 
     style="display:none">
    <img alt="" border="0" id="store_inv_status_img_4_${htmlIdentifier}"/>
    &nbsp;<a href="#" class="bopis_link" id="store_inv_status_link_4_${htmlIdentifier}">
    </a>&nbsp;<span id="store_inv_status_4_${htmlIdentifier}"></span></p>

Defining the itemprop review

Another important piece of information that you can mark up for rich snippets is the product rating. To do so, a Social Commerce feature has to be installed and enabled, and SocialCommerce.sar must be published on top of the Madisons store. For more information about how to enable this Social Commerce feature, see Enabling and configuring Social Commerce.

  1. To specify the itemprop review for the product, find the Social Commerce EAR folder from your application server. Inside the EAR, find and edit Reviews.html. Locate the block of code shown in Listing 11 and add the code highlighted in bold to the HTML.

    Listing 11. Adding review itemprop to Reviews.html
                    
    <div class="reviewsHeader" >
      <div class="itemContainer" dojoAttachPoint="itemContainer">
       <div class="overallRating" tabindex="0" dojoAttachPoint="overallRatingDisplayDiv">
         <span class="overallRatingLabel">${messages.rating_overallRating}</span>
         <span class="overallRatingStarDisplay" 
             dojoAttachPoint="overallRatingDisplayImg">
            <img dojoAttachPoint="prodRatingStar_1" src="${imagePath}/star_grey.png" 
            alt="star"/>
            <img dojoAttachPoint="prodRatingStar_2" src="${imagePath}/star_grey.png" 
            alt="star"/>
            <img dojoAttachPoint="prodRatingStar_3" src="${imagePath}/star_grey.png" 
            alt="star"/>
            <img dojoAttachPoint="prodRatingStar_4" src="${imagePath}/star_grey.png" 
            alt="star"/>
            <img dojoAttachPoint="prodRatingStar_5" src="${imagePath}/star_grey.png" 
            alt="star"/>
          </span>
          <span itemprop="review" 
          itemscope itemtype="http://data-vocabulary.org/Review-aggregate">
            <span class="overallRatingText"dojoAttachPoint="overallRatingText" ></span>
          </span>
          <br>
        </div>

  2. Next, mark up the rating information. From Reviews.js, locate the block of code shown in Listing 12 and add the code highlighted in bold to the JSP.

    Listing 12. Adding rating itemprop to Reviews.js
                    
    case 9: fractionStar.src = this.imagePath + "/star_full.9.png";
       break;
             
        }
    		 
      }
    	 
      this.overallRatingText.innerHTML = "<span itemprop='rating'>" + 
      overallRatingNum.toFixed(1) + "</span>" + this.messages.rating_overallRating_of; 
    }
    
    else{
      this.overallRatingText.innerHTML = this.messages.rating_overallRating_zero_reviews;
    }

  3. When there is no rating specified, you can show the information by modifying ReviewsNJS.js. Locate the block of code shown in Listing 13 and add the code highlighted in bold to the JSP.

    Listing 13. Adding count itemprop to ReviewsNJS.js
                    
      "rating_overallRating": "Overall Rating : ",
      "rating_overallRating_of": " of 5",
      "rating_overallRating_zero_reviews": "<span itemprop='count'>0</span> reviews",
    	
      "reviewTitleLimitExceeded" : "The title you have entered is too long. The title 
       can be a maximum of {0} characters.",
      "reviewCommentsLimitExceeded" : "The comments you have entered is too long. 
      Comments can be a maximum of {0} characters.",

Now, you are ready to test how your search result snippets. Note that the above examples provide a walkthough on how to mark up the product detail page. If you want to mark up the item, package, and bundle pages, you will need to update the corresponding JSPs for those pages.

3 of 8 | Previous | Next

Comments



Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=753701
TutorialTitle=Implementing rich snippets on your WebSphere Commerce site to improve search engine results
publish-date=08242011
author1-email=nylwan@ca.ibm.com
author1-email-cc=dwu@us.ibm.com

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).