Templates

B2C Commerce uses ISML templates to generate dynamic storefront pages. Templates combine HTML with a proprietary language extension called Internet Store Markup Language (ISML). An ISML template consists of standard HTML markup, ISML tags, and script expressions. ISML templates are similar to Java Server Pages in that both are used to present dynamically generated web content.

ISML templates don’t support JSP syntax or directives.

Templates convert the result of business processes (for example, product details) into a response that can be returned to the client (for example, a list of product specifications and an image).

  1. The first time a template is requested it's converted into an internal structure for processing.
  2. The Template Processor processes the ISML tags and expressions and parses any attributes and values stored in the Pipeline Dictionary.
  3. The resulting data is added to the output stream and pure, static HTML pages are sent to the browser.

Templates are always triggered by a pipeline. They implement the presentation logic (web design). You can cache execution results as an HTML file (page caching).

Templates contain:

  • Browser-ready content of web pages
  • Special markup tags for handling variables that are looked up in the Pipeline Dictionary on demand for dynamic content
  • Other instructional markup tags for processing and information flow
  • Style information for formatting the requested page

Templates are stored as *.isml files that consist mainly of HTML and ISML code. They’re located in a locale-specific folder under the /cartridge/templates/ folder, with /cartridge/templates/default being the default locale. Each local-specific folder can contain for subdirectories organized around areas of functionality. If you support multiple locales, each locale must have a separate subdirectory under /templates/. All templates must be in a subdirectory of the templates directory, either the default directory or a locale directory, and can't be stored in the templates directory itself.

Each cartridge has its own templates directory.

Templates used to show information in the storefront are represented by an interaction node in a pipeline. Information about them also appears in the Properties view. If you want to modify how information is presented in a storefront, you should edit a template or create one.

Before you edit a template, you must define the layout or design of a web page. You must also identify information about the pipeline that uses your template and the data to appear by the template. After you collect this information, modify the template using UX Studio.

This is the information you need about the pipeline that calls a template:

  • The name of the pipeline that calls the template
  • The name of the template you’re modifying
  • The name of the template variables you need to show the data in a template

The interaction between the storefront and the buyer is defined by input and output data delivered by a pipeline.

Input Data:

  • Order information
  • Shipping information
  • UPS built-in gateway integration
  • Payment information
  • Built-in gateway integration for: Cybersource, Paypal, Verisign, BillMeLater
  • Tax information
  • Gift certificates|
  • Catalog data

Output Data:

  • Inventory
  • Pricing
  • Promotions, coupons, source codes
  • Customer profile management
  • Customer address book
  • Payment preferences
  • Order status

Templates either deliver input data or show a pipeline's output data on the browser.

Building a secure custom website with Salesforce B2C Commerce requires paying attention to all areas that are vulnerable to attack and preventing it.

To prevent malicious attacks through content manipulation, you must ensure that all shown content is encoded.

If a script expression such as ${pdict.ProductSearchResult.searchPhrase} is used in an ISML template, where the content type is set via the following:

The script result is automatically HTML encoded.

But if the same expression is used in an ISML template that is included via <isinclude template=""> and no content type is set in the included ISML snippet, the content type text/plain is assumed and no HTML encoding takes place. This inconsistency can lead to XSS problems.

To correct this situation, you must explicitly set the content type or use <isprint value="{}"/> to ensure the resulting HTML is encoded.

To ensure that a script expression is HTML encoded, you must set the included page's content type to text/html via the following statement:

If you include pages, ensure that you set the content type, as described.

Using <isprint>

In SiteGenesis, we’ve addressed this problem by using the <isprint> element instead of merely using the following:

The <isprint> element ensures that special characters are HTML encoded.

For example:

Results in:

This notation avoids cross-side scripting attacks, because the alert() function is obfuscated for the browser.

Check all areas in your code where ${pdict.ProductSearchResult.searchPhrase} is used and add the <isprint> function, as described.

In a customized searchresultheader.isml template, use the following:

Instead of this:

Templates let you separate page content into static and dynamic.

Page ContentDescription
StaticWeb page elements such as HTML headings and text, images called with HTML tags, and any other part of the page that is unaffected by the ISML conversion process, are considered static content.
DynamicWhen ISML tags call variables to generate a specific list at run time (for example, a list of products), they look up object properties in the Pipeline Dictionary to present product details or other session-dependent data dynamically. This is called dynamic content. URLs are another example of dynamic content. The system parses this information at run time to compose content that changes from session to session.

Certain ISML tags facilitate dynamic and conditional page generation.

