3

Does anybody know a nice solution for including templates, whose names would be known only at run time? EJS's includes allows only to specify exact file/template name.

Use case: I have a article layout and there is article HTML/EJS content in some local file.

To do so I need something like https://github.com/visionmedia/ejs#includes but file name should be taken from locals variable:

Assume I have such handler (simplified):

app.get('/article/:article', function (req, res) {
        var articleContent = req.params.article;
        res.locals.articleContent = 'data/'+articleContent;
        return res.render('article.ejs')
    })

And in article.ejs (assume having ejs-locals):

<% layout('layout') -%>
<section>
  <article class="single-country">
      <% include ???articleContent???  %>
  </article>
</section>

Is there any possibility to do so or is the only option is to load article content and put into articleContent, so available by <%- articleContent %>?

The problem with this solution is that the content of article should be plain html (`<%- -%>' do not interpolate value). So if inside article I need to use any EJS feature, I need to compile/render by myself.

Maybe someone else already knows how this can be done with some dynamic include helper for EJS so no need of additional code?

3
  • I've edited your question as it was very hard to read. Please revert my changes if it changed the meaning. Also, what do you mean by file name should be taken from variable.? Do you have the content shared among multiple files? Also, I don't understand the whole content of the article should be plain HTML problem Commented Dec 25, 2013 at 23:46
  • Sorry... My thoughts were focused on finding solution. Changed text to be more understandable :) Commented Dec 26, 2013 at 0:59
  • AFAIK this is possible with EJS and express by employing the VM module, it felt messy to me and , as I was on the fence, between EJS and DUST, I went with DUST for a current project. - here is a dynamic named partial 'included template file with DUST - {>"{dynamicvalue}.dust"/} . I hope there is a simpler answer for ejs as I like it. Commented Dec 27, 2013 at 12:49

2 Answers 2

2

Looks like this is now supported in EJS. It was introduced in v2.0.1: 2015-01-02. The new syntax looks like this

 <%- include(articleContent) %>

To get this to work I had to disable caching in Express by setting:

app.set('view cache', false);
Sign up to request clarification or add additional context in comments.

Comments

0

You can use a filter like this:

var ejs = require('ejs');
var fs = require('fs');

ejs.filters.article_teaser = function(my_object) {
    return ejs.render(fs.readFileSync(__dirname + '/views/' + my_object.template + '.ejs', 'utf8'), {my_object: my_object});
}

On your template just use:

<%-: article | article_teaser %>

Cheers!

2 Comments

Interesting workaround. But in this case from inner "render" parent scope/context would not be accessible... So it is like "isolated" rendering and not actual include...
EJS ^2.0.* supports this feature: Variable-based includes now possible

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.