6

I try to render html with ejs like this

const ejs = require('ejs'),
      fs = require('fs'),
      str = fs.readFileSync(`${__dirname}/../mail_templates/test.ejs`, 'utf8');

console.log(ejs.render(str, {name: 'abc'});

test.ejs

<%- include(`header.ejs`)%>
...

But got this error:

Error: ejs:1
>> 1| <%- include(`header.ejs`)%>

Could not find the include file "header.ejs"
...

Here is how the folder structure look like:

enter image description here

Can you tell me why? I also tried these cases but no hope:

<% include header.ejs %>
<% include header %>
<%- include('header.ejs'); -%>
<%- include('../mail_templates/header.ejs'); -%>
<%- include('mail_templates/header.ejs'); -%>
<%- include('./mail_templates/header.ejs'); -%>

The only case that work is to use the absolute path:

<%- include("/Users/admin/Work/engine/mail_templates/header.ejs")%>

But of course I don't want to use this.

0

2 Answers 2

12

Includes are relative to current template. In order for the engine to be aware of current template path, it should be specified with filename option, something like:

const templatePath = `${__dirname}/../mail_templates/test.ejs`;
str = fs.readFileSync(templatePath, 'utf8');

ejs.render(str, {filename: templatePath, name: 'abc'});

Then it's expected that any of these includes will work:

<% include header.ejs %>
<% include header %>
<%- include('header.ejs'); -%>
<%- include('./header.ejs'); -%>
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, saved my day! Though the it worked bit differently for me, filename is the key! I have added my code which worked for me since the options bit changed now
1

Thanks to @Estus Flask. Looking at his answer, I checked documentation and it worked for me. so adding the code here for reference.

Now ejs.render accepts, check EJS documentation

ejs.render(str, data, options);

So, in my case below code worked

const templatePath = path.resolve(__dirname, '../../../templates/parent.ejs');
const ejsTemplate = fs.readFileSync(templatePath, 'utf8');

const html = ejs.render(ejsTemplate, { data: data }, {filename : templatePath}); //I need to pass data. so used data object

As documentation says,

filename Used by cache to key caches, and for includes

In .ejs file I include partial templates as

<%- include('partials/child'); -%>

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.