3

I have a header.html and a footer.html which I would like to be rendered along with other views. I want to accomplish this using Node+Express. I tried to render views in the following way but clearly it doesn't work:

var express = require('express');
var app = express();
app.get('/', function(req, res) {
    res.render('header');
    res.render('home');
    res.render('footer');
});
3
  • Render home and include in it the header and footer isn't an option? Commented Feb 1, 2015 at 19:00
  • 1
    The problem is I need each of the views to decoupled from each other so that they can be reused for other purposes later. Commented Feb 1, 2015 at 19:05
  • But you can 'include' the html or the jade and keep the 3 components decoupled Commented Feb 1, 2015 at 19:07

3 Answers 3

1

You have to set a template engine to your project. You can use Swig for instance, it works very nice and it is well documented.

The example below, shows you how to set it and how you can call partial views from a layout or master page.

Install it by doing npm install swig --save on your project root. You need to install an additional library called consolidate which acts as interface among different template engine libraries, it is kind of standard in express applications.

npm install consolidate --save

require the library in your main script with

consolidate = require('consolidate');
swig = require('swig');

Configure it as follows:

app.engine('html', cons.swig);
app.set('view engine', 'html');
app.set('views', __dirname + '/views'); // set your view path correctly here

Then you can render a page as:

app.get('/', function (req, res) {
  res.render('index', {});
});

(Example taken from Swig's author, Paul Armstrong github page) Layout.html:

<!doctype html>
<html>
<head>
    <meta charset="utf-8" />
    <title>{% block title %}{% endblock %} - Example</title>
</head>
<body>
    <header>
        <h1>{% block title %}{% endblock %}</h1>
        {% block header %}{% endblock %}
        <nav>
            <ul>
                <li><a href="/">Home Page</a></li>
                <li><a href="/people">People</a></li>
            </ul>
        </nav>
    </header>

    <section role="main">
        {% block body %}{% endblock %}
    </section>

</body>
</html>

Index.html:

{% extends 'layout.html' %}

{% block title %}Home Page{% endblock %}

This way, you can decoupled your views as you need :)

Sign up to request clarification or add additional context in comments.

Comments

0

When you are using pug, you can take an advantage of include feature, like @Kangcor suggestion

home.pug

html
  head
    include ./path/to/header.pug
    title= title
  body
    ...
    include ./path/to/footer.pug

Comments

0

You can use Handlebars partial views Here is a well documented library https://handlebarsjs.com/guide/partials.html#basic-partials

Install hbs https://handlebarsjs.com/installation/#npm-or-yarn-recommended

npm install handlebars

Configure Handlebars

// import library on the your start js file ie: app.js || index.js
let hbs = require('hbs');

// view engine setup
app.set('views', path.join(__dirname, 'views'));
hbs.registerPartials(__dirname + '/views/partials');
app.set('view engine', 'hbs');

Create your partial views ie: header.hbs and footer.hbs on the partials directory

Create a file layout.hbs and you can call the partial view as follows

<div>
{{> header}}
{{> body}}
{{> footer}}
</div>

Then when calling

res.render("home", {});

home.hbs will be mapped as the body and the footer and header will be added to the layout.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.