29

Okay I have a mostly static homepage but I wanted to have partial views that for navigation, footer ect. I'm using ejs and it looks like this:

my controller: home.js

// Dependencies
var express = require('express');


    module.exports = {
        get: function(req, res) {
            app.set('view engine', 'ejs');  
            var model = {
            layout:'home',
                    };


            res.render('home');


        }
    };

My views directory has nav, home and footer all .ejs

Then the actual html file stripped of text would look as following.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" >
<title>Tom Jones</title>

<!-- CSS -->
<link rel="stylesheet" href="/css/home.css" type="text/css" media="screen" >

</head>
<body>

<%- partial('nav') %>

<!--content part -->  
<div id="showcontainer">
        <section>

        </section>
</div>

<div id="maincontainer">
        <section>

        </section>
</div>

</body>
</html>

The Problem When ever I test it out I run into the error partial is not defined. I tried requiring ejs but no success.

lostAstronaut
  • 1,331
  • 5
  • 20
  • 34

2 Answers2

60

As @Pickels said, Partial was removed in 3.x. However, the most recent version of EJS provides a mechanism for including "partials", called "include":

https://github.com/visionmedia/ejs#includes

Includes are relative to the template with the include statement, for example if you have "./views/users.ejs" and "./views/user/show.ejs" you would use <% include user/show %>. The included file(s) are literally included into the template, no IO is performed after compilation, thus local variables are available to these included templates.

The following will work as a replacement for your old partial() function. You'll need to make tweaks elsewhere to support Express 3.x completely, but for the most part this seems to work well (better actually - less code and more performant).

<% include nav.ejs %> <!-- replaces your old <%- partial('nav') %> -->

Now in ejs 3.1.x

<% include('relative_filepath'); %>

Must be replaced by

<%- include('relative_filepath'); %>

ht006
  • 134
  • 13
Joshua
  • 3,615
  • 1
  • 26
  • 32
  • 3
    Thing to watch out for here is you need to include the filename: http://stackoverflow.com/a/13537052/131809 – Alex Nov 24 '12 at 12:21
  • Also, the layout section on the ejs site has an example of using includes https://github.com/visionmedia/ejs/blob/master/Readme.md#layouts to support something like what you are looking for. – Hector Correa Dec 13 '12 at 14:52
  • Any idea how to include a partial in a parent directory? Using `../path/partial` doesn't work at all... – Vadorequest Aug 16 '14 at 09:49
  • 1
    @Vadorequest Path might need to come from the app root, otherwise context is assumed. – Joshua Aug 18 '14 at 22:03
  • huh but what happened to EJS's <%- body %> tag ?? – Alexander Mills Mar 16 '15 at 22:12
  • When I see a minus like `<%- include('../helper.ejs') %>`, can I be sure, this is wrong? Harmless, since no returned output, but wrong? – Frank N Jun 09 '16 at 07:44
  • apparently the new syntax broke something, so the latest ejs (3.1.x) reverts to using this syntax: `<%- include('nav.ejs'); %>`. – ericfossas Jan 03 '21 at 17:20
  • @Joshua how do we have something like this `<%- include('../../'+<%= isReleaseDirectory %>+'/components/headercontent.html'); %>` how to concatenate ejs render within include render ? – Rizwan Patel Jul 26 '22 at 20:55
4

Partial was removed in 3.x. It's now up to the templating engine to provide partials.

Pickels
  • 33,902
  • 26
  • 118
  • 178
  • ejs. There is a bridge project for express.js and a lot of templating engines which is called consolidate.js and can be found here: https://github.com/visionmedia/consolidate.js – Pickels Jul 05 '12 at 22:42
  • 6
    Ironically, this is only a 'partial' answer. Can you provide an explanation on how to make Partials work in express 3.x and EJS using consolidate.js? – Joshua Aug 06 '12 at 20:35