Connector for Salesforce Commerce Cloud Manual / Version 2307
Table Of Contentsislcinclude
Behind the scenes of the CoreMedia Content Widget works the CoreMedia islcinclude
tag.
You may also use it in your own ISML
templates to embed CoreMedia content on the
commerce side. In general it is used like this:
<iscontent type="text/html" charset="UTF-8" compact="true"/> <isinclude template="coremedia/modules.isml"/> <!-- COREMEDIA HEADER --> <isset name="pageId" value="${cmUtil.pageId(pdict)}" scope="page"/> <isset name="categoryId" value="${cmUtil.categoryId(pdict)}" scope="page"/> <isset name="productId" value="${cmUtil.productId(pdict)}" scope="page"/> <islcinclude pageId="${pageId}" categoryId="${categoryId}" productId="${productId}" placement="header"/>
All parameters are described in the Include Tag Reference section.
The islcinclude
tag from CoreMedia renders the CMS fragments in the same context of the
caller. That means all the following code would have access to the results of this call. This
technique is, for example, especially useful for the metadata
call.
This is different to the islcincludeRemote
tag that will be described describe later.
islcincludeVar
In some cases you might want to decide what to do next, depending on the result of a fragment call.
For such a case you can use the islcincludeVar
tag. It stores the result in a
fragmentPayload
page variable and the HTTP status in a separate fragmentHttpStatus
variable. You could now, depending on the status, either print the fragment payload to the output stream
or do an alternative rendering.
As an example you can use this technique to decide whether the navigation should be rendered by the CMS or the shop. In the template you can ask the CMS if it is able to render the navigation. If there is a result status of "200", then the fragment payload can be printed to the response. Otherwise, the original shop template should do the work.
<isinclude template="coremedia/modules.isml"/> <iscomment>Render CoreMedia Navigation if available</iscomment> <isset name="pageId" value="${cmUtil.pageId(pdict)}" scope="page"/> <islcincludeVar pageId="${pageId}" view="asNavigation" /> <isif condition="${fragmentHttpStatus == '200'}"> <iscomment> Render the output of the navigation fragment call into the page. The fragment response is already encoded and shouldn't be encoded twice! </iscomment> <isprint value="${fragmentPayload}" encoding="off"/> <iselse/> <iscomment> The original SFRA template was copied. Please verify if the original is changed and should be renewed. </iscomment> <isinclude template="components/header/menu-original" /> </isif>
islcincludeRemote
As a specialty of the Salesforce Commerce platform fragments can be
rendered in a remote call for the reason of cacheability and reusability. In
ISML
templates an iscomponent
can be used to achieve this.
With the islcincludeRemote
tag it is
possible to enforce a remote call to gather a CMS fragment. The CMS fragment will then be rendered in
the remote context with its own pipeline dictionary. But the parameters of this tag are mostly
the same as for the islcinclude
tag except of the prefetch
and
ajax
parameters. Both parameters make no sense in the remote case, because the fragment is
requested in a completely new context (by a new HTTP call). This new context serves only this single fragment
and a further prefetch of all fragments would result in an unnecessary rendering effort
on the CAE side. Same applies to the ajax
parameter. The actual fragment call is made by
the browser. The required AJAX stub code is so small that it does not have to be cached separately.
<div class="header-banner"> <iscomment>CoreMedia include of header</iscomment> <isset name="pageId" value="${cmUtil.pageId(pdict)}" scope="page"/> <islcincludeRemote pageId="${pageId}" placement="header" view="asDefaultFragment"/> </div>
Note
The CoreMedia Content Widget is using the islcinclude
tag. The reason for this is that
it makes it easier to transfer computed values into the caller context and thus influence the
subsequent rendering. For example, the processing of the HTML metadata makes use of it (to set
the HTML title and meta tags).
Include Tag Reference
The tag attributes have the following meaning:
Parameter | Description |
---|---|
|
These attributes are used in the CAE to find the context which will be used for
rendering the requested fragment. Both parameters should not be set at the same time
since depending on the attributes set for the include tag, different handlers are
invoked: If the |
|
This parameter is optional. Usually, the page ID is computed from the requested URL (the last token in the URL path without a file extension). If you set the parameter, the automatically generated value is overwritten. On the Blueprint side an Augmented Page will be retrieved to serve the fragment HTML. The transmitted page ID parameter must match the External Page ID of the Augmented Page. You might use the parameter, for example, in order to have one CoreMedia page to deliver the same content to different shop pages. |
|
This attribute defines the name of a placement in the page grid of the requested
context. In the example for the header fragment, the "header" placement was used. If
you do not want to render a certain placement but a view of the whole CMS page you
may omit it. This attribute can be combined with the
|
|
The attribute "view" defines the name of the CMS view which will render the
fragment. Such view templates must exist on the CMS side. There are several views
prepared in Blueprint: |
|
This attribute is used in the CAE to find content. The attribute can be used in
combination with the |
|
This attribute is used to signal the CoreMedia Fragment Connector a prefetch of all
fragments should be made before requesting the fragment. At best, this should lead
to a single call that gets all wanted fragments that will follow in the same request context.
A following fragment call can then be served from the local cache, or if not found, will be
made in the traditional way. This attribute is optional and the default value is
|
|
This attribute is used to signal the CoreMedia Fragment Connector that a AJAX stub code should
be written into the output instead of calling the CAE. The link that is set into stub
code points to the |
|
This attribute is optional and can be used to apply a request attribute to the CAE
request. The request attribute is stored using the constant
|
Table 5.1. Attributes of the Include tag
Finding Handlers
You can control the behavior of the islcinclude
tag by providing different sets of
attributes. Depending on the used attributes, different handlers are invoked to generate the
HTML.
The CoreMedia islcinclude
tag requests data from the CAE via HTTP. Each attribute
value of the include tag is passed as path or matrix parameter to the
FragmentPageHandler
. In order to find the matching handler, the
FragmentPageHandler
class calls the include
method of all fragment handler classes defined in the file
livecontext-fragment.xml
. The first handler that returns "true" generates
the HTML. Example 5.1, “Default fragment handler order” shows the default order:
<util:list id="fragmentHandlers" value-type="com.coremedia.livecontext.fragment.FragmentHandler"> <description>This list contains all handlers that are used for fragment calls.</description> <ref bean="externalRefFragmentHandler" /> <ref bean="externalPageFragmentHandler" /> <ref bean="productFragmentHandler" /> <ref bean="categoryFragmentHandler" /> </util:list>
Example 5.1. Default fragment handler order
If the handlers are in the default order, then the table shows which handler is used depending on the attributes set. An "x" means that the attribute is set, a "-" means that the attribute is not allowed to be set and no entry means that it does not matter if something is set. For more details, have a look into the handler classes.
External Reference | Page ID | Category ID | Product ID | Used Handler | |
---|---|---|---|---|---|
x |
ExternalRefFragmentHandler
| ||||
| x | - | - |
ExternalPageFragmentHandler
| |
| x |
ProductFragmentHandler
| |||
| x | - |
CategoryFragmentHandler
|
Table 5.2. Fragment handler usage
Using Commerce-side Includes
Up to this point you have already seen CMS fragments that are embedded in the store-side HTML output. But one twist further it is also possible the other way around: to define placeholders in CMS templates that will be replaced later during the shop rendering (as server-side includes). This is already used by default for creating URLs in CMS fragments.
A "Velocity rendering technique" is used to achieve this. The Salesforce system has already the possibility to write Velocity expressions in templates as an alternative scripting mechanism. For example such Velocity expressions can be used to include other components or even to call each publicly exported script function.
It is possible to write Velocity script directly into CMS-side FreeMarker templates. Such a Velocity script section must be included into an HTML comment section to have an unbroken output of fragments even without the Velocity script engine (for example, if you call the fragments directly in a browser).
A Velocity sections must start with a <!--VTL
text and end with
VTL-->
. The following examples will illustrate this.
VTL scripts cannot be nested. Be careful with includes of further templates within such a Velocity section that may contain more Velocity scripts. Be aware that rendering a link within a Velocity script (using
cm.getLink()
) would lead to such a situation. Rather don't use any includes in VTL scripts.Velocity expressions start with a "$" char. Additionally, the "#" char is also reserved. If you want to use these chars around a Velocity expression but within a VTL section you have to mask these characters manually. Use "$D" instead of "$" and $H instead of "#".
This mechanism is currently prepared for four use cases. To support these cases, there is a file
cartridge/scripts/cmInclude.js
which contains publicly exported script
functions that can be used directly.
Rendering Commerce Links
It is already used by default. The SfccLinkResolver
class is part of the
eCommerce Blueprint and generates Velocity expression instead of HTML links into the fragment
output. It ensures that commerce links are built exclusively on the Commerce side. The CMS does
not need to know anything about the resulting format (for example, SEO mapping on/off is transparent for
the CMS).
In general the CMS-side format complies to the canonical URL format in the
Salesforce Commerce Cloud platform. Parameters can be passed directly to certain controllers.
There are various types of possible target pages/controllers. In the following example a
category page link is shown. Each target page type has its own allowed set of parameters. Please
see the class SfccLinkResolver
to get further information.
<!--VTL $include.url('Search-Show','cgid','womens-clothing-dresses','preview','true') VTL-->
Overwriting HTML Metadata
The CMS can overwrite the finally used HTML metadata for the HTML title, keywords and
description tag by using the metadata
function in CMS templates. This is
typically the case for content driven pages. The following code shows an example from the
Page.metadata.ftl
template.
<!--VTL $include.metadata('${content.htmlTitle}','${content.htmlDescription}', '${content.keywords}') VTL-->
Including any Salesforce Controller
Salesforce Commerce Cloud reusable components are typically implemented as a controller with its
own URL to call. Any Salesforce controller can be included by giving its name and all
required parameters. The same ones you need to call the controller on the Salesforce side.
There is a controller()
function prepared in the
cmInclude.js
file that can be used. The following code example shows how
the include a product teaser that is rendered by the Salesforce platform. All parameters can
also be calculated dynamically.
<!--VTL $include.controller('Product-HitTile','pid','25448070','showswatches','true', 'showpricing','true','showpromotion','true','showrating','true') VTL-->
Including any ISML Template
Less often it will be necessary to embed an ISML
template. A template()
function is prepared in the cmInclude.js
file for such cases. This
example shows the include of a template example.isml
which renders a
product teaser again. The called ISML
template must be located in the
cartridge/templates/default/coremedia/cms
directory of the
CoreMedia Cartridge for Salesforce.
<!--VTL $include.template('example','pid','682875090845','showswatches','true', 'showpricing','true','showpromotion','true','showrating','true') VTL-->
Including the Availability of a Product
The availability of a product in stock can be tested on the shop side by calling the
availability()
function. The prepared function in the cmInclude.js
file expects at least one argument: the product ID. The result of this method is a string that indicates
if the product is available in stock or not. If not given as separate parameters the method returns
true
or false
. Alternative strings can be passed as second and third argument.
<!--VTL $include.availability('${self.product.externalId}') VTL--> or <!--VTL $include.availability('${self.product.externalId}','available','not-available') VTL-->
Calling custom Script Functions
Only exported functions from the cartridge/scripts/cmInclude.js
file can be
called by default. As you can see in the examples above, they are all exposed below the context
include
. To call your own functions you can add these functions to the file. To
call other function from other files or even other cartridges, more
requires
directives would have to be added to the
renderVelocity()
function in
cartridge/scripts/cmVtlProcessor.js
. An alternative would be to overwrite
the whole cmInclude.js
module in our own custom cartridge and copy and
extend the code.
Fragment Request Context
In addition to the passed request parameters, a personalization context is built via the
cmContextProvider.js
script as part of the CoreMedia Cartridge for Salesforce. The
default implementation can be extended with custom values. The context information is then
passed as header attributes to the CAE. For more details see
Section 5.3, “Extending the Shop Context”.