The information displayed on the product detail page is driven by product and SKU properties and their values.

This illustration is described in the surrounding text.

While the SearchAndNavigation plugin provides all of the required code and configuration to display product name, description, price, and image for any type of product, the SKU pickers displayed for a product depend on the type of product itself. For example, a clothing product might show options for picking color and size while a furniture product might show options for picking wood finish. Because the SKU pickers on product detail pages are so tightly tied to the underlying data, generic instructions for how to create them cannot be provided. Instead, this section provides an example for you to follow by describing the code and configuration included in the B2CStore module for rendering SKU pickers that are appropriate for its underlying sample data of clothing and furniture products.

Defining SKU Types and Their Properties

To configure SKU pickers for a given site, the product detail page must know:

The B2CStore application module defines two SKU types: clothing-sku and furniture-sku. Two components in the B2CStore module define the SKU properties that are used to create SKU pickers for these two types, /atg/commerce/catalog/sku/properties/ClothingSkuProperties and /atg/commerce/catalog/sku/properties/FurnitureSkuProperties. The properties files for these components are shown below.

ClothingSkuProperties

$class=atg.projects.store.sku.SkuTypeProperties
$scope=global
$description=Properties component used to define clothing SKU-related properties
allowing the property names to be configured in component property files.

# This is a list of properties that are used for building a SKU picker for this
# SKU type.
skuPropertyList=\
  color,\
  size

FurnitureSkuProperties

$class=atg.projects.store.sku.SkuTypeProperties
$scope=global
$description=Properties component used to define furniture SKU-related properties
allowing the property names to be configured in component property files.

# This is a list of properties that are used for building a SKU picker for this
# SKU type.
skuPropertyList=\
  woodFinish

Both components are of class atg.projects.store.sku.SkuTypeProperties, which is included in the SearchAndNavigation plugin. This class contains a single property, skuPropertyList, that defines the SKU properties that should be used to create pickers for the associated SKU type. In the case of B2CStore, color and size properties are used to create SKU pickers for clothing SKUs while the woodFinish property is used to create a SKU picker for furniture SKUs.

Informing the ProductDetails Cartridge Handler of the SKU Types

The content item that Experience Manager returns for the product detail page contains all of the information required for the initial page load including all of the product’s properties, the skuTypes that the page must handle, and the SKU properties that are used to build the SKU pickers for the individual skuTypes. The cartridge handler for the product detail page, namely the /atg/endeca/assembler/cartridge/handler/ProductDetails component, uses its skuTypes property to map each SKU type to the list of SKU properties that should be used to create a picker for that type. For example, in the B2CStore, the skuTypes property maps the clothing-sku to the properties list defined by /atg/commerce/catalog/sku/properties/ClothingSkuProperties.skuPropertyList and the furniture-sku to the properties list defined in /atg/commerce/catalog/sku/properties/FurnitureSkuProperties.skuPropertyList.

# Resolving Map that holds a map of the SKU types that will be served and any
# unique properties that will be used for their corresponding SKU pickers.
# The key for this map should be the identifier for the SKU type.
skuTypes=\
  clothing-sku^=/atg/commerce/catalog/sku/properties/\
                ClothingSkuProperties.skuPropertyList,\
  furniture-sku^=/atg/commerce/catalog/sku/properties/\
                FurnitureSkuProperties.skuPropertyList

By including this configuration, additional SKU information is added to the content item to facilitate the rendering of the SKU pickers, namely childSkuType and childSkuPickerProperties.

