HandlebarsJs is a simple and powerful templating language that uses templates and input objects to generate HTML or other text formats.

Create powerful webapps using handlebars.js

The provided screenshot showcases an application that we developed utilizing Handlebars.js. This application utilizes Handlebars.js to list products, demonstrating the usefulness of templating libraries. We have employed a similar approach to create a comprehensive headless e-Commerce solution for our client.

The functioning of Handlebars.js can be simplified as follows:

Template + Data + Compile = HTML

To create this application, we utilized two JavaScript libraries: jQuery and Handlebars.js.

<script src="https://code.jquery.com/jquery-3.7.0.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"></script>

Data

For this example the json formatted data is stored in data.json with below format. Full source at the end.

{
    "mainEntity": [
        {
            "id": "tomato",
            "name": "Tomato 1Kg",
            "mrp": "99",
            "price": "30",
            "buy": "5Kg",
            "get": "1Kg"
        },
        ....
}

Template

The code is a Handlebars template that is used to render the json data to HTML.

<script id="handelbarTemplateShop" type="text/template">
  {{#each mainEntity}} 
    <div class="col">
      <div class="card card-product" style="width: 150px;">
        <img loading="lazy" class="card-img-top" src="./image/veg/{{this.id}}.png" alt="Vegetable" width="150" height="150">
        <div class="card-body ps-1">
          <h3 class="card-title"><a href="#" class="stretched-link">{{this.name}}</a></h3>
          <p class="card-text"><span class="text-danger fs-4">{{this.price}}</span>
            <span class="text-decoration-line-through text-secondary">{{this.mrp}}</span>
            <br><span class="badge bg-primary text-light">Buy {{this.buy}}</span>
            <br><span class="badge bg-danger text-light">Get {{this.get}} Free</span>
          </p>
        </div>
      </div>
    </div>
  {{/each}}
</script>

By utilizing the built-in #each helper in Handlebars.js, we can easily iterate over an array. Within the iteration block, we can refer to the current element using the ’this’ keyword, which allows us to access the current context in any given context.

In the specific case mentioned, for each item in the mainEntity array, a product card is generated. The product card includes details such as the item’s id, name, price, mrp, buy, and get properties.

Compile & Render handlebars.js Template

<script>
  $.getJSON("/data.json", function (data) {
    var template = $('#handelbarTemplateShop').html();
    var output = Handlebars.compile(template)(data);

    $('#shop').html("");
    $('#shop').append(output);
  })
</script>

.

Above code is almost self explanatory

  • jQuery getJSON() method used to loads data from the /data.json file.
  • Handlebars.compile() compiles the template with data fetched by getJSON()
  • Append the html generated by Handlebars

Full Code

File: index.html

<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Fresh Vegetables &amp Fruits</title>
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
    integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
  
  <style>
    .card-product {
      border: 1px solid #fff;
    }

    .card-product:hover {
      border: 1px solid rgba(0, 0, 0, 0.4);
    }

    .card h2,
    .card h3,
    .card a {
      font-size: 1rem;
      text-decoration: none;
      color: #333;
      opacity: 100%;
    }

    .card h2,
    .card h3 {
      border-left: 3px solid #333;
      padding-left: 5px;
    }

    main {
      flex-grow: 1;
      padding-bottom: 50px;
    }

    footer {
      position: sticky;
      bottom: 0;
      height: 50px;
      background-color: #f5f5f5;
    }
  </style>

</head>

<body>
  <div class="container-fluid text-center py-2">
    <div class="row">
      <div class="col align-self-start">
        <h1><img src="./image/banner.jpg" class="img-fluid rounded" alt="Fresh Vegetables &amp Fruits"></h1>
      </div>
    </div>

  </div>
  <main class="container-fluid py-4">
    <div id="shop" class="row row-cols-auto justify-content-center justify-content-md-start">
      <div class="col align-self-center">
        <div class="spinner-border text-center" role="status">
          <span class="visually-hidden">Loading Products...</span>
        </div>
      </div>
    </div>
  </main>


  <footer>
    <p class="pt-2">
      <button type="button" class="btn btn-light">To Order</button>
      <a class="btn btn-success" href="https://wa.me/919876543210?text=Website%20I%20want%20to%20place%20order"
        role="button">Whatsapp</a>
      <a class="btn btn-primary" href="tel:9876543210" role="button">Call Us</a>
    </p>
  </footer>

  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4"
    crossorigin="anonymous"></script>
  <script src="https://code.jquery.com/jquery-3.7.0.min.js"
    integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"></script>

  <script id="handelbarTemplateShop" type="text/template">
      {{#each mainEntity}} 
        <div class="col">
          <div class="card card-product" style="width: 150px;">
            <img loading="lazy" class="card-img-top" src="./image/veg/{{this.id}}.png" alt="Vegetable" width="150" height="150">
            <div class="card-body ps-1">
              <h3 class="card-title"><a href="#" class="stretched-link">{{this.name}}</a></h3>
              <p class="card-text"><span class="text-danger fs-4">{{this.price}}</span>
                <span class="text-decoration-line-through text-secondary">{{this.mrp}}</span>
                <br><span class="badge bg-primary text-light">Buy {{this.buy}}</span>
                <br><span class="badge bg-danger text-light">Get {{this.get}} Free</span>
              </p>
            </div>
          </div>
        </div>
      {{/each}}
  </script>

  <script>
    $.getJSON("/data.json", function (data) {
      var template = $('#handelbarTemplateShop').html();
      var output = Handlebars.compile(template)(data);

      $('#shop').html("");
      $('#shop').append(output);
    })

  </script>
</body>

</html>

File: data.sjon

{
    "mainEntity": [
        {
            "id": "tomato",
            "name": "Tomato 1Kg",
            "mrp": "99",
            "price": "30",
            "buy": "5Kg",
            "get": "1Kg"
        },
        {
            "id": "potato",
            "name": "Potato 1Kg",
            "mrp": "50",
            "price": "46",
            "buy": "5Kg",
            "get": "1Kg"
        },
        {
            "id": "eggplant",
            "name": "Brinjal 250g",
            "mrp": "120",
            "price": "99",
            "buy": "5Kg",
            "get": "1Kg"
        },
        {
            "id": "okra",
            "name": "Okra 100g",
            "mrp": "28",
            "price": "25",
            "buy": "200g",
            "get": "50g"
        },
        {
            "id": "radish",
            "name": "White Radish 250g",
            "mrp": "55",
            "price": "30",
            "buy": "500g",
            "get": "200g"
        }
    ]
}