Using Mustache JS by jQuery and Express application example. Part 1/2.

mustache-js

Level: advanced

In this tutorial we will create a web application using great tools – html5, Bootstrap, jQuery, Mustache JS and Express. Step by step. We will also use the ionicons.

Mustache JS

Not everyone (including me) likes templating systems in for example PHP. But here the situation is much different!

Mustache JS is a JavaScript implementation of the Mustache templates mini-engine (logic-less), which was created for many different programming languages: http://mustache.github.io.

Why the Mustache JS (and similar libraries) are cool?

First of all, having the data obtained e.g. from JSON objects, we don’t have to process the data manually. This can be tedious. Instead, we define a small template with placeholders, in which the Mustache engine will interpolate the values. In this way we will get the data integrated with our front-end layer at once.

Having mastered Mustache JS, we can save a lot of valuable time and effort. We will see it in practice.

Learning Mustache JS

It’s a good idea to start with a quick introduction to working with the library.

1. The template we defined as in following example:

...
<body onload="loadUser()">
<div id="target">Loading...</div>

<script id="template" type="x-tmpl-mustache">
Hello {{ name }}!
</script>

</body>

2. The JS code, which will trigger the magic of Mustache:

function loadUser() {
  var template = $('#template').html();
  Mustache.parse(template); // optional, speeds up future uses
  var rendered = Mustache.render(template, {name: "Luke"});
  $('#target').html(rendered);
}

That’s it!

Additional, small tutorial @ Tutsplus:

http://code.tutsplus.com/tutorials/using-the-mustache-template-library–net-14590

The library with simple documentation can be found on GitHub page:

https://github.com/janl/mustache.js

Mustache JS is easy, even pleasant in use, and can significantly help the programmer.

In practice – we write a small web application

It will be a node.js (express) web app, with single page app front.

The project had few assumptions:

On-line application for ordering food (pizza, drinks)

– show the menu in a clean way

– cart – the ability to add different products to the basket

– each pizza has a name, price, description and picture; drinks instead of description have types (soda, beer, rum)

– a simple logic of price validation:

– if user orders drinks only, the minimum price must be 10 EUR

– if only pizza – minimum 30 EUR

– no minimal price in case of ordering both food and drink

– the user can type his data and click “Order now”; the application will send the order to the server (node.js), or will display a message, that the price of selected products is too low.

From technical point of view:

– jQuery (and any plugin if necessary)

– HTML5, Bootstrap

– should work in FF, Chrome, IE and on mobile devices.


Let’s start with the preparation of test input data (pizzas and drinks)

The data may come from an external source as JSON, from the API, or simply retrieved from DB and returned via AJAX.

For simplicity, in the example we keep them as an array of objects, in an external JS file, which will be read by our simple server written in node.js:


// pizzas
var pizzaList = [
    {
        name: "Margherita",
        price: 20.99,
        details: "Lorem ipsum",
        img: "img/pizza.jpg"
    },
    {
        name: "Salami",
        price: 24,
        details: "Dolor sit amet",
        img: "img/pizza.jpg"
    },
    {
        name: "Pizza Super Good, with a long name",
        price: 44,
        details: "Great pizza with extra cheese, corn and bacon",
        img: "img/pizza.jpg"
    },
    {
        name: "Pepperoni",
        price: 20,
        details: "Lorem ipsum Pepperoni",
        img: "img/pizza.jpg"
    }
];

// drinks
var drinkList = [
    {
        name: "Coca-Cola",
        price: 5,
        type: "Soda",
        img: "img/soda.jpg"
    },
    {
        name: "Sprite",
        price: 6,
        type: "Soda",
        img: "img/soda.jpg"
    },
    {
        name: "Pilsner X",
        price: 6.2,
        type: "Beer",
        img: "img/beer.jpg"
    },

...  

    {
        name: "Captain Morgan",
        price: 7.75,
        type: "Rum",
        img: "img/rum.jpg"
    }
];

// group drinks by type, to display them grouped in "categories"
var drinkListByType = {};

for (var i = 0; i < drinkList.length; ++i) {
    var obj = drinkList[i];

    // create the "type key" if missing
    if (drinkListByType[obj.type] === undefined) {
        drinkListByType[obj.type] = [obj.type];
    }

    // pack the rest of the data to temporary object
    var tmp = {
        name: obj.name,
        price: obj.price,
        img: obj.img
    };

    drinkListByType[obj.type].push(tmp);
}

data = {
    pizzaList: pizzaList,
    drinkList: drinkList,
    drinkListByType: drinkListByType
};

module.exports = data;

Please also note the code for grouping drinks into “categories” by type parameter.

The whole file available here:

https://github.com/dominik-w/express-food-app/blob/master/data.js

The next step – node.js (express) application

First, load the required modules and resources (from public/ directory):

var express = require('express');
var app = express();
var path = require('path');
var bodyParser = require('body-parser');

// assets
app.use(express.static(__dirname + '/public'));

// to process post requests
app.use(bodyParser.json());

The bodyParser module will be useful for painless handling POST requests.

In the further part of code we load the input data, prepared before:


// load input test-data
var data = require('./data.js');
var pizzaList = data.pizzaList;
var drinkList = data.drinkListByType;
//console.log(pizzaList); console.log("\n"); console.log(drinkList);

It’s time for routes – the main page and sub-pages:


// main - at http://localhost:8080
app.get('/', function (req, res) {
    res.sendFile(path.join(__dirname + '/index.html'));
});

// app routes
app.get('/pizzas/', function (req, res) {

    // adding some more pizzas
    var localList = pizzaList.slice(0);
    for (var i = 0; i < 30; i++) {
        localList.push({
            name: "Generic Pizza" + (i + 1),
            price: 30 + i,
            details: "Lorem ipsum " + (i + 1),
            img: "img/pizza.jpg"
        });
    }

    res.json(localList);
});

app.get('/drinks/', function (req, res) {
    res.json(drinkList);
});

In case of /pizzas/ route, we’ve added a simple code, where in loops we generate more test data.

At the end we define the submit (POST) action, and the start of the server on port 8080:


// submit process
app.post('/submit', function (req, res) {

    // simply show order data; we can save them in DB,
    // send via API to our pizzeria or whatever we need
    console.log("New order:\n");
    console.log(req.body);

    res.json({msg: 'Success'});
});

// start the server 
app.listen(8080);

The handler implemented in submit action is limited to only displaying coming orders in the console. In the real application we can implement here final actions, such as saving orders in DB, or sending them via API to the pizzeria. Whatever we need 🙂

And well done – our server is ready, but let’s don’t start it for the moment. We have to implement index.html – a page to serve.

But this we will make in part II.

Thank you!

Web and Mobile Apps Developer, with years of experience. A passionate about programming, new technology, e-commerce, as well as sports and cars. A beginner blogger.

Facebook Twitter LinkedIn Google+ Skype Xing 

Share: Share on Facebook1Tweet about this on TwitterShare on Google+1Share on LinkedIn1Share on Tumblr0Digg thisEmail this to someonePin on Pinterest1
You can leave a response, or trackback from your own site.