At the top of each template page, we display historical navigation information by listing the hierarchy of categories that a customer has already visited on his or her way to the current page.

For example, if a customer navigates from the top of the Motorprise catalog to the Air and Fuel category, to the Filters and then Air Filters subcategory pages, and then to the product page for the SUP-2744 air filter, the navigation history (at the top of the page) looks like this:

Each of the items in the hierarchical navigation is a link. For example, if the user clicks on Air and Fuel, she is brought to the category template page for Air and Fuel.

If a customer goes directly from the home page to the product page of the SUP-2744 air filter, (for example, from the featured product on the home page) the historical navigation still reflects the catalog’s hierarchical structure. We wanted the navigation path to be intuitive to the customer and therefore, the historical navigation list reflects the category pages so that the user can have a sense of how this item fits into the catalog. To do this, we invoke the CatalogNavHistoryCollector component with the navAction parameter set to “jump”.

There are two parts to using historical navigation: collecting the information and displaying it.

Collecting the Navigation History

We used the component /atg/commerce/catalog/CatalogNavHistoryCollector to collect the locations visited and to add them to the array of visited locations. In Motorprise, the visited locations are the repository items that represent the products and categories of the product catalog. This snippet, taken from /Motorprise/en/common/breadcrumbs.jsp, invokes the CatalogNavHistoryCollector:

<dsp:droplet name="/atg/dynamo/droplet/Switch">
  <dsp:param name="value" param="no_new_crumb"/>
  <dsp:oparam name="true">
  </dsp:oparam>
  <dsp:oparam name="default">
     <dsp:droplet name="CatalogNavHistoryCollector">
        <dsp:param name="navAction" param="navAction"/>
        <dsp:param name="item" param="element"/>
     </dsp:droplet>
  </dsp:oparam>
</dsp:droplet>

There are two things to note in this code snippet. Although both these techniques are specific to the Motorprise implementation, they can be applied to any site. First, notice that the required parameter navCount is not passed to CatalogNavHistoryCollector. The navCount parameter is set in the page that invokes this snippet. Since JSPs invoked as servlets from other JSPs are in a sub-scope of their callers, they have access to the same parameters as the caller.

Second, we used the no_new_crumb parameter to decide whether to invoke the snippet. This is just a switch on a parameter passed to the page to determine whether to add the current location to the NavHistory or not. However, it demonstrates how we decided to address navigation for pages that do not represent catalog items. For example, the search page, the shopping cart, and the user profile page are not added to the NavHistory like regular catalog pages.

Another use of this parameter includes certain instances in the product catalog where we want users to temporarily leave the catalog, but then return quickly. In such situations we use special implementations of breadcrumbs using the no_new_crumb parameter. For example, when a user adds an item to their current order, the “Checkout” breadcrumb is added to the list allowing a user to quickly return to any part of the catalog. When the user returns to catalog, the “Checkout” value is not part of the breadcrumbs trail.

Displaying the Navigation History

The property /atg/commerce/catalog/CatalogNavHistory.navHistory is a LinkedList of locations. The CatalogNavHistoryCollector populates this list as described in the preceding section. The following snippet from breadcrumbs.jsp demonstrates how the navigation history is displayed in Motorprise. A ForEach component iterates over the NavHistory list and a link is created for each item in the list. Comments in the JSP describe the variations from that behavior.

<%
/* -------------------------------------------------
 * use the ForEach droplet to render the navHistory array.
 * ------------------------------------------------- */
