Templating
How to use the embedded logic-less template system.
The Woosmap JS Store Locator API embeds Hogan.js, a simple JavaScript templating based on Mustache logic-less template syntax.
When it should be used
Javascript templating lets you separate the logic from your view. Imagine a placeholder where you want to render the selected store attributes. After retrieving the selected store data, without templating, your javascript looks like this:
let selectedStoreHTML = '<div><h2>' + store.name + '</h2>';
if (store.address.lines.length > 0) {
selectedStoreHTML += '<ul id="addressLines">'
for (let i = 0; i < store.address.lines; i++) {
selectedStoreHTML += '<li>' + store.address.lines[i] + '</li>'
}
selectedStoreHTML += '</ul>'
}
selectedStoreHTML += '</div>'
Using templating the same code is much cleaner and easier to maintain:
const selectedStoreTemplate =
'<div><h2>{{name}}</h2>' +
'{{#address.lines}}<ul id="addressLines"><li>{{.}}</li></ul>{{/address.lines}}' +
'</div>'
const renderer = new woosmap.TemplateRenderer(selectedStoreTemplate);
const selectedStoreHTML = renderer.render(store);
You can use this templating system whenever you have to deal with the stores attributes or any JSON object. Some classes of the Woosmap JS Store Locator API are designed to take advantage of this templating like the Info Window or Driving Direction features.
Build a TemplateRenderer for InfoWindow
The woosmap.TemplateRenderer
that you put as parameter to the woosmap.LocatorWindow
will receive a store properties object.
Therefore, the tags specified in the template should correspond to the properties
object of Store Data Structure.
Simple Template
Here’s a simple example.
const templateInfoWindow =
"<div class='store-title'>{{name}}</div>" +
"<div class='store-address'>{{address.lines}}</div>" +
"<div class='store-contact'><a href='tel:{{contact.phone}}'>{{contact.phone}}</a></div>";
Assume that the selected store have this following properties.
{
"store_id": "123456",
"name": "SuperMarket Edinburgh",
"address": {
"lines": ["20 Castle Terrace"]
},
"contact": {
"phone": "+441313375757"
}
}
The rendered template will look like.
<div class='store-title'>SuperMarket Edinburgh</div>
<div class='store-address'>20 Castle Terrace</div>
<div class='store-contact'><a href='tel:+441313375757'>+441313375757</a></div>
Register Lambda Function
As the template system is logic-less it could be hard to display advanced behaviour. To enable a finer-grained
processing of your stores attributes you can add to your template some custom tags/functions using
the woosmap.TemplateRenderer.registerLambda
method. You will have access to the selected store properties inside the lambda function using infoWindow.get("selectedStore")
.
Here is a sample to put an opening label when the store is opened.
function getOpeningLabel() {
let openLabel = "Close";
const store = infoWindow.get("selectedStore").properties;
if (store.open && store.open.open_now) {
openLabel = store.open.current_slice["all-day"]
? "24/24"
: store.open.current_slice.start + "–" + store.open.current_slice.end;
openLabel =
store.open && store.open.open_now ? "Open now: " + openLabel : "";
}
return openLabel;
}
const templateInfoWindow =
"<div class='store-title'>{{name}}</div>" +
"<div>{{#opening_label}}{{/opening_label}}</div>";
const renderer = new woosmap.TemplateRenderer(templateInfoWindow);
renderer.registerLambda('opening_label', getOpeningLabel);