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)
воздушно пузырчатая пленка купить. email marketing agency
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!