The ProductSpotlight-ATGCategoryRecommendations
cartridge renders products returned by Oracle Recommendations on Demand for the current category on category pages.
Note: This cartridge should only be used on category pages. If you place it on a browse page, it will not render any content. See Category Pages versus Browse Pages for more details on the differences between the two page types.
Note: The ProductSpotlight-ATGCategoryRecommendations
cartridge provides the rendering mechanism for the products returned by Oracle Recommendations. The Oracle Recommendations integration also includes functionality for page instrumentation and making calls to the Oracle Recommendations engine. This functionality is described in the Oracle Recommendations On Demand Integration chapter. This section assumes you are familiar with the information in that section.
Template
The XML template for the ProductSpotlight-ATGCategoryRecommendations
cartridge, located in <ATG10dir>/CommerceReferenceStore/Store/Storefront/deploy/cartridge_templates/MainContent-ProductSpotlight-ATGCategoryRecommendations.xml
, sets the cartridge’s content type to MainContent
and its ID to ProductSpotlight-ATGCategoryRecommendations
. The XML template defines one editable property, numberOfRecords
, that defines the number of recommendations to show for the current category. By default, numberOfRecords
is set to 4.
Content Item and Handler
The atg.projects.store.assembler.cartridge.CategoryRecommendationsContentItem
class represents the content item that the ProductSpotlight-ATGCategoryRecommendations
cartridge returns to the renderer. The CategoryRecommendationsContentItem
class has two properties:
categoryId
: The ID of the current category.numberOfRecords
: The number of recommended products to be displayed.
The /atg/endeca/assembler/cartridge/handler/CategoryRecommendations
component, which is of class atg.projects.store.assembler.cartridge.handler.CategoryRecommendationsHandler
, is responsible for creating and populating the CategoryRecommendationsContentItem
object. The CategoryRecommendationsHandler
class is an extension of the com.endeca.infront.cartridge.NavigationCartridgeHandler
class.
The CategoryRecommendations
component uses the methods provided by the StoreCartridgeTools
component to get the ID for the current category. The CategoryRecommendations
component then stores this ID, along with the value specified in Experience Manager for the number of records to display, in the CategoryRecommendationsContentItem
object. It is the renderer’s responsibility to take this information stored in the content item, make an appropriate request to the Oracle Recommendations engine, and render the results. The CategoryRecommendations
component has one configurable property, storeCartridgeTools
, which references the StoreCartridgeTools
component that CategoryRecommendations
should use. Out of the box, this property is set to /atg/endeca/assembler/cartridge/StoreCartridgeTools
.
JSP Renderer
The store.war/cartridges/ProductSpotlight-ATGCategoryRecommendations/ProductSpotlight-ATGCategoryRecommendations.jsp
page is the renderer for the ProductSpotlight-ATGCategoryRecommendations
cartridge. This page is responsible for inserting a container <div>
element with content that specifies information about the recommendations to be displayed, including the number of products to show and any products to be excluded from the list of recommendations.
The ProductSpotlight-ATGCategoryRecommendations.jsp
page checks for the existence of the /atg/store/recommendations/StoreRecommendationsConfiguration
component, which is part of the Store.Recommendations
module. If this component is present, it indicates Oracle Recommendations is running, and the ProductSpotlight-ATGCategoryRecommendations.jsp
page should render the <div>
element.
Calculating the Products to Exclude
When creating the <div>
element, the ProductSpotlight-ATGCategoryRecommendations.jsp
page starts with the data stored in the CategoryRecommendationsContentItem
object that indicates the number of products to display and the current category ID. The page must also calculate the list of products to exclude. This functionality is required to avoid showing products in the Recommended Items area that are already displayed elsewhere on the page. There are several other cartridges on a category page that can potentially show products, specifically ProductSpotlight-ATGCategoryRelatedProducts
, HorizontalRecordSpotlight
, and ProductList-ATGCategoryChildren
.
To determine the products to exclude, the ProductSpotlight-ATGCategoryRecommendations.jsp
page invokes the /atg/endeca/assembler/cartridge/CrossCartridgeItemsLookupDroplet
servlet bean. This servlet bean retrieves the root content item object from the current request’s rootContentItem
attribute and passes it to the /atg/endeca/assembler/cartridge/CrossCartridgeItemsLookup
component’s traverse()
method. The traverse()
method returns a list of products that are already being displayed on the page by other cartridges. The renderer then inserts that list into the <div>
element.
The CrossCartridgeItemsLookupDroplet
servlet bean is a request-scoped component of class atg.projects.store.assembler.cartridge.CrossCartridgeItemsLookupDroplet
. It has one property, contentItemTreeIterator
, that specifies the component that should be used to traverse the content item tree to find already-displayed products. This property is set to /atg/endeca/assembler/cartridge/CrossCartridgeItemsLookup
.
The CrossCartridgeItemsLookup
component is of class atg.projects.store.assembler.cartridge.CrossCartridgeItemsLookup
, which is an implementation of the atg.projects.store.assembler.cartridge.ContentItemTreeIterator
abstract class. The ContentItemTreeIterator
abstract class implements a traverse()
method that takes a content item as an input parameter and then traverses that content item, looking for descendent content items. For each content item detected, ContentItemTreeIterator
calls its process()
method. The ContentItemTreeIterator
class is able to detect and handle circular references, terminating content item traversal and throwing an exception when a circular reference occurs.
The CrossCartridgeItemsLookup
class inherits the traversing logic from the ContentItemTreeIterator
abstract class and implements a process()
method that checks whether a content item is of a specified type and, if so, it processes the content item accordingly. The CrossCartridgeItemsLookup
class has two properties that define the content item types to look for:
typeToPropertyNameMap
: A mapping between cartridges that display products and the property names in the associated content items where the displayed products are stored.contentItemsToCache
: A list of cartridges whose associated content items should be cached during content item tree traversing.
If a cartridge’s type is specified in the typeToPropertyNameMap
mapping, the process()
method tries to retrieve the products displayed by the cartridge. Displayed products are retrieved from the property configured in the typeToPropertyNameMap
mapping. It is expected that products are represented either by a product ID, a com.endeca.infront.cartridge.model.Record
object or an atg.repository.RepositoryItem
object. Once all the displayed products are retrieved from the content item hierarchy, their IDs are stored in a single shared displayedItems
property that forms the basis of the items to exclude list.
If a cartridge’s type is specified in the contentItemsToCache
list, the process()
method caches the associated content item into a contentItemCache
map. This caching is required for cartridges whose content items do not directly contain displayed products or product IDs. For example, the content item for the ProductList-ATGCategoryChildren
cartridge contains information about the products to be displayed, such as the ID of the parent category and the number of products to display, but it does not contain any actual product data. In this case, the content item data is cached so that the ProductSpotlight-ATGCategoryRecommendations
cartridge renderer can use it to calculate which product IDs are already being displayed by the ProductList-ATGCategoryChildren
cartridge.
The CrossCartridgeItemsLookup
component is configured as follows:
# Mapping between cartridge type and property name containing products typeToPropertyNameMap=\ ProductSpotlight-ATGCategoryRelatedProducts=relatedProducts,\ HorizontalRecordSpotlight=records # List of IDs for cartridges that do not directly contain product data but instead # contain data that allow the product IDs to be calculated. This information is # cached so that the renderer can use it to calculate which product IDs are # already being displayed. contentItemsToCache=ProductList-ATGCategoryChildren
Rendering the Returned Products
Part of the page instrumentation that occurs for Oracle Recommendations is the insertion in the <head>
element of a call to the Oracle Recommendations JavaScript library:
<script type="text/javascript" src="//static.atgsvcs.com/js/atgsvcs.js"></script>
After the HTML page loads, the atgsvcs.js
script executes and sends the information from the container <div>
about the product recommendations to be returned by the Oracle Recommendations engine (the container <div>
information is sent along with Oracle Recommendations clickstream code; see the Oracle Recommendations On Demand Integration chapter for more details on clickstream code). Oracle Recommendations returns a response containing data about the products to display, and executes JavaScript renderer code that manipulates the DOM of the page to alter the HTML to display the recommendations.
Modifying the Recommended Items Label
The “Recommended Items” label that appears above the product spotlight row in the main content area, along with its translated versions, is stored in the StoreText
repository in the product_spotlight_categoryRelatedProductsTitle
item and may be edited in the Business Control Center.