wp-content/uploads/2016/01/PBS_Logo.png

In the previous instalment we got our first look at Mustache templates. In this instalment we’ll finish our look at this handy little third party library with a look at some of Mustache’s more advanced features. This will set us up perfectly to finally introduce AJAX into this series. This is an extremely common technique for fetching external resources with JavaScript. We’ll learn how to use AJAX to fetch both Mustache template strings and JSON data from URLs.

You can download this instalment’s ZIP file here.

Listen Along: CCATP Episode 587

MP3 File

PBS 73 challenge Solution

The challenge set at the end of the previous instalment was quite straight forward, re-write the sill timer app we’ve been working on for the past few challenges so it uses Mustache templates rather than the HTML5 <template> tag.

The first thing to do was to load the Mustache library into the document:

With Mustache now available in the document, the next step was to update the template for the toasts so it’s contained within a <script> tag with a non-executable MIME type (I chose text/html) and an ID rather than a <template> tag with an ID. Then it was just a matter of inserting the Mustache placeholders for injecting the content from the view object. I chose to use the names title and message:

Then it was just a matter of updating my showToast() function so it loaded the template from the newly created <script> tag, and used Mustache to process it:

More on Mustache Sections

In the previous instalment we learned how to use so-called Mustache sections to show include or exclude content depending on whether or not a given variable in the view had a truthy value. We also saw how we could use sections to loop parts of a template multiple times.

A section to be included if the the view variable boogers has a truthy value (and is not an array) would start with {{#boogers}} and end with {{/boogers}}. Similarly, a section to be shown only if boogers is neither an array nor a truthy value would start with {{^boogers}} and end with {{/boogers}}. Finally, if our view contained an array named boogerList we could repeat a section of the template once for each value in the array by starting the section with {{#boogerList}} and ending it with {{/boogerList}}.

Last time we described the view variables (boogers and boogerList in this case) as controlling the sections. The official term for these section-controlling variables in the Mustache documentation is section key. I.e., in the above examples, the section keys were boogers and boogerList.

Functions as Mustache Section Keys

We saw in the previous instalment that Mustache does something special when a section key is an array — it loops the section once for each element in the array.

We also saw last time that if you include a view variable that is a function Mustache will execute the function and use the returned value. We can take this a step further by using a function as a section key.

There is an unexpected second level of indirection here, so pay close attention. To use a function to process the content of a section you need to have the section key be a function that returns a function that returns a string. The inner-most function will get called with two arguments:

  1. The raw template text containing within the section
  2. A special render function which takes just one argument, a Mustache template string, and renders it using the current view object.

And, the output of that inner-most function will be used to represent the section in the template output.

This sounds a little confusing, so let’s illustrate how this works with an example.

Function as Section Key Example — Rendering Temperatures

These example code snippets can be executed in the JavaScript console on any page that includes the Mustache API, e.g. pbs74a.html in this instalment’s ZIP file.

Let’s start with the following simple view:

We’d like to use it to render the following output:

It will be 72°F (22°C) in LA tomorrow.

Without using functions the closest we could get would be the following:

Which would render:

It will be 22°C in LA tomorrow.

Close, but not what we want.

Let’s start by creating a function for converting a Celsius temperature to the desired representation:

Now let’s update our view to offer this function as a section key:

Note that our section key, humanTemp, is a function that returns a function that returns a string.

We can now use humanTemp as a section key:

This will now render:

It will be 72°F (22°C) in LA tomorrow.

So how does this work? When the anonymous function defined in the view is called it returns another anonymous function which Mustache then executes. This inner-most anonymous function gets called with two arguments. The first argument, which we have named rawText, will be the raw template text within the section, i.e. {{tempC}}. The second argument, which we have named render, will be a special rendering function with the view baked in. So, to get the number to be converted to our nice representation we render the raw template text with: render(rawText). We can then pass this to our temperature rendering function degCToHumanTemp().

If the conversion is only needed once it doesn’t make sense to add it to the view as a function, but if you need it more than once it starts to make more sense:

This will render:

It will be between 64°F (18°C) and 82°F (28°C) in LA tomorrow.

You can see a version of the above example in the file pbs74a.html in this instalment’s ZIP file.

Mustache Partials — Templates within Templates

Within a larger project you may find you have little snippets of markup that appear in many places. The simplest thing to do would be to copy-and-paste them into every template that needed them, but of course, that leads to utterly un-maintainable code. It would be nice to be able to include little named sub-templates from within larger templates. Mustache Partials to the rescue!

Mustache takes an optional third argument, a plain object containing template strings indexed by names. If your partials object contained a partial named boogers, you would include it in your main template with the Mustache {{> boogers}}.

Let’s see this in action with a pair of examples. You can see these in their full context in the file PBS74b.html in this instalment’s ZIP file.

First, lets create two partials, one for links to external sites, and one for a ‘new’ badge.

We can now use these partials in our templates. Let’s start with the following template:

We can now use this partials-containing template like so:

We can of course use these same partials in other templates within the same document.

Let’s start by defining another template:

Note that this template is intended to loop over a view variable named jsLibs, and that the newBadge partial is included in a conditional section controlled by the view variable new.

We can now use this template as follows:

You can see what both of these templates look like when rendered by opening pbs74b.html from the ZIP file in your favourite browser.

Embedding View Data as JSON Strings

The trick for using <script> tags with non-executable types to store template strings can be adapted to store view data in JSON format.

As with template strings, you can use any type you like in your <script> tag, but I prefer to use the correct MIME Type for the data I’m storing. The appropriate MIME Type for JSON is application/json so, I use <script> tags of the following form (replacing the content of the tag and the ID as appropriate):

We can then access the embedded JSON string using jQuery’s .text(). function, e.g.

As we learned way back in instalment 17, the JavaScript function for converting a JSON string into a JavaScript object is JSON.parse(), so we can go directly from an ID to a JavaScript object with code of the form:

If your JSON has gotten a little rusty, you might find my Quick Introduction to JSON useful.

A Challenge

In this instalment’s ZIP file you’ll find a folder named pbs74-challenge-startingPoint. Use this file as your starting point for this challenge.

Note that this file imports jQuery, Bootstrap, Mustache, and FontAwesome 5.

Near the top of the file you’ll find a <script> tag with the ID pbs74_view_data. This is an embedded JSON string containing the data to be rendered. At the top level of the object you’ll find objects representing myself and Allison, and an object mapping contact mechanisms to to the CSS classes for FontAwesome 5 icons.

Your challenge, should you choose to accept it 😉, is to build a contact listing for both myself and Allison. Your solution should have the following properties/features:

  1. Each piece of contact information should be rendered as a flex item within a flex box, and should use the appropriate FontAwesome glyph as an obvious icon.
  2. The contact listings should be usable at all Bootstrap breakpoints.
  3. The contact listings should be accessible.
  4. You should use the same Mustache template to render both contact listings.
  5. You should use one or more partials within your template.

I do also want to remind you that you that flexboxes can be arranged both horizontally and vertically, and that Booststrap’s flex utilities allow different orientations at different break points.

Final Thoughts

One of the reasons I love Mustache is that it’s nice and simple — it does what it does well, but doesn’t have too many features. We have no covered almost every feature the library supports!

In the next instalment we’ll learn how to use a very powerful JavaScript technique known as AJAX to fetch both Mustache template strings and JSON strings from URLs.