%>
<dsp:droplet name="/atg/dynamo/droplet/Switch">
  <dsp:param name="value" param="displaybreadcrumbs"/>
  <dsp:oparam name="true">

    <dsp:droplet name="/atg/dynamo/droplet/ForEach">
      <dsp:param bean="CatalogNavHistory.navHistory" name="array"/>
      <dsp:param name="elementName" value="crumb"/>
      <dsp:oparam name="output">

        <dsp:droplet name="/atg/dynamo/droplet/Switch">
          <%
          /* -------------------------------------------------
           * We want to put a separator between the items in the navHistory. In
           * this example we put | sign between them.  We use a switch droplet to
           * identify the first item in the array because we don't want to render
           * a separator, but a link to Store Home before the first item.
           * ------------------------------------------------- */
          %>
          <dsp:param name="value" param="count"/>

          <dsp:oparam name="1">
            &nbsp; <dsp:a href="../home.jsp">Product Catalog</dsp:a> &gt;
          </dsp:oparam>

          <dsp:oparam name="default">
            &gt;
          </dsp:oparam>

        </dsp:droplet>

        <dsp:droplet name="/atg/dynamo/droplet/IsNull">
          <dsp:param name="value" param="crumb"/>

          <dsp:oparam name="true">
             element is null
          </dsp:oparam>

          <dsp:oparam name="false">
            <dsp:droplet name="/atg/dynamo/droplet/Switch">
              <%
              /* -------------------------------------------------
               * Use a switch droplet to compare size to count. When
               * they are the same, then we are on the last item in
               * array iterated by the ForEach.
               * ------------------------------------------------- */
              %>
              <dsp:param name="value" param="size"/>

              <dsp:getvalueof id="countParam" idtype="Integer" param="count">
              <dsp:oparam name="<%=countParam.toString()%>">
                <dsp:droplet name="/atg/dynamo/droplet/Switch">
                  <%
                  /* -------------------------------------------------
                   * The last item in the list is generally the item we are
                   * currently visiting and should therefore not be a link.
                   * In some cases, when we do not want to add a new breadcrumb,
                   * we want the last item to be a link.  We do this on the
                   * shopping cart page, search page, and others.  This is
                   * indicated by the "no_new_crumb" parameter.
                   * ------------------------------------------------- */
                  %>
                  <dsp:param name="value" param="no_new_crumb"/>

                  <dsp:oparam name="true">
              <dsp:getvalueof id="urlStr" idtype="java.lang.String" param=
                "crumb.template.url">
                    <dsp:a page="<%=urlStr%>">
                      <dsp:param name="id" param="crumb.repositoryId"/>
                      <dsp:param name="navAction" value="pop"/>
                      <dsp:param name="Item" param="crumb"/>
                      <dsp:valueof param="crumb.displayName">No name</dsp:valueof>
              </dsp:a>
              </dsp:getvalueof>
                  </dsp:oparam>

                  <dsp:oparam name="default">
                    <dsp:valueof param="crumb.displayName"/>
                  </dsp:oparam>
                </dsp:droplet>
              </dsp:oparam>
              </dsp:getvalueof>

              <dsp:oparam name="default">
             <dsp:getvalueof id="urlStr" idtype="java.lang.String" param=
               "crumb.template.url">
                <dsp:a page="<%=urlStr%>">
            <dsp:param name="id" param="crumb.repositoryId"/>
            <dsp:param name="navAction" value="pop"/>
            <dsp:param name="Item" param="crumb"/>
            <dsp:valueof param="crumb.displayName">No name</dsp:valueof>
               </dsp:a>
               </dsp:getvalueof>
              </dsp:oparam>
            </dsp:droplet>

          </dsp:oparam>
        </dsp:droplet>

      </dsp:oparam>
    </dsp:droplet> <%/* end ForEach */%>
  </dsp:oparam>
</dsp:droplet>
Displaying different sets of breadcrumbs

There are certain instances where a user can arrive at a particular page from different navigational contexts. In the code snippet below, taken from cart.jSP, you will notice that the breadcrumbs droplet is enclosed within a switch droplet that examines a parameter called noCrumbs. This switch allows us to display two different sets of breadcrumbs depending on the context of the situation. When a user selects “Add to Order” from the product page, the parameter noCrumbs is passed to the current order page. If the value of noCrumbs is false, then the page is arrived at from the product page and the navigational history from the product catalog is displayed. Otherwise a new breadcrumb is displayed, indicating that “Current Order” was selected.

<dsp:droplet name="Switch">
   <dsp:param name="value" param="noCrumbs"/>
   <dsp:oparam name="false">
      <dsp:include page="../common/breadcrumbs.jsp" flush="true"><dsp:param
         name="displaybreadcrumbs" value="true"/><dsp:param name="no_new_crumb"
         value="true"/></dsp:include> &gt; Checkout
   </dsp:oparam>
   <dsp:oparam name="default">
      <dsp:param name="noCrumbs" value="true"/>
      &nbsp; Current Order
   </dsp:oparam>
</dsp:droplet>

We created a similar implementation for scheduled orders where certain pages are viewed in a number of different contexts.

 
loading table of contents...