Modifying a store JSP page to use the Commerce Composer Framework

In this lesson, you update the OrderItemDisplay.jsp JSP file to call the Commerce Composer framework service. By calling the Commerce Composer framework, the JSP file uses the Commerce Composer framework service to retrieve the Shopping Cart page design and content.

Within the Commerce Composer framework, a page is a URL, with no content. The content of a page is defined by a 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.

Previously, you used the default provided Two-column with right sidebar template layout template as a base template. You set slot 4 in the template to include your custom ShoppingCartDetailWidget as a predefined widget within the slot. Slot 5 includes the CatalogEntryRecommendationWidget predefined for the slot. The remaining slots for the layout template do not contain any predefined content or widgets.

With your template defined and registered, the Commerce Composer framework layout authoring services enable business users to use the template to create a layout. The layout calls the template to render any included widgets. For more information about layout templates, see Commerce Composer layout template architecture.

Procedure

  1. Open WebSphere Commerce Developer. Switch to the Enterprise Explorer view.
  2. Go to the Stores\WebContent\AuroraStorefrontAssetStore\ShoppingArea\ShopcartSection directory.
  3. Open the OrderItemDisplay.jsp file for editing.
  4. Add the following code to the beginning of the file:
    <%@ taglib uri="http://commerce.ibm.com/pagelayout" prefix="wcpgl" %>
  5. Add the following code after the </head> tag and before the <body> tag:
    
    <wcf:rest var="shopcart" url="store/{storeId}/page">
    <wcf:var name="storeId" value="${storeId}"/>
    <wcf:param name="q" value="byNames"/>
    <wcf:param name="name" value="SampleShoppingCartDetailPage"/>
    <wcf:param name="profileName" value="IBM_Store_Summary"/>		
    </wcf:rest>
    	
    <wcf:rest var="getPageResponse" url="store/{storeId}/page/name/{name}">
    <wcf:var name="storeId" value="${storeId}" encode="true"/>
    <wcf:var name="name" value="SampleShoppingCartDetailPage" encode="true"/>
    <wcf:param name="langId" value="${langId}"/>
    <wcf:param name="profileName" value="IBM_Store_Details"/>
    </wcf:rest>
    <c:set var="page" value="${getPageResponse.resultList[0]}"/>
    
    <wcf:rest var="getPageDesignResponse" url="store/{storeId}/page_design">
    <wcf:var name="storeId" value="${storeId}" encode="true"/>
    <wcf:param name="catalogId" value="${catalogId}"/>
    <wcf:param name="langId" value="${langId}"/>
    <wcf:param name="q" value="byObjectIdentifier"/>
    <wcf:param name="objectIdentifier" value="${page.pageId}"/>
    <wcf:param name="deviceClass" value="${deviceClass}"/>
    <wcf:param name="pageGroup" value="Content"/>
    </wcf:rest>
    <c:set var="pageDesign" value="${getPageDesignResponse.resultList[0]}" scope="request"/>
    <c:set var="PAGE_DESIGN_DETAILS_JSON_VAR" value="pageDesign" scope="request"/>
    
  6. Within the <body> tags, locate the following code:
    
    <%-- This file includes the progressBar mark-up and success/error message display markup --%>
    <%@ include file="../../Common/CommonJSPFToInclude.jspf"%>
    Move the code that you located to before the following code:
    <c:set var="shoppingCartPage" value="true" scope="request"/>
  7. Within the file, locate the following code:
    
    <div id="page" class="nonRWDPage">
    <div id="grayOut"></div>
    <%-- This file includes the progressBar mark-up and success/error message display markup --%>
    <%@ include file="../../Common/CommonJSPFToInclude.jspf"%>
    <!-- Header Widget -->
    <div class="header_wrapper_position" id="headerWidget">
    <%out.flush();%>
    <c:import url = "${env_jspStoreDir}/Widgets/Header/Header.jsp" />
    <%out.flush();%>
    </div>
    
    <script type="text/javascript">
    dojo.addOnLoad(function() {
    CommonControllersDeclarationJS.setControllerURL('ShopCartDisplayController','<c:out value="${ShopCartDisplayViewURL}"/>');
    });
    </script>
    
    <div class="content_wrapper_position" role="main">
    <div class="content_wrapper">
    <div class="content_left_shadow">
    <div class="content_right_shadow">
    <div class="main_content">
    <%out.flush();%>
    <c:import url="/${sdb.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();%>
    <div class="container_content_rightsidebar shop_cart">
    <div class="left_column">
    <flow:ifDisabled feature="AjaxCheckout">
    <form name="ReplaceItemForm" method="post" action="OrderChangeServiceItemDelete" id="ReplaceItemForm">
    <!-- Define all the hidden fields required for submitting this form in case of Non-Ajax Checkout -->
    <input type="hidden" name="storeId" value='<c:out value="${storeId}"/>' id="WC_OrderItemDisplay_inputs_2"/>
    <input type="hidden" name="langId" value='<c:out value="${langId}" />' id="WC_OrderItemDisplay_inputs_3"/>
    <input type="hidden" name="orderId" value='<c:out value="${order.orderId}"/>' id="WC_OrderItemDisplay_inputs_4"/>
    <input type="hidden" name="catalogId" value='<c:out value="${catalogId}"/>' id="WC_OrderItemDisplay_inputs_5"/>
    <input type="hidden" name="errorViewName" value="InvalidInputErrorView" id="WC_OrderItemDisplay_inputs_6"/>
    <input type="hidden" name="orderItemId" value="" id="WC_OrderItemDisplay_inputs_7"/>
    <input type="hidden" name="URL" value="AjaxOrderItemDisplayView" id="WC_OrderItemDisplay_inputs_1"/>
    <input type="hidden" name="calculationUsage" value="-1,-2,-3,-4,-5,-6,-7" id="WC_OrderItemDisplay_inputs_8"/>
    </form>
    </flow:ifDisabled>
    
    <span id="ShopCartDisplay_ACCE_Label" class="spanacce"><fmt:message bundle="${storeText}" key="ACCE_Region_Shopping_Cart_Content"/></span>
    <div dojoType="wc.widget.RefreshArea" widgetId="ShopCartDisplay" id="ShopCartDisplay" controllerId="ShopCartDisplayController" ariaMessage="<fmt:message bundle="${storeText}" key="ACCE_Status_Shopping_Cart_Content_Updated"/>" ariaLiveId="${ariaMessageNode}" role="region" aria-labelledby="ShopCartDisplay_ACCE_Label">
    <%out.flush();%>
    <c:import url="/${sdb.jspStoreDir}/ShoppingArea/ShopcartSection/ShopCartDisplay.jsp"/>
    <%out.flush();%>
    </div>
    <%-- Include after ShopCartDisplay.jsp. ShopCartDisplay.jsp fetches the order details which can be reused in the GiftsPopup dialog --%>
    <%@ include file="../../Snippets/Marketing/Promotions/PromotionChoiceOfFreeGiftsPopup.jspf" %>
    <script type="text/javascript">
    dojo.addOnLoad(function() {
    parseWidget("ShopCartDisplay");
    });
    </script>
    <br/>
    <flow:ifEnabled feature="Analytics">
    <%-- Begin - Added for Coremetrics Intelligent Offer to Display dynamic recommendations for the most recently viewed product --%>
    <%-- Coremetrics Aanlytics is a prerequisite to Coremetrics Intelligent Offer --%>
    
    <div class="item_spacer_5px"></div>
    
    <div class="widget_product_listing_position">
    <%out.flush();%>
    <c:import url="${env_siteWidgetsDir}com.ibm.commerce.store.widgets.IBMProductRecommendations/IBMProductRecommendations.jsp">
    <c:param name="emsName" value="ShoppingCart_ProductRec" />
    <c:param name="widgetOrientation" value="horizontal"/>
    <c:param name="catalogId" value="${WCParam.catalogId}" />
    </c:import>
    <%out.flush();%>
    </div>
    
    <%-- End - Added for Coremetrics Intelligent Offer --%>
    </flow:ifEnabled>
    </div>
    <div class="right_column">
    <!-- Vertical Recommendations Widget -->
    <div class="widget_recommended_position">
    <% out.flush(); %>
    <c:import url="${env_siteWidgetsDir}com.ibm.commerce.store.widgets.CatalogEntryRecommendation/CatalogEntryRecommendation.jsp">
    <c:param name="emsName" value="ShoppingCartRight_CatEntries"/>
    <c:param name="widgetOrientation" value="vertical"/>
    <c:param name="pageSize" value="2"/>
    </c:import>
    <% out.flush(); %>
    </div>
    </div>
    </div>
    </div>
    </div>
    </div>
    </div>
    </div>
    
    <script type="text/javascript">
    dojo.addOnLoad(function() {
    <c:choose>
    <c:when test="${!empty errorMessage && currentOrderLocked eq 'true' && env_shopOnBehalfSessionEstablished ne true}">
    // Current order is locked and this is shopper session. Just display generic error message instead of actual error message.
    require([
    "dojo/html",
    "dojo/_base/lang",
    "dojo/domReady!"], function(html,lang) {
    var msg = storeNLS['ORDER_LOCKED_ERROR_MSG'];
    if(typeof(msg) != 'undefined' && msg != ""){
    MessageHelper.displayErrorMessage(lang.replace(msg, ['${order.orderId}']));
    } else {
    MessageHelper.displayErrorMessage(<wcf:json object="${errorMessage}"/>);
    }
    });
    </c:when>
    <c:when test="${!empty errorMessage}">
    MessageHelper.displayErrorMessage(<wcf:json object="${errorMessage}"/>);
    </c:when>
    </c:choose>
    });
    </script>
    
    
    <!-- Footer Widget -->
    <div class="footer_wrapper_position">
    <%out.flush();%>
    <c:import url = "${env_jspStoreDir}/Widgets/Footer/Footer.jsp" />
    <%out.flush();%>
    </div>
    </div>
    Replace the code that you located with the following code:
    
    <c:set var="layoutPageIdentifier" value="${page.pageId}"/>
    <c:set var="layoutPageName" value="${page.name}"/>
    <%@ include file="/Widgets_701/Common/ESpot/LayoutPreviewSetup.jspf"%>		
    <div id="headerWrapper">
      <%out.flush();%>
      <c:import url = "${env_jspStoreDir}Widgets/Header/Header.jsp" />
      <%out.flush();%>
    </div>	
    <div id="page">
      <c:set var="rootWidget" value="${pageDesign.widget}"/>
      <wcpgl:widgetImport uniqueID="${rootWidget.widgetDefinitionId}" debug=false/>
    </div>
    <div id="footerWrapper">
      <%out.flush();%>
      <c:import url="${env_jspStoreDir}Widgets/Footer/Footer.jsp"/>
      <%out.flush();%>
    </div>
    Note: Use the widgetImport tag to import the container widget for your Shopping Cart page template. The values for the following properties must be set in a standard way before the JSP file calls the widgetImport functionality:
    • layoutPreviewLayoutId
    • Name
    • Default