CRS uses the atg.repository.seo.BrowserTyperDroplet
servlet bean to determine if a site visitor is a web spider. CRS includes a component of this class, /atg/repository/seo/BrowserTyperDroplet
, whose browserTypes
property is set to robot
. The servlet bean examines the current request, and if it determines that the source of the request is a robot or spider, it sets its browserType
output parameter to robot
; otherwise it sets it to other
. The value of this parameter is passed to an atg.repository.seo.ItemLink
servlet bean, which renders either a static link (if the value is robot
) or a dynamic link (if it isn’t).
Each ItemLink
component is configured with an itemDescriptorNameToMapperMap
property, which is a mapping of template mappers to repository item types. The template mappers themselves have a templates
property that is a list of URL templates.
Commerce Reference Store includes two ItemLink
components, CatalogItemLink
and ProductLookupItemLink
, and their associated template mapper and template components. All of these components are found in the /atg/repository/seo/
Nucleus folder.
CatalogItemLink
The CatalogItemLink
component is the main instance of the ItemLink
servlet bean used by CRS. This component is configured as follows:
itemDescriptorNameToMapperMap=\ product=/atg/repository/seo/ProductTemplateMapper,\ category=/atg/repository/seo/CategoryTemplateMapper defaultRepository=/atg/commerce/catalog/ProductCatalog defaultItemDescriptorName=product
The itemDescriptorNameToMapperMap
property determines the template mapper to use, based on the type of repository item passed to the servlet bean. The item type is either product
(for a link to a product detail page) or category
(for a link to a category page).
Each template mapper component has a templates
property that specifies one or more templates to use for rendering URLs. The templates
property of the ProductTemplateMapper
component is set to /atg/repository/seo/ProductIndirectTemplate
. This template is used to construct static URLs for product detail pages if the site visitor is a spider. (Similarly, the templates
property of the CategoryTemplateMapper
is set to /atg/repository/seo/CategoryIndirectTemplate
, which is used to construct static URLs for category pages.) The urlTemplateFormat
property of ProductIndirectTemplate
, which specifies the format of the static URLs, is set to:
/jump/{item.displayName}/productDetail/{item.parentCategory.displayName}/
{item.id}/{item.parentCategory.id}
The resulting URL thus includes the display name of the product and its default parent category, so the search engine can index these terms. In addition, it includes the repository IDs of the product and category. These IDs, along with the /jump
prefix, enable the SEO jump servlet to reconstruct the dynamic URL, as discussed below.
ProductLookupItemLink
When the CatalogItemLink
component constructs a static URL for a product detail page, it determines the category to use in the URL by looking up the product’s default parent category. But if the product has multiple parent categories, and is being accessed in a category that is not the default parent, using the default parent category may not be desirable. To handle this situation, CRS includes another instance of the ItemLink
servlet bean, ProductLookupItemLink
.
The ProductLookupItemLink
component is used for generating links to product detail pages in cases where a product is not being viewed in its default category. It uses the ProductIndirectTemplate
to generate static URLs. The urlTemplateFormat
property of this template is set to:
/jump/{item.displayName}/productDetail/{item.parentCategory.displayName}/
{item.id}/{categoryId}
The resulting URL includes the display name of the default parent category, but rather than the default parent category’s ID, it instead includes the ID of the category that the product is being accessed from. This enables the search engine to associate the product with its default category in the index, while still allowing the SEO jump servlet to reconstruct the dynamic URL specifying the (non-default) category that the product was accessed from.
The ProductIndirectTemplate
can obtain the category ID of the nondefault parent category from a page parameter, or it can be explicitly set on the page, as in the following example taken from browse/asSeenIn.jsp
:
<dsp:droplet name="/atg/repository/seo/ProductLookupItemLink"> <dsp:param name="item" param="product"/> <dsp:param name="categoryId" value="asSeenIn"/> <dsp:oparam name="output"> <dsp:getvalueof var="finalUrl" vartype="String" param="url"/> <dsp:include page="/browse/gadgets/asSeenInElement.jsp"> <dsp:param name="product" param="product"/> <dsp:param name="hasTemplate" value="true" /> <dsp:param name="url" value="${finalUrl}" /> </dsp:include> </dsp:oparam> </dsp:droplet>