Serving templates with vision

In most situations, when building a web application or website like that of the previous example, you won't just serve HTML files. Although some applications use this approach, where a single HTML is served, and then the JavaScript on the page interacts with the server through APIs to customize the page (commonly referred to as a Single Page App) which would be common in an AngularJS application, most web applications will customize the content served before is sent. This is commonly known as server-side rendering. There has been a lot of innovation in this area recently from client-side libraries such as React, where some of the page is rendered server-side and some on the client. These have been dubbed UniversalJS or Isomorphic JavaScript apps. Those concepts are worth knowing about, but are beyond the scope of this book.

What we will look at in this section is how to do server-side rendering, commonly called templating. In hapi, for templating support, much like with the static content support, we use a hapi plugin called vision (https://github.com/hapijs/vision), which provides all the utilities we need for templating or as vision refers to them: views.

When you register the vision plugin, it decorates the server, request, and reply interfaces with extra methods and utilities to simplify template rendering. Let's look at how to register and configure vision as well as add a route to serve some templates:

const Path = require('path');
const Hapi = require('hapi');
const Vision = require('vision');
const server = new Hapi.Server();
server.connection({ port: 1337 });
server.register(Vision, (err) => {                  // [1]
  server.views({                                    // [2]
    engines: {                                      // [2]
      handlebars: {                                 // [2]
        module: require('handlebars')               // [2]
      }                                             // [2]
    },                                              // [2]
    relativeTo: __dirname,                          // [2]
    path: 'templates'                               // [2]
  });                                               // [2]
  server.route({
    method: 'GET',
    path: '/index',
    handler: function (request, reply) {
      let context = { title: 'Hapi Templates!' };
      return reply.view('index', context);          // [3]
    }
  });
  server.start((err) => {
    console.log(`Server running at: ${server.info.uri}`);
  });
});

Some new concepts have been introduced in the preceding code, but overall it should largely look familiar at this stage. With reference to the numbers given in the code, let's go through some of the new concepts introduced therein:

  • [1]: We register the Vision plugin, similar to the inert example. This provides us with the decorated server, request, and reply interfaces.
  • [2]: We use the new server.views() interface to register a view engine. Although hapi supports most view engines, here we are using handlebars, as it is simple and widely used. Take note of the engines key here. Specifically, we are stating that handlebars is the templating engine for the HTML files here. Finally, we just specify where the templates are found.
  • [3]: Here we use the new reply.view() interface. This is of the form reply.view(template, [context]) where the template is the file, and context is an object of values that will map to the placeholders in the template.

So for the previous example, let's create a template called index.html:

<html>
  <body>
    <h1>{{title}}</h1>
    <p>This is hard coded</p>
  </body>
</html>

With reply.view() called it would return the following:

<html>
  <body>
    <h1>Hapi Templates!</h1>
    <p>This is hard coded</p>
  </body>
</html>

Even though this is a very trivial example, it hopefully demonstrates clearly how simple templating is in hapi, and how powerful it can be in generating customized pages per request.

Let's look at some of the extra options for configuring template engines in hapi.

Vision configuration

For the full options available when configuring vision, I encourage you to read the module README.md at https://github.com/hapijs/vision, but I will briefly discuss the need-to-know parts here. These parts are as follows:

Engines

In order to use templates in hapi and vision, you have to register at least one templating engine, which will be the default for all file extensions. If more than one templating engine is registered, file extensions need to be matched to the templating engine, for example:

…
server.views({
  engines: {
    html: {
      module: require('handlebars')
    },
    jsx: {
      module: require('jsx')
    }
  }
  relativeTo: __dirname,
  path: 'templates'
});
…

Paths

The paths option in vision is for configuring the locations of all your template files. We have seen examples of some of these with relativeTo and path already.

Some templating engines like handlebars have methods for reducing boilerplate, and making it easier for breaking up templates such layouts, partials, and helpers. If you want to learn more about these, I recommend reading the description in the particular templating engine, but the good news is that they are also supported by vision.

compileMode

By default, vision assumes template engines to be synchronous, but asynchronous templating engines are also supported. If you are using a templating engine that requires an asynchronous render, just override the default when registering the engine as follows:

server.views({
  engines: {
    'html': {
      module: require('someasyncrenderingengine'),
      compileMode: 'async' // engine specific
    }
  }
});

Vision summary

This covers most of what you need to be able to render templates with hapi. Of course, templating is a much bigger topic, and I've only explored what you need to get started with templating here with hapi. To learn more about templating, I suggest you read more about the different templating methods today, like handlebars, dust, and jsx, which all attempt to simplify view rendering in their own ways.

Note

Like the last chapter, all code samples seen in here as well as some extra material can be found online in the repository available at https://github.com/johnbrett/Getting-Started-with-hapi.js. If you have any questions about the code samples in trying to understand code snippets or problems running them, feel free to open an issue.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.80.209