ISML TagUsed to...
<iscontent>Set up the content type.
<isdecorate>Decorate the enclosed content with the contents of the specified decorator template.
<isinclude>Enable content inclusion from an additional source. Allows for the inclusion of content from an additional source to a template. Either from another template file (local include, or by executing a second pipeline that returns the information (remote include)
<ismodule>Build units of reusable template functionality that are inserted into the template using custom ISML tags. When <ismodule> specifies a template, the specified template is included and user-defined attributes and custom ISML tags are accessible. See ismodule element for examples of isml modules.

Page caching is when pages (or parts of pages) are stored for immediate browser display, without having to call the server.

The nature of the Internet is that a page is served to the browser, then the connection to the server is dropped.

You can easily design a site that caches portions of pages for data that doesn't change frequently or is generic (not dependent on who is viewing the page). By caching portions of pages, merchants can manage the customer experience, while satisfying business requirements related to timely data changes such as pricing and promotions.

Pipeline caching is site-based. If you turn off pipeline caching, you turn it off for all pipelines for that site.

B2C Commerce uses the B2C Commerce Web Server to perform page caching.

  1. A browser client makes a request to the B2C Commerce Web Server. Because the page isn't in the cache, the request is dispatched to the Application Server.
  2. The Application Server returns the page to the B2C Commerce Web Server. The B2C Commerce Web Server caches the page and returns the page to client.
  3. The client makes a request to the B2C Commerce Web Server for the same page.
  4. B2C Commerce Web Server finds the page in the cache and delivers it to the client.

All the data served to a browser doesn't have to be resent each time a button is clicked or an entry made in a field. Some content (often, most of it) can be cached for immediate redisplay. Web page elements such as HTML headings and text, images called with HTML tags, and any other part of the page that is unlikely to change, can be cached. This content is considered static.

By contrast, when ISML tags call variables to generate a specific list at run time (for example, a list of products), they look up object properties in the Pipeline Dictionary to present product details or other session-dependent data on-the-fly. This content is dynamic in that it changes each time a request is made from the browser.

URLs are also dynamic because the system uses them at run time to compose content that changes from session to session.

You can enable page caching in Business Manager; and use the <iscache>ISML tag within a template to control what parts of a page are cached and for how long.

When a controller or a pipeline is processed, the Pipeline Dictionary accepts and stores parameters in key-value pairs. A template can show only the dynamic information that is stored in the Pipeline Dictionary at the time the template is called.

The value of a key-value pair stored in the Pipeline Dictionary can be:

  • Simple values, stored as strings

    Some key-value pairs are delivered in their simplest form, for example, ProductID = 4569. You could parse the value of the ProductID key and use an <isprint> statement in the template to show the product number directly in the storefront, as shown:

  • Complex objects, containing more attributes and values

    Many keys have as their value a complex object that acts as a container for many other key-value pairs. However, templates can't show complex objects; they only show simple values, such as strings or numbers. To obtain the values of complex objects' properties, a special notation is used describing the path through the object to the simple property that the template can show.

    The following <isprint> statement shows how to show the value of the FirstName variable on the DataSheet form of the Buyer object:

Controllers don’t manipulate the Pipeline Dictionary directly; instead, they construct an object that is passed to a template. This object consists of name-value pairs.

You can use the UX Studio debugger to view the contents of the object before it’s passed into a template. Within the template context, the variable pdict is used to reference this object.

Information on available key-value pairs in the Pipeline Dictionary can be found in the Properties editor of the pipelet that produces the appropriate key as an output parameter and puts it in the Pipeline Dictionary.

If the value of a key-value pair is a complex object, you must know the name of its attributes that contain the values you want to appear in a template.

  • To determine the key-value pair's key attributes
  1. Open UX Studio.

  2. Select the pipelet.

  3. Look in the Properties editor.

  4. Observe the Dictionary Input and Output keys, which are the key-value pairs.

    For example, for AddGiftCertificateToBasket (bc_api) it would be:

DictionaryKeyValue
InputAmountCurrrentForms.giftcert.purchase.​amount.value
 BasketBasket
 MessageCurrrentForms.giftcert.purchase.​message.value
 ProductListItemProductListItem
 RecipientEmailCurrrentForms.giftcert.purchase.​email.​value
 RecipientNameCurrrentForms.giftcert.purchase.​recipient.​value
 SenderNameCurrrentForms.giftcert.purchase.​from.​value
 ShipmentShipment
OutputAddGCErrorMessagenull
 GiftCertificateLineItemGiftCertificateLineItem

The available key-value pairs of the selected attribute appear.

jQuery is frequently used in ISML templates. B2C Commerce supports versions up to and including jQuery 1.3.2.

Avoid using the # character in jQuery or JavaScript because it's reserved in ISML templates and can cause problems.

Generally, if you follow the best practices of unobtrusive JavaScript and progressive enhancement, you don't mix HTML and JavaScript behavior, so this is unnecessary.

However, there might be cases where you must use the # character. In these cases, instead of the following code:

Use the following code:

Alternatively, the following notation:

is correctly written in ISML as

Determining which template is causing an issue requires knowing the template name. The process of determining the name depends on whether the template is static or dynamic.

Template typeWhere to find information
StaticCheck the interaction node properties. The Interaction Template Name property shows the name of the template called by the interaction node. This is the file name of the template you must modify.
DynamicThe template to be called by an interaction node isn't always hard-coded in the node. Instead, the name can be determined dynamically during run time from the Pipeline Dictionary. Usually, if products and categories are visible, the storefront is using a dynamic template, indicated by a D in the symbol of an interaction node.

You can also use the Storefront Toolkit to identify which parts of a page belong to which templates.