"mainProductContent": [
{
  "metadata": {
  "keywords": "silk,dry,suede,buttons,newest,clean,blazer,fall,town,leather,",
  "description": "Greet fall with our newest suede blazer. Dry clean only.",
  "title": "CSA Store - Suede Blazer"
},
"product": {
  "longDescription": "Greet fall with our newest suede blazer. Dry clean only.",
  "isAvailable": true,
  "salePrice": "84.0 - 99.0",
  "displayName": "Suede Blazer",
  "largeImageUrl":
     "/csadocroot/content/images/products/large/APP_SuedeBlazer_large.jpg",
  "repositoryId": "xprod2504",
  "childSkuType": "clothing-sku",
  "showSalePrice": false,
  "childSkuPickerProperties": [
    "color",
    "size"
  ],
  "listPrice": "84.0 - 99.0"
},

Note: The clothing-sku and furniture-sku types map to item-descriptors that are defined in the B2CStore repository extensions.

Sku Picker Dependencies on B2CStore.Base Plugin Extensions

The SKU pickers described in the previous section also rely on some extensions made in the B2CStore.Base module.

atg.projects.store.catalog.B2CStoreCatalogProperties

This class is an extension of the atg.projects.store.catalog.StoreCatalogProperties class included in the Commerce Store Accelerator Base module and it adds a new catalog property called sizePropertyName and sets its value to size. Instead of directly referencing the size property by name, other components use the getSizePropertyName() method. This allows you to change the name of the size property in one location, if necessary, without having to modify other code that uses the size property. The /atg/commerce/catalog/custom/CatalogProperties component in the B2CStore.Base module is configured to use the B2CstoreCatalogProperties class, thereby making the size property available to other components.

atg.projects.store.catalog.B2CstoreCatalogTools

This class is an extension of the atg.projects.store.catalog.StoreCatalogTools class included in the Commerce Store Accelerator Base module and it provides the CatalogTools component with a number of additional methods for sorting lists of colors and sizes. The /atg/commerce/catalog/CatalogTools component in the B2CStore.Base module is configured to use this class. The component also defines the sizeSortOrder property, which specifes the order in which lists of sizes should be presented. For B2CStore, this order is:

sizeSortOrder=One Size,
Small,Large,XS,S,M,L,XL,XXL,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42

Sorting for colors is done alphabetically.

Creating the SKU Pickers

The process used to determine a SKU based on selections made in a SKU picker is application-specific and is not included in the SearchAndNavigation plugin out of the box. The role of a SKU picker is twofold. First, the SKU picker is used to return a list of all available options for any child SKUs that exist for the product being rendered on the product detail page. This information is included in the content item returned for the request along with the rest of the product and SKU information. Secondly, the SKU picker responds to changes to the selected options on the client and, using the available information, attemps to find the matching SKU and return it back to the client. Several additional classes have been created in the B2CStore.Plugins.SearchAndNavigation module to provide this functionality.

Based on the B2CStore catalog, the minimum number of SKU pickers that could be present on the product detail page is 0, for a single SKU product, while the maximum is two, for a clothing SKU that has both color and size pickers. To accommodate this situation, the following classes were created:

The B2CStore.Plugins.SearchAndNavigation module configures a set of SKU picker components using these classes.

ColorSkuPicker Component

The /atg/commerce/product/detail/ColorSkuPicker component defined in the B2CStore.Plugins.SearchAndNavigation module is of class atg.projects.store.sku.picker.ColorSkuPicker. The configuration for this component is shown below:

$class=atg.projects.store.sku.picker.ColorSkuPicker
$scope=prototype
$description=A component used to to control the behaviour of a SKU picker that
contains color options.

# Instance of Catalog Tools.
catalogTools=/atg/commerce/catalog/CatalogTools

# Instance of ProductDetailTools.
productDetailsTools=/atg/commerce/product/detail/ProductDetailsTools

# Instance of skuPickerPropertyManager.
skuPickerPropertyManager=/atg/commerce/product/detail/SkuPickerPropertyManager

The ColorSkuPicker component also contains three additional properties, which are not configured here because appropriate defaults are specified for them in the class itself. These properties represent the keys that are used to identify the color property, the selected color, and the available colors in the Map that is returned from the server when a picker change is made on the client:

These properties do not need to be adjusted if you are configuring a SKU picker for use with colors but they can be overriden to work with a different SKU property (for example, a wood finish property), as described in the next section.

WoodFinishSkuPicker Component

Furniture SKUs in the B2CStore catalog can have a maximum of one SKU picker for selecting the furniture’s wood finish. The /atg/commerce/product/detail/WoodFinishSkuPicker component defined in the B2CStore.Plugins.SearchAndNavigation module is of class atg.projects.store.sku.picker.ColorSkuPicker and its configuration is shown below:

$class=atg.projects.store.sku.picker.ColorSkuPicker
$description=A component used to control the behaviour of a SKU picker that
contains wood finish options.
# Base this component on the ColorProductDetailsPicker component as they share
# similar properties.
$basedOn=ColorSkuPicker

# Override the color-related properties in order to make this picker target
# the wood finish-related properties.
colorPropertyName=woodFinish
selectedColorPropertyName=selectedWoodFinish
availableColorsPropertyName=availableWoodFinishes

The WoodFinishSkuPicker extends the ColorSkuPicker component and inherits all of that component’s properties. However, the WoodFinishSkuPicker overrides the default values of colorPropertyName, selectedColorPropertyName, and availableColorsPropertyName to reflect the fact that this SKU picker works with wood finish-related SKU properties instead. Specifically, it sets colorPropertyName to woodFinish, selectedColorPropertyNames to selectedWoodFinish, and availableColorsPropertyName to availableWoodFinishes.

SizeColorSkuPicker Component

Like the WoodFinishSkuPicker, the SizeColorSkuPicker component extends the ColorSkuPicker. Its configuration is shown below:

$class=atg.projects.store.sku.picker.SizeColorSkuPicker
$description=A component used to to control the behaviour of a SKU picker with
size and color options.

# Base this component on the ColorSkuPicker component as they share similar
# properties.
$basedOn=ColorSkuPicker

# Add 'One Size' (and its translations) to the helper property black list.
helperPropertyBlackList=\
  One Size

While the SizeColorSkuPicker component is based on the ColorSkuPicker component, it does override the $class property to use atg.projects.store.sku.picker.SizeColorSkuPicker instead. This class adds a number of additional properties that have defaults specified in the class definition. These properties represent the keys that are used to identify the size property, the selected size, and the available sizes in the Map that is returned from the server when a picker change is made on the client:

As with the ColorSkuPicker, these properties do not have to be set if the SKU picker being selected has color and size properties. They can, however, be modified if required as demonstrated with the WoodFinishPicker in the previous section. Some attention must be paid, however, if using this picker for other SKU types as some unexpected sorting can happen unless it is managed properly in the class methods.

The helperPropertyBlackList property controls the display of the size chart hyperlink, which should be suppressed if a product only has only one size. This property ensures that a size chart link is not displayed for a product if the property values listed in the black list are the only values available to the picker. In other words, if One Size is the only value available to the picker, do not display the size chart link.

Encapsulating the SKU Pickers and Controlling Access to Them

After the different types of SKU pickers required by the site are defined, they need a container to encapsulate them and control access to them. The /atg/commerce/product/detail/SkuPickers component included in the B2CStore.Plugins.SearchAndNavigation module fulfills these requirements. The SkuPickers component encapsulates the SKU pickers in two different maps, shown below:

# Service map containing each of the available SKU pickers. These are keyed by
# the unique SKU property name that a SKU picker would be generated for, for
# example "color" for a clothing-sku.
skuPickerMap=\
  color=/atg/commerce/product/detail/ColorSkuPicker,\
  size=/atg/commerce/product/detail/SizeColorSkuPicker,\
  woodFinish=/atg/commerce/product/detail/WoodFinishSkuPicker

# Service map that maps a SKU type to a particular product picker. Used to
# retrieve the correct SKU picker when a REST call is made from the client.
skuTypeToSkuPickerMap=\
  clothing-sku=/atg/commerce/product/detail/SizeColorSkuPicker,\
  furniture-sku=/atg/commerce/product/detail/WoodFinishSkuPicker

The skuTypeToSkuPickerMap is keyed on the SKU item-descriptor which, in the case of B2CStore, is clothing-sku or furniture-sku. The map is used to identify which SKU picker should be used to find a matching SKU for the passed SKU property value(s). The SKU property values are passed through a REST request whenever a change is made to a SKU picker on the product detail page in the browser.

The skuPickerMap is keyed on a SKU property which should match one of the properties defined in the skuPropertyList of either the /atg/commerce/catalog/sku/properties/ClothingSkuProperties or /atg/commerce/catalog/sku/properties/FurnitureSkuProperties components. This map is used by the SkuSelector component, described below, to retrieve the correct SKU picker to use for generating a list of all available options for the passed SKU property, for example, a list of all colors associated with the color SKU property.

SkuSelector Cartridge Handler

While the /atg/endeca/assembler/cartridge/handler/ProductDetails cartridge handler handles the addition of product (and some SKU) properties to the content item returned by the server, it does not include the construction of data objects required for building and rendering SKU pickers on the product detail page. This task is handled by the /atg/endeca/assembler/cartridge/handler/SkuSelector component. This component is of class atg.projects.store.assembler.cartridge.handler.SkuSelectorHandler, which is a class included in the SearchAndNavigation plugin out of the box. The component itself, however, must be configured in the application module. The configuration included in the B2CStore module is shown below:

$class=atg.projects.store.assembler.cartridge.handler.SkuSelectorHandler
$description=Store-specific version of the product details handler.
$scope=prototype

# Import properties.
$basedOn=/atg/endeca/assembler/cartridge/handler/ProductDetails

# Instance of SKU Picker Property Manager.
skuPickerPropertyManager=/atg/commerce/product/detail/SkuPickerPropertyManager

# Instance of SkuPickers which contains the service map that holds the
# different sku pickers that are available.
skuPickers=/atg/commerce/product/detail/SkuPickers

# Remove any configured Content Item Modifiers.
contentItemModifiers^=/Constants.NULL

The SkuSelectorHandler class is an extension of the atg.projects.store.assembler.cartridge.handler.ProductDetailsHandler class. Also, the SkuSelector component as configured in B2CStore is based on the ProductDetails component and inherits all of that component’s configuration. The portion of the configuration that the SkuSelector component overrides is:

The SkuSelectorHandler component builds the SKU picker data objects and adds them to the ProductInformation content item list in the content item returned by the server for the product details page. An example of this data is shown below:

"ProductInformation": [
  {
    "endeca:auditInfo": {
    "ecr:resourcePath": "/content/Web/Product Detail Pages/Default Product Detail
        Page",
    "ecr:innerPath": "mainProductContent[0]/ProductInformation[0]"
  },
  "name": "SKU Selector",
  "metadata": {
    "keywords": "silk,dry,suede,buttons,newest,clean,blazer,fall,town,leather,",
    "description": "Greet fall with our newest suede blazer. Dry clean only.",
    "title": "CSA Store - Suede Blazer"
  },
  "@type": "SkuSelector",
  "skuPickers": [
    {
      "options": [
        "Black",
        "Blue",
        "Olive"
      ],
      "type": "color",
      "value": null
    },
    {
      "options": [
        "S",
        "M",
        "L",
        "XL",
        "XXL"
      ],
      "helperInformation": {
        "type": "sizeChart",
        "contentUrl": "SizeChart.html"
      },
      "type": "size",
      "value": null
    }
  ]
},

In the example above, you can see a skuPickers array that has been created for a clothing-sku that has both color and size options. The skuPickers array contains two objects, each representing a SKU picker, one for color and one for size. Each SKU picker object contains a list of available options as well as the SKU picker type and the currently selected value. In this case, the value is set to null because no option has been selected. In cases where only a single option exists for the picker, the value property is set to that single option.

Also seen in this example is the addition of the size chart information included in the helperInformation object of the size SKU picker. This portion of the data structure defines that the size chart will only appear for the size picker.

Configuring Helper Information

Helper information can come in many forms. The example included in the B2CStore is a link to a size chart for the shopper to reference while choosing clothing products. While the size chart itself is found in an HTML file, ensuring that it is included for rendering within the correct SKU picker is configured using the /atg/commerce/product/detail/ProductDetailsPropertyManager component in the B2CStore.Plugins.SearchAndNavigation module.

$description=Properties component used to define product detail related properties
allowing the property names to be configured in component property files.

# ResolvingMap keyed by the SKU properties that, if present in a product's child
# SKUs, will trigger the inclusion of additional information in the response to
# the Product Detail Page. In this case, when there is a size property present
# the URL for the size chart will be made available to the modal window.
additionalInformationProperties+=\
  size^=/atg/commerce/catalog/custom/SizeChart.additionalInformationMap

In this example, the additionalInformationProperties map is populated with an entry for the size property. This entry maps to the additionalInformationMap property of the /atg/commerce/catalog/custom/SizeChart component, shown below:

$class=atg.projects.store.product.detail.AdditionalInformationProperty
$scope=global
$description=Properties component used to define size chart related properties,
allowing the property names to be configured in component property files.

# Map containing the information required for including the Size Chart on the
# Product Detail Page.
additionalInformationMap+=\
  type=sizeChart,\
  contentUrl=SizeChart.html

The SizeChart component is based on the atg.projects.store.product.detail.AdditionalInformationProperty class and contains a single property called additionalInformationMap that has been populated with two entries:

REST Object Examples

The following examples show what the REST objects look like as requests are being sent to the server and responses are sent back to the client.

// Object sent to server when Black/S are selected for a Suede Jacket
{
  "selectedColor": "Black",
  "selectedSize": "S",
  "productIdPropertyName": "xprod2504",
  "type": "clothing-sku"
}

// Object containing matching SKU received from server
{
  "selectedSku": {
    "showSalePrice": false,
    "type": "clothing-sku",
    "repositoryId": "xsku2504_4",
    "isAvailable": true,
    "size": "S",
    "id": "xsku2504_4",
    "color": "Black",
    "listPrice": 84,
    "displayName": "Suede Blazer",
    "inStock": true
  }
}

Copyright © 1997, 2016 Oracle and/or its affiliates. All rights reserved. Legal Notices