Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render multiple .ejs files in nested form in Node.js and Express?

How can I render multiple .ejs files in a nested form?

So I have the following file:

var mysql = require('mysql');
var ejs = require('ejs');
exports.index = function(req, res){
    if (req.method=='POST'){
        var connection = mysql.createConnection({user:'root', password:'root', database:'testdb'});
        var name = req.param('name');
        connection.query('select * from table_name where name = ?', name, function(err, rows, fields){
            if(err) throw err;
            res.render('index', {
                 title: 'title', content: res.render('index2', {data:rows})
            });
        });
    }
});

Where index.ejs consists of very basic html tag (say html, head, body, and one p tag) and have <%- content %> in it, where content is assumed to be rendered by another .ejs file, which doesn't include html, head, or body tag and is only assumed to be rendered a content and a title. However, when I accessed to this file by POST request and tried to render files and then checked out the outputted HTML file from my browser, the content consisted only of index2.ejs file, which means it has no html, body, head tag.

So what am I missing? And if I want to include a Javascript library by <script src='some_file.js'></script>, should I add another rendering property when I try to render in index2.ejs file...right?

like image 529
Blaszard Avatar asked Jun 09 '13 21:06

Blaszard


People also ask

What is render in Express JS?

Build The Complete Portfolio Website with HTML CSS BS JS JQ 14 Lectures 4.5 hours. More Detail. The app. render() method is used for returning the rendered HTML of a view using the callback function. This method accepts an optional parameter that is an object which contains the local variables for the view.

What is .EJS file?

EJS (Embedded JavaScript Templating) is one of the most popular template engines for JavaScript. As the name suggests, it lets us embed JavaScript code in a template language that is then used to generate HTML.


2 Answers

First, I think you are confused on how res.render operates. According to the docs:

res.render(view, [locals], callback)

Render a view with a callback responding with the rendered string.

which explains why you are only seeing the content of index2.ejs in your HTML page.


Now, there are multiple ways to achieve your goal, which is nesting views within views. Starting from Express 3.x, you need to use include.In this case, you can rewrite your views like this:
1- Define a header.ejs file, which would look like this example.
2- Define a footer.ejs. which would look like this other example.
3- In your index2.ejs, include these two files, like this:

<% include header %>
    //The HTML of your index2.ejs
    //You can add some reusable views, like, say, a submit button above the footer
    <% include reusable_views/submit %>
<% include footer %>

A second method is to use ejs-locals, which allows you to insert any view by only specifying their path:

res.render('index', {
                 title: 'title', 
                 content: 'index2', 
                 data:rows
            });

And, in your index1.ejs, you will have:

<html><head>
<title><%= title %></title></head>
<body><p>
<%- partial('index2',{}) %>
</p></body></html>

The advantage of this method is you can pass extra values to your view, using the extra object. Check out the ejs-locals github page for more details.

like image 95
verybadalloc Avatar answered Nov 11 '22 11:11

verybadalloc


Update : ejs-mate Express 4.x locals for layout, partial.

https://www.npmjs.com/package/ejs-mate

cf https://scotch.io/tutorials/use-ejs-to-template-your-node-application

like image 28
nico6 Avatar answered Nov 11 '22 09:11

nico6