Using interpolation within Node.js EJS includes

寵の児 提交于 2019-12-04 16:28:12

问题


My Express app is using EJS, and my views directory looks like this:

./views
  ./contents
    home.ejs
  ./includes
    header.ejs
    footer.ejs
  layout.ejs

I'm trying to load home.ejs in my layout.ejs view conditionally based on a local variable named contents in my routes/index.js. That file looks like this:

/*
 * GET home page.
 */

exports.index = function(req, res){
  res.render('index', { title: 'Home', contents: 'home.ejs' });
};

Ideally I could simply write (in layout.ejs):

<% include '/contents' + contents %>

where the trailing "contents" is the local variable which contains the relative path to the body text to load.

But alas, it appears EJS always interprets the text following an include directive literally, and there is no chance for any interpolation magic to happen.

I've also tried to no avail:

<% function yieldContent(contents){ %>
  <% var contentPath = 'contents/' + contents; %>
  <% include contentPath %>
<% }; %>
<% loadContent(); %>

Does anyone have a creative solution for conditionally including a view based on a variable passed in routes?


回答1:


I think there is no way to do this kind of dynamic includes in EJS. It might break the separation of business logic and view. The solution can be to rendering the subtemplate in the controller, and passing its content to the layout.

For rendering subtemplate in the controller use something like this:

var ejs = require('ejs'),
, fs = require('fs')
, home = ejs.render(fs.readFileSync("contents/home.ejs", "utf-8"))



回答2:


In the version 2 of EJS, the include function does it well. With it, includes are inserted at runtime so variables can be used as pathnames.

In this case, the solution may be :

<%- include('contents/' + contents) %>

The function can also have another argument if necessary :

<%- include('mypathname', {foo:"bar"}) %>

The pathname has to be relative to the template which calls the function.




回答3:


Currently this hasn't been implemented into ejs but, there is this discussion and pull request that offers the functionality.

https://github.com/visionmedia/ejs/issues/93




回答4:


in your render function you can include fs.readFileSync and __dirname.

Render your page with options like this

res.render('pages/'+req.file,{file_get_contents:fs.readFileSync,__dirname:__dirname});

Then you can use it in your .ejs page like this. This remains in server side.

<% var products=JSON.parse(file_get_contents(__dirname+'/web/data/products.json','utf8')) %>

You can print the data on client HTML like this.

<%- JSON.stringify(products)%>

Note : Using this method means you have fs included somewhere at the top of your script.

var fs = require('fs')


来源:https://stackoverflow.com/questions/11804691/using-interpolation-within-node-js-ejs-includes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!