WebSphere Commerce DeveloperFeature Pack 7 or later

Updating a Deprecated featureMadisons store catalog page to use Commerce Composer

In this lesson, you update the JSP files for your starter store catalog pages to use the Commerce Composer framework. You are also updating the JavaScript and CSS files for the catalog pages. By updating these files, you ensure that the style and all of the functionality of your catalog pages work correctly with a Commerce Composer page layout.

About this task

Before your store pages can use the Commerce Composer layout templates and widgets that your store subscribes to, you must modify your existing JSP pages to use the Commerce Composer framework. By updating your JSP pages to use the Commerce Composer framework, the pages can retrieve the appropriate page design and content to render the store pages.

As an example, this tutorial uses the Deprecated featureMadisons store Product Display page JSP file as the model for updating JSP pages to use the Commerce Composer framework. To view the existing Product Display page, open the Madisons store in a web browser. Browse to a store category and find a product. Select the product to view the Product Display page, which can resemble the following image.

Product Details page before Commerce Composer support.

If you right-click the page and select to view the source code for the page, you can identify the JSP file that the page uses. TheProduct Display page uses the ProductDisplay.jsp JSP file.

Within the Commerce Composer framework, a page is a URL, with no content. The content of a page is defined by the page layout when the layout is assigned to the page. A layout is a layout template that has widgets, which are included within the layout template slots. The widgets are used to add the content for the page.

The following steps modify a store page JSP file to follow the structure of a page that the Commerce Composer framework expects. Your modified JSP page no longer defines any content for display. The content is determined when a layout is assigned to your modified page with Commerce Composer tool. If no layout is assigned, your modified page uses the default layout that you subscribed your store to use in an earlier task.

