3 Rendering Views - OpenTechConsult/shoutbox GitHub Wiki
In this project application we will use EJS templates. But we need to keep in mind that almost any template engine in NODE community can be used. EJS is similar to other templating language found in other web development platforms (PHP, JSP, ERB).
Rendering views is very important in nearly every application. Rendering views can concern an entire web page, a fragment of HTML or even an RSS feed. The concept of rendering view is simple. We pass data to a view and that data is transformed to HTML for web applications.
The figure below illustrate how a view creates a new representation of data.
The template that generate the figure above can be found in the following snippet.
<h1><%= name %></h1>
<p><%= name %> is a 2 years old <%= species %>.</p>
Express provides two ways to render views:
- At the application level with
app.render()
- At the response level with
res.render()
which usesapp.render()
internally.
In this project, we'll only use res.render()
. If we look at ./routes/index.js
a function is defined that invokes res.render('index')
in order to render the ./views/index.ejs
as shown in the following code.
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
Before we look at res.render()
closely, let's see how to configure the view system.
Configuring Express view system is very simple. Even though the express
command generated the configuration for us, it's still useful to know what is behind the scenes, so we can make change if necessary.
Configuring the view system generally consist of three things :
- Adjusting the view lookup
- Configuring the template engine
- Enable view caching to reduce file I/O
Here is the snippet of the views setting created by Express.
app.set('views', __dirname + '/views');
This snippet specifies the directory that express will use during view lookup.
It's generally a best practice to use __dirname
so that the application is not dependent on the current working directory being the application's root.
Our application generated by express command has the view engine setting set to ejs . This is because we use -e
command line option. This allows us to render index
instead of index.ejs
. If the -e command-line option is not specified, Express will require the extension in order to determine which template engine is to be used.
The reason Express considers extensions is because the use of extensions allows the use of multiple template engines within a single Express application. Use cases for using several template engine might be for instance the migration from one template engine to another or the ease of use of one template engine to perform a specific task.
Example :
app.set('view engine', 'pug');
app.get('/', function() {
res.render('index');
});
app.get('/feed', function(){
res.render('rss.ejs');
});
The view cache is enabled by default in the production environment. View cache prevents subsequent render()
calls to perform disk I/O. The content of the templates are saved in memory, greatly improving performance.
This setting is disabled in development environment, in order to edit template files without restarting the server.
As illustrated in the following figure, when view cache is disabled, the template is read from disk on every request. When view cache is enabled, the disk is hit only once per template.
Next we are going to see how Express locates views in order to render them.
The way the lookup process works is similar to the way Node's require()
works. When res.render()
or app.render()
is invoked, Express first checks whether a file exists at an absolute path. Next, Express looks relatives to the views directory. Finally, Express tries an index file.
The process is represented in the following flowchart:
Because ejs is set as the default engine, the render
call omits the .ejs extension, and the template file will still be resolved correctly.
Generally, as the application evolves, we will need more views, sometimes several views for a single resource. Using view lookup can help with organization. For example: Create subdirectories related to resource and create views within them.
Subdirectories eliminates redundant parts of names (edit-entry.ejs and show-entry.ejs). Express then add the view engine extension and resolve res.render('entries/edit')
to ./views/entries/edit.ejs
.
Express checks for a file named
index that reside in subdirectories of the view directory.
When files are named with a pluralized resource, such as entries, this