Templating

How to use the embedded logic-less template system.

  1. When it should be used
  2. Build a TemplateRenderer for InfoWindow

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);
Was this article helpful?
Have more questions? Submit a request