Procedure

  1. Modify the display JSP file for your store page to use the GetPageDesign service that retrieves Commerce Composer assets for rendering your store page.
    1. Open WebSphere Commerce Developer and switch to the Enterprise Explorer view.
    2. Go to the Stores\WebContent\Madisons\ShoppingArea\CatalogSection\CatalogEntrySubsection directory. This directory includes the JSP file for the Product Details page for your Madisons store.
    3. Open the ProductDisplay.jsp file for editing to update the file to define the use of the GetPageDesign service. The service calls the Commerce Composer framework to retrieve the appropriate layout data for your store page. As a reference for updating the page, you can review the ProductDisplay.jsp file within the Aurora starter store archive that you extracted.
    4. Add the following code into the end of the header section of the file. This code indicates that the JSP file must include the specified "pageDesign" JavaScript. This code is required for all pages that use the Commerce Composer framework to determine the design and content to display on the page.
      <wcpgl:jsInclude varPageDesignDetails="pageDesign"/>
    5. Add the following sample code before the HTML section of the file. This code defines how to obtain product details and Commerce Composer widget data for the page.
      <%@include file="../../../Common/EnvironmentSetup.jspf" %>
      <c:if test="${!empty productId}">
      <%-- Since this is a product page, get all the details about this product and save it in internal cache, 
           so that other components can use it... 
      --%>
        <wcf:rest var="catalogNavigationView" url="${searchHostNamePath}${searchContextPath}/store/${WCParam.storeId}/productview/byId/${productId}" >
          <wcf:param name="langId" value="${langId}"/>
          <wcf:param name="currency" value="${env_currencyCode}"/>
          <wcf:param name="responseFormat" value="json"/>
          <wcf:param name="catalogId" value="${WCParam.catalogId}"/>
        </wcf:rest>
        <wcf:getData type="com.ibm.commerce.catalog.facade.datatypes.CatalogNavigationViewType" 
         var="catalogNavigationViewBOD" expressionBuilder="getCatalogEntryViewSummaryByID" 
         varShowVerb="showCatalogNavigationView" maxItems="1" recordSetStartNumber="0">
          <wcf:param name="accessProfile" value="IBM_Store_Summary_SEO"/>
          <wcf:param name="searchProfile" value=""/>
          <wcf:param name="UniqueID" value="${productId}"/>
          <wcf:contextData name="storeId" data="${storeId}" />
          <wcf:contextData name="catalogId" data="${catalogId}" />
        </wcf:getData>
        
        <%-- Cache it in our internal hash map --%>
        <c:set var="key1" value="${productId}+getCatalogEntryViewAllByID"/>
        <wcf:set target = "${cachedCatalogEntryDetailsMap}" key="${key1}" value="${catalogNavigationView.catalogEntryView[0]}"/>
        <c:if test="${!empty catalogNavigationView && !empty catalogNavigationView.catalogEntryView[0]}">
          <c:set var="catalogEntryDetails" value="${catalogNavigationView.catalogEntryView[0]}"/>
        </c:if>
        <c:set var="parentCatEntryId" value="${catalogNavigationView.catalogEntryView[0].parentCatalogEntryID}" scope="request"/>
        <%-- If parentCateEntryId is not empty, then this is an item and not a product --%>
        <c:if test="${not empty parentCatEntryId}">
          <%-- Since this is an item, get all the details about the parent product and save it in internal cache, 
               so that other components can use it... --%>
          <wcf:rest var="parentCatalogNavigationView" 
           url="${searchHostNamePath}${searchContextPath}/store/${WCParam.storeId}/productview/byId/${parentCatEntryId}" >
          <wcf:param name="langId" value="${WCParam.langId}"/>
          <wcf:param name="currency" value="${env_currencyCode}"/>
          <wcf:param name="responseFormat" value="json"/>
          <wcf:param name="catalogId" value="${WCParam.catalogId}"/>
          </wcf:rest>
          <%-- Check if the parent is a product and not package or bundle --%>
          <c:if test="${parentCatalogNavigationView.catalogEntryView[0].catalogEntryTypeCode eq 'ProductBean'}">
            <%-- Keep all the defining attributes and its value in WCParam so that it will be selected by default --%>
            <c:forEach var="attribute" items="${catalogNavigationView.catalogEntryView[0].attributes}">
              <c:if test="${attribute.usage eq 'Defining'}">
                <c:set target="${WCParam}" property="${attribute.name}" value="${attribute.values[0].value}"/>
              </c:if>
            </c:forEach>
            <%-- So that the parent page can be displayed instead of item page and pre select the values correspoding to the item --%>
            <c:set var="catalogNavigationView" value="${parentCatalogNavigationView}" />
            <c:set var="productId" value="${parentCatEntryId}" scope="request"/>
            <c:set var="catalogEntryDetails" value="${catalogNavigationView.catalogEntryView[0]}"/>
            <%-- Cache parent catalog entry in our internal hash map --%>
            <c:set var="key1" value="${productId}+getCatalogEntryViewAllByID"/>
            <wcf:set target = "${cachedCatalogEntryDetailsMap}" key="${key1}" value="${catalogNavigationView.catalogEntryView[0]}"/>
          </c:if>
        </c:if>
      </c:if>
      
      <c:set var="type" value="${fn:toLowerCase(catalogEntryDetails.catalogEntryTypeCode)}" />
      <c:set var="type" value="${fn:replace(type,'bean','')}" />
      <c:choose>
        <c:when test="${type == 'item'}">
          <c:set var="pageGroup" value="Item" scope="request"/>
        </c:when>
        <c:otherwise>
          <c:set var="pageGroup" value="Product" scope="request"/>
        </c:otherwise>
      </c:choose>
      <wcf:getData type="com.ibm.commerce.pagelayout.facade.datatypes.PageDesignType" var="pageDesign" scope="request" expressionBuilder="getPageDesign">
        <wcf:contextData name="storeId" data="${storeId}" />
        <wcf:contextData name="catalogId" data="${catalogId}" />
        <wcf:param name="deviceClass" value="Web"/>
        <wcf:param name="pageGroup" value="${pageGroup}"/>
        <wcf:param name="ObjectIdentifier" value="${productId}"/>
        
        <%--
          <c:forEach var="aParam" items="${WCParamValues}">
            <c:forEach var="aValue" items="${aParam.value}">
              <wcf:param name="${aParam.key}" value="${aValue}"/>
            </c:forEach>
          </c:forEach>
        --%>
      </wcf:getData>
      <c:set var="PAGE_DESIGN_DETAILS_VAR" value="pageDesign" scope="request"/>
      
    6. Update the file to use a Commerce Composer layout that a business user assigns to the page instead of the CachedProductOnlyDisplay.jsp file for rendering the page.
      Locate and remove the following code that uses the CachedProductOnlyDisplay.jsp file:
      <%out.flush();%>
        <c:import url="${jspStoreDir}Snippets/Catalog/CatalogEntryDisplay/CachedProductOnlyDisplay.jsp">
          <c:param name="storeId" value="${WCParam.storeId}"/>
          <c:param name="catalogId" value="${WCParam.catalogId}"/>
          <c:param name="langId" value="${langId}"/>
          <c:param name="productId" value="${productId}"/>
        </c:import>
      <%out.flush();%>
      Add the following code between the definition of the page header and footer sections. This code indicates where on your store page, the Commerce Composer framework inserts the content of the Commerce Composer layout that is assigned to the page.
      <c:set var="rootWidget" value="${pageDesign.widget}"/>
      <wcpgl:widgetImport uniqueID="${rootWidget.widgetDefinitionIdentifier.uniqueID}" debug=false/>
      
    7. Add the following code within the Div element for the page and before the Div element for the content_wrapper_box. This code adds support for previewing the page with store preview.
      <%@ include file="/Widgets/Common/ESpot/LayoutPreviewSetup.jspf"%>
    8. Add caching support for your store page JSP file.
      Add the following code to the end of the <body> element before the end tag for the element:
      <wcpgl:pageLayoutCache pageLayoutId="${pageDesign.layoutID}"/>
      For more information, see Commerce Composer layout caching and invalidation.
    9. Save and close the file.
  2. Add the store environment setup JSP fragments for the Aurora starter store to your store directory structure.
    1. In a file manager, go to the tempAuroraDir\StoreAssetsDir\Common directory, where tempAuroraDir is the temporary directory where you extracted the Aurora.sar archive.
    2. Copy the EnvironmentSetup.jspf and JSTLEnvironmentSetup.jspf files.
    3. Go to the corresponding directory for your store, workspace_dir\Stores\WebContent\Madisons\Common. If the Common folder does not exist for your store directory, create this folder.
    4. Add the copied files into the Common folder for your store.
    5. In the Enterprise Explorer view, browse to the Common directory for your store. Open the EnvironmentSetup.jspf file for editing.
    6. Remove any include statements in this file and remove any references to the SterlingConfiguratorIntegrationSetup.jspf file.
    7. Save and close the file.
    8. Browse to the workspace_dir\Stores\WebContent\store\include directory for your store. Open the EnvironmentSetup.jspf file for editing.
    9. Remove any inNonSSLAcceleratorPort and inSSLAcceleratorPort setup references to avoid potential conflicts with the JSTLEnvironmentSetup.jspf file that you copied from the Aurora.sar archive.
    10. Save and close the file.
  3. Refresh the Product Display page for your Madisons store to view the changes to your page. Your updated page can resemble the following image:

    Product Details page with partial support.

    Observation results
    • If your Product Details page launches successfully, your store page now uses the GetPageDesign service to calls the Commerce Composer framework to retrieve a page layout. If you view the page with a browser debugging tool, you can confirm that the page now uses the GetPageDesign service instead of the CachedProductOnlyDisplay.jsp file to retrieve a page design.

      GetPageDesign service in debugging tool.

    • Your page can have content and functionality removed. For instance, the Add to Compare and Add to Wishlist functions can be removed for your Madisons store page. These functions are disabled when you migrate your page to use the code that you copied from your extracted Aurora starter store archive. The Add to Compare function is included within the Catalog Entry List widget, which you can include on Search results and Category pages. The Add to Wishlist function is included within the Shopper Actions widget, which you can include on Catalog Entry pages, such as your Product Details page. To add the Add to Wishlist function, you must first enable the Enable wish lists store function in the Store Management tool.
    • The content for the page can also display incorrectly. To improve the display of the page content, you must update your page JavaScript dependencies and CSS files. By viewing the errors for your page with a browser debugging tool, you can see the missing JavaScript files and errors for your page, as shown in the following image.

      Product Details page with JavaScript errors.

      The steps for updating the page JavaScript dependencies and CSS are provided in the following lesson.
    • By using the Commerce Composer widgets, you can create a cleaner organization of code. By reviewing your page with your debugging tool, you can identify the references to other JSP files and JSP fragments that define functionality or content. For instance, the following JSP files and fragments can be removed from the Product Details page and replaced with Commerce Composer widgets.
      • LeftSidebarDisplay.jspf
      • RightSidebarDisplay.jspf
      • BreadCrumbTrailDisplay.jsp
  4. Remove the references to the JSP files or JSP fragments that define content that a Commerce Composer widget already provides.
    1. Go to the Stores\WebContent\Madisons\include directory.
    2. Open the LayoutContainerTop.jspf file for editing.
    3. Remove any references to the LeftSidebarDisplay.jspf file.
    4. Open the LayoutContainerBottom.jspf file for editing.
    5. Remove any references to the RightSidebarDisplay.jspf file.
    6. Open the HeaderDisplay.jspf file for editing.
    7. Remove the following code from the file:
      <%out.flush();%>
        <c:import url="${jspStoreDir}include/BreadCrumbTrailDisplay.jsp">
          <c:param name="topCategoryPage" value="${requestScope.topCategoryPage}" />
          <c:param name="categoryPage" value="${requestScope.categoryPage}" />
          <c:param name="productPage" value="${requestScope.productPage}" />
          <c:param name="shoppingCartPage" value="${requestScope.shoppingCartPage}" />
          <c:param name="compareProductPage" value="${requestScope.compareProductPage}" />
          <c:param name="finalBreadcrumb" value="${requestScope.finalBreadcrumb}" />
          <c:param name="extensionPageWithBCF" value="${requestScope.extensionPageWithBCF}" />
          <c:param name="hasBreadCrumbTrail" value="${requestScope.hasBreadCrumbTrail}" />
          <c:param name="requestURIPath" value="${requestScope.requestURIPath}" />
          <c:param name="SavedOrderListPage" value="${requestScope.SavedOrderListPage}" />
          <c:param name="pendingOrderDetailsPage" value="${requestScope.pendingOrderDetailsPage}" />
          <c:param name="sharedWishList" value="${requestScope.sharedWishList}" />
          <c:param name="searchPage" value="${requestScope.searchPage}"/>
        </c:import>
      <%out.flush();%> 
      
    8. Save and close the files.
  5. Refresh the Product Display page for your Madisons store again to view the changes to your page. Your updated page can resemble the following image:

    Product Details page with functionality removed.

    The content that is provided by the LeftSidebarDisplay.jspf, RightSidebarDisplay.jspf, and BreadCrumbTrailDisplay.jsp files are removed from the page. The JavaScript errors, however can still display. You resolve these errors in the following lesson.

  6. Update the Madisons starter store ProductDisplay.jsp to include the code from the Aurora starter store ProductDisplay.jsp file that defines the handling of information for entitled items. This code defines information for supporting full image paths, angle image paths, and attribute data for entitled items.
    1. In a file manager, go to the tempAuroraDir\StoreAssetsDir\ShoppingArea\CatalogSection\CatalogEntrySubsection directory.
    2. Open the ProductDisplay.jsp for editing.
    3. Copy the code within the div element that includes the attribute id=entitledItem_attribute.
    4. In the Enterprise Explorer view, go to the corresponding directory for your store, Stores\WebContent\store\ShoppingArea\CatalogSection\CatalogEntrySubsection
    5. Open the ProductDisplay.jsp for editing.
    6. Add the code into the body element of the file before the div element for the page.
    7. Save and close the file.