Predict web recommender templates use the popular doT.js template language.
When recommended items are returned from the recommender servers in the SC object, the template controls the structure and the content of document elements inserted into your recommendation widget. Basically, a template is a piece of HTML code containing JavaScript snippets that refer to the recommended items.
We serve a default template controlled by CSS, but you are welcome to implement your own template. We advise you to familiarize yourself with the concepts by reading this section; then you can start the actual implementation by copying and modifying the default template.
Using a non-default recommender template
Defining a recommender template
Add your template to a script block with the scripts type
attribute set to text/html
. Inside the block, start with the preamble <![CDATA[
and finish with ]]>
. You may define multiple templates using different id
s. The example below shows how to add a dummy template that displays nothing but the text “This is my first website recommender template“.
<script type="text/html" id="my-recommender-template">
<![CDATA[
<i>This is my first recommender template</i>.
]]>
</script>
Applying the template to a recommender box
The template can be passed to the recommend
API command by setting templateId
. For example, the above-defined my-recommender-template
can be applied to the RELATED
widget as below.
<div id="my-recommendation-container"></div>
<script>
ScarabQueue.push(["recommend", {
logic: "RELATED",
containerId: "my-recommendation-container",
templateId: "my-recommender-template"
}]);
</script>
The template language
Templates are substituted with the JavaScript object SC
holding the recommended products in the array SC.page.products
. Each product has attributes corresponding to the columns of the uploaded catalog. For example, SC.page.products[0].title
refers to the content of the catalog field title of the first recommended item, etc.
The size of this array never exceeds the limit passed to the recommend
command as an argument.The template is essentially an HTML string, but you can insert the value of a JavaScript variable into the HTML by {{= variable }}
. For example:
<i>We recommend {{=SC.page.products.length}} number of products for You</i>!
In addition, the template may contain JavaScript code blocks between {{
and }}
. For example:
{{ if(SC.page.products.length > 0) { }}
<i>We primarily recommend {{=SC.page.products[0].title}} for You</i>!
{{ } else { }}
<i>Sorry! No recommendations found!</i>
{{ } }}
Marking the outer HTML elements of recommended items
Our system needs to track each click on recommended items. To support this, you must add the attribute data-scarabitem
to one of the HTML elements containing the recommended item, and set the value to the ID of the recommended product. See the example of a link to a recommended item contained in a span
element:
<span data-scarabitem="{{= SC.page.products[i].id }}">
<a href="{{= SC.page.products[i].link }}">
<img src="{{= SC.page.products[i].image }}">
{{= SC.page.products[i].title }}
</a>
</span>
Copy and modify the default template
If you are familiar with the previous section, you start the actual implementation by using and modifying the default template quoted below.
<script type="text/html" id="my-recommender-template">
<![CDATA[
{{ if (SC.page.products.length) { }}
<div class="scarab-itemlist">
<div class="scarab-prev"></div>
{{ for (var i=0; i < SC.page.products.length; i++) { }}
{{ var p = SC.page.products[i]; }}
<span data-scarabitem="{{= p.id }}" class="scarab-item">
<a href="{{= p.link }}">
<img src="{{= p.image }}">
{{= p.title }}
</a>
</span>
{{ } }}
<div class="scarab-next"></div>
</div>
{{ } }}
]]>
</script>
Remember that you have to apply the template to each recommender widget as in the example below:
<div id="my-recommendation-container"></div>
<script>
ScarabQueue.push(["recommend", {
logic: "RELATED",
containerId: "my-recommendation-container",
templateId: "my-recommender-template"
}]);
</script>
Here is an example:
Errors validating Web Recommender templates: 'Unexpected "}"
The Web Recommender uses the same template language as the TWIG personalization, which can result in errors when curly the brackets { and }. This can result in the following message when validating a template:
There are two solutions to this problem.
1. Unfold the curly brackets with string concatenation, such as:
2. Disable twig parsing by enclosing parts of the content between verbatim/endverbatim statements, such as:
<!-- {% verbatim %} -->
<script>
</script>
<!-- {% endverbatim %} -->
or
<script>
// {% verbatim %}
// {% endverbatim %}
</script>
Working with the recommended items directly in Javascript
If you want to access the recommended items directly, you can pass a JavaScript function to the recommend
command, called the success handler
. It is called after the recommendation service returns the recommendations but before the widget is rendered. The success handler
takes two parameters, the SC object, and a render
function which has to be called to start the widget rendering. Here are some things that you can do with this function.
Display discounts
Let’s say you want to display the discount on the product compared to the recommended retail price. You could calculate the value from the price
and msrp
fields in the template code between double brackets {{ }}
, but that would make the template harder to read. The success
function lets you separate display from logic.
var mySuccessHandler = function(SC, render) {
for (var i = 0, l = SC.page.products.length; i < l; i++) {
var product = SC.page.products[i];
product.discount = ((1 - product.price / product.msrp) * 100).toFixed(0) + '%';
}
render(SC);
};
ScarabQueue.push(["recommend", {
logic: "RELATED",
containerId: "my-recommendations",
success: mySuccessHandler
}]);
The example above allows you to use the field discount
in the recommender template similarly to catalog fields like title
or link
.
Do something after the recommendations are rendered
You might want to attach a custom click handler, or start an animation after the widget is rendered.
var mySuccessHandler = function(SC, render) {
render(SC);
attachMyClickHandler();
};
ScarabQueue.push(["recommend", {
logic: "RELATED",
containerId: "my-recommendations",
success: mySuccessHandler
}]);
Don’t use Scarab rendering, render with your own code
If you just want to get the IDs of the recommended products, and take care of the rest yourself, you can do this with a success handler
that doesn’t call render
.
var mySuccessHandler = function(SC, render) {
var recommendedItems = [];
for (var i = 0, l = SC.page.products.length; i < l; i++) {
recommendedItems.push(SC.page.products[i].id);
}
doMyOwnThing(recommendedItems);
};
ScarabQueue.push(["recommend", {
logic: "RELATED",
containerId: "my-recommendations",
success: mySuccessHandler
}]);
You will still have to render the widget in the given container
, and mark the recommended items with data-scarabitem
attributes, otherwise click tracking won’t work.
Get live data from your servers
In some scenarios, you need to collect additional information about the recommended items by talking to other servers with asynchronous requests. For example, you sell movie tickets, and you want to display the exact number of tickets available, checking availability in your own booking database.
var mySuccessHandler = function(SC, render) {
$.ajax({
url: 'ajax/num_available_tickets?items=...',
success: function(data) {
for (var i = 0, l = SC.page.products.length; i < l; i++) {
SC.page.products[i].num_available_tickets = ...
}
render(SC);
}
});
};
ScarabQueue.push(["recommend", {
logic: "RELATED",
containerId: "my-recommendations",
success: mySuccessHandler
}]);
The num_available_tickets
field can now be used in the template code. Please note that this delays the widget’s appearance, since the browser will have to wait for an extra request.