Lesson 10. Connecting views with templates

In lesson 9, you constructed a routing system for your Express.js application. In this lesson, you learn about templating engines and see how to connect your routes to views. You learn how to work with Embedded JavaScript (EJS), a syntax for applying Java-Script functions and variables within your views, as well as how to pass data into those views from your controllers. You start by setting up EJS with your application and seeing how templating engines work. By the end of the lesson, you’ll understand the syntax needed to master EJS in your Express.js applications. At the end of the lesson, you install the express-ejs-layouts package to use dynamic layouts in your application.

This lesson covers

  • Connecting a templating engine to your application
  • Passing data from your controllers to your views
  • Setting up Express.js layouts
Consider this

You have some wireframes laying out how your application pages will look, and you notice that many of the pages share components. Your home page and contact page both use the same navigation bar. Instead of rewriting the HTML representing the navigation bar for each view, you want to write the code once and reuse it for each view.

With templating in a Node.js application, you can do just that. In fact, you’ll be able to render a single layout for all your application pages or share view content in code snippets called partials.

10.1. Connecting a templating engine

In lesson 9, you reorganized your routes to serve responses with Express.js routing methods and an MVC application structure. The next step is using your routes to respond with more than single lines of text. As in unit 1, you’ll render separate files, but these files aren’t purely HTML, and you won’t explicitly need the fs module to serve them.

Part of what makes Express.js so popular is its ability to work with other packages and tools. One such tool is the templating engine. Templating allows you to code your views with the ability to insert dynamic data. In this book, you’ll be writing your views in HTML with EJS—data in the form of JavaScript objects embedded in the page with special syntax. These files have the .ejs extension. There are many templating languages like EJS, but this book assumes that you have moderate experience with HTML, and EJS proves to be the most effective and simplest templating language to learn with that background. If you want to explore other templating engines, consider some of the ones listed in table 10.1.

Table 10.1. Templating engines

Templating engine

Description

Mustache.js Without the custom helpers offered by Handlebars.js, this templating engine is simple and lightweight, and it compiles for many languages other than JavaScript (https://mustache.github.io/).
Handlebars.js Functionally similar to EJS, this templating engine focuses on the use of curly brackets, or handlebars, for inserting dynamic content into your views (http://handlebarsjs.com/).
Underscore.js In addition to other JavaScript functions and libraries, this engine offers templating with customizable syntax and symbols (http://underscorejs.org/).
Pug.js This engine offers syntax similar to Jade in Ruby, abbreviating HTML tag names for simplicity, and is indentation-sensitive (https://pugjs.org).

A templating engine is what Express.js uses to process your views and convert them to browser-readable HTML pages. Any non-HTML lines are converted to HTML, with values rendered where embedded variables once were. See figure 10.1 to understand the conversion process.

Figure 10.1. Converting EJS to HTML

In a new application project called express_templates, initialize your application, install express as a dependency, and create your controllers folder with a home controller. In your main.js file, require the normal Express.js module and app object, homeController.js, and set your server to listen on port 3000. Next, install the ejs package with the following terminal command: npm install ejs --save.

Note

You can also install express and ejs in one line by running npm install express ejs --save.

The set method

set is often used to assign values to predefined configuration variables used by your application. Those variables, called application settings properties, are listed at https://expressjs.com/en/api.html#app.set. Some variables are used by app itself to allow your application to function on your computer. Assigning variables with set is another way toset the application’s configurations.

You’ve been setting the port for your application to 3000. Although 3000 is a conventional port number used in web development, the port number won’t stay the same when the application is deployed online.

app.set lets you assign a value to some key that you plan to reuse in your application. The following code will set port to the environment variable PORT value or 3000 if the former value is undefined. You could use app.set("port", process.env.PORT || 3000);, forexample.

To use this set value, you need to replace your hardcoded 3000 at the end of the application main.js file with app.get("port"). Similarly, you could run app.get("view engine"). Now you can even replace your console.log with a more dynamic statement, such as console.log(`Server running at http://localhost:${ app.get("port") }`);

Restart this application with the added code to make sure that it still runs correctly.

Now that the ejs package is installed, you need to let your Express.js application know that you plan to use it for templating. To do so, add app.set("view engine", "ejs") below your require lines in main.js. This line tells your Express.js application to set its view engine as ejs. This line is how your application knows to expect EJS in your views folder in your main project directory.

Now that your application is ready to interpret EJS, create an index.ejs file in your views folder with the code in listing 10.1. In this code, you use the EJS syntax <% %> to define and assign a variable within your view. Everything within these characters runs as valid JavaScript. Each line of HTML contains an embedded variable. By using <%= %>, you’re able to print that variable’s value within the HTML tags.

Listing 10.1. Sample EJS content in your index.ejs view
<% let name = "Jon"; %>            1
<h1> Hello, <%= name %> </h1>      2

  • 1 Define and assign a variable in EJS.
  • 2 Embed a variable within HTML.

Last, create a route in main.js for the /name path. You can think of a name for the controller function that relates to what the function will do. The following example calls the function respondWithName: app.get("/name", homeController.respondWithName). This route runs when a request is made to the /name path; then it calls the respondWithName function in the home controller.

In homeController.js, add the respondWithName function as shown in the next listing. You use the render method on the response object to respond with a view from your views folder.

Listing 10.2. Rendering a view from a controller action in homeController.js
exports.respondWithName = (req, res) => {
  res.render("index");                        1
};

  • 1 Respond with a custom EJS view.
Note

Notice that you don’t need the .ejs extension for the index.ejs view, and you don’t need to specify the folder that this view lives in. Express.js takes care of all that for you. As long as you continue to add your views to the views folder and use EJS, your application will know what to do.

Restart your application, and visit http://localhost:3000/name in your browser. If you run into any issues, try reinstalling the ejs and express packages, and make sure that your files are in the correct folders.

In the next section, I talk about passing data from the controller to your EJS views.

Quick check 10.1

Q1:

What is a templating engine?

QC 10.1 answer

1:

A templating engine is the tool that Express.js uses in your application to process a template view. Because template views contain a mix of HTML and JavaScript content, the engine’s job is to convert this information to an HTML file that your browser can use.

 

10.2. Passing data from your controllers

Now that your templates are rendering, the best way to use them is to pass data from your controllers to your views instead of defining those variables directly in the view. To do so, remove the line in index.ejs that defines and assigns the name variable, but keep the H1 tag and its EJS contents.

Change your route to take a parameter in its path and then send that parameter to the view. Your route should look like the following code: app.get("/name/:myName", home Controller.respondWithName). Now the route takes a parameter at the end of the /name path.

To use this parameter, you need to access it from your request params in the home -Controller.respondWithName function. Then you can pass the name variable to your view in a JavaScript object. Your function should look like the code in the following listing. In this code block, you set the route parameter to a local variable; then you pass the name variable as a value for the name key (which should match the variable name in your view).

Listing 10.3. Passing a route parameter to your view in homeController.js
exports.respondWithName = (req, res) => {
  let paramsName = req.params.myName;                1
  res.render("index", { name: paramsName });         2
};

  • 1 Assign a local variable to a request parameter.
  • 2 Pass a local variable to a rendered view.

Restart your application, and visit http://localhost:3000/name/jon in your browser.

Warning

/name/jon is a different path from /name/. If you don’t add a name as a route parameter, your application will complain that no route matches your request. You must add some text following the second forward slash in the URL.

In the next section, I talk about layouts and partials, and discuss how they allow you to write less code to get the same results in your views.

Quick check 10.2

Q1:

What is the format in which you send data from your controller to a view?

QC 10.2 answer

1:

To send data from your controller, you can pass a variable within a JavaScript object. The variable that’s local to your controller’s context follows the key, whose name should match the variable name in your view.

 

10.3. Setting up partials and layouts

In the preceding two sections, you introduced dynamic data to your views. In this section, you set up your views a little differently so that you can share view content across multiple pages.

To start, create an application layout. A layout is a shell in which your views are rendered. Think of layouts as being the content that doesn’t change from page to page when you browse a website. The bottom (footer) of the page or navigation bar might stay the same, for example. Instead of re-creating the HTML for these components, add them to a layout.ejs file that other views can share.

To do so, install the express-ejs-layouts package, and require it in your main.js file by layouts = require("express-ejs-layouts"). Then let Express.js know to use this package as an additional middleware layer by adding app.use(layouts) to your main.js file.

Next, create a layout.ejs file in your views folder. You can start with some simple HTML in the layout file, as shown in the next listing. The body keyword is used by Express.js and the layout express-ejs-layouts to fill your other views’ contents in its place.

Listing 10.4. EJS layout file contents in layout.ejs
<body>
  <div id="nav">NAVIGATION</div>
    <%- body %>                        1
  <div id="footer">FOOTER</div>
</body>

  • 1 Wrap body with boilerplate HTML.

When you visit a route that renders a view, you’ll notice the navigation and footer text with your rendered view in between. This layout will continue to render along with your view on every page load. To see, restart your application, and visit the /name/:myName path in your browser.

Partials work similarly to layouts. Partials are snippets of view content that can be included in other views. In your recipe application, you may want to add a notification box on a few of the pages. To do so, create a partial called notification.ejs, and add it to select EJS views by using the include keyword. To create a partial for the navigation element, move your code for that div to a new file called navigation.ejs. Place that file in a new folder called partials within your views folder. Then include that file within your layout.ejs file by using the following code: <% include partials/navigation %>. With a little styling, your view should resemble figure 10.2.

Figure 10.2. Example view of name page

Within the EJS carets, use the include keyword followed by a relative path to your partial. Because the layout is already in the views folder, it needs to look in the partials folder on the same directory level to find the navigation partial.

Restart your application, and visit the /name/:myName path again. If everything was set up correctly, nothing in that view should have changed since the addition of a layout file. To prove that the partial is working, try changing the text in the navigation partial or adding new tags to see how content changes in your browser.

Note

When making changes in your views, you don’t need to restart your application.

Now you have an application using an EJS templating engine, a layout, and partials that accept dynamic data. In lesson 11, you learn about handling errors and adding some configurations to your package.json file.

Quick check 10.3

Q1:

What keyword do you use to share partials across multiple views?

QC 10.3 answer

1:

The include keyword looks for a partial in the relative path provided and renders it in place.

 

Summary

In this lesson, you learned how to use templates in your application with EJS. You also learned how to pass data from your controllers to application views. At the end of the lesson, you learned how to create a layout with the express-ejs-layouts package and partials to share content across your views. In lesson 11, you add a configuration to start your application with a different command and handle errors with new middleware functions.

Try this

Now that you have templates, partials, and a layout in your application, you should use them to create multiple views. Try creating a contact page for your recipe application that uses your application layout and a partial that renders a notification box called notificationBox.ejs. Add this partial to your index.ejs view as well.

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

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