[英]How to do multi-render with Node.js, EJS Template and dynamic file name
我將Node.js與Express和EJS模板一起使用,並且希望動態管理HTML Templace。
這次,我有:
- server.js
- views/
- - template.ejs
- - layout.ejs
在server.js中,我使用數據加載模板視圖,並使用<% include %>
加載模板上的布局:
server.js
var data = { some: 'stuff'};
res.render('template', data);
template.ejs
<% include layout %>
在這一點上,代碼工作得很好,並且我得到了預期的結果。
但是現在,我想要一個數據變量,例如布局的文件名,可以在layouts /目錄中使用:
- server.js
- views/
- - template.ejs
- - layouts/
- - - home.ejs
- - - login.ejs
server.js
var data = {
layout_view: 'layouts/home'
};
res.render(template, data);
template.ejs
<% include layout_view %>
但是,不會對變量進行求和,並且僅測試變量的名稱,而不測試值:
錯誤:ENOENT,沒有這樣的文件或目錄'C:\\ Users \\ Arthur \\ Desktop \\ Node-www \\ G \\ views \\ layout_view.ejs
如何使用<% include %>
命令和變量加載視圖'views / layouts / home.ejs'?
謝謝你們 ! :)
這是我在Express 4(用於ejs測試)中用於布局的內容:
/*
Usage:
Set a global/default layout with:
app.set('view layout', 'bar');
Set a layout per-render (overrides global layout) with:
res.render('foo', { layout: 'bar' });
Or disable a layout if a global layout is set with:
res.render('foo', { layout: false });
If no layout is provided using either of the above methods,
then the view will be rendered as-is like normal.
Inside your layout, the variable `body` holds the rendered partial/child view.
Installation:
Call `mpResponse();` before doing `require('express');` in your application.
*/
function mpResponse() {
var expressResponse = require('express/lib/response'),
expressResRender = expressResponse.render;
expressResponse.render = function(view, options, fn) {
options = options || {};
var self = this,
req = this.req,
app = req.app,
layout,
cb;
// support callback function as second arg
if (typeof options === 'function')
fn = options, options = {};
// merge res.locals
options._locals = self.locals;
// default callback to respond
fn = fn || function(err, str) {
if (err) return req.next(err);
self.send(str);
};
if (typeof options.layout === 'string')
layout = options.layout;
else if (options.layout !== false
&& typeof app.get('view layout') === 'string')
layout = app.get('view layout');
if (layout) {
cb = function(err, str) {
if (err) return req.next(err);
options.body = str;
expressResRender.call(self, layout, options, fn);
};
} else
cb = fn;
// render
app.render(view, options, cb);
};
}
解決了Ben Fortune的評論:
該功能在EJS上尚不可用,因此請更新文件ejs.js和lib / ejs.js ( ligne〜155 )
舊代碼
if (0 == js.trim().indexOf('include')) {
var name = js.trim().slice(7).trim();
if (!filename) throw new Error('filename option is required for includes');
var path = resolveInclude(name, filename);
include = read(path, 'utf8');
include = exports.parse(include, { filename: path, _with: false, open: open, close: close, compileDebug: compileDebug });
buf.push("' + (function(){" + include + "})() + '");
js = '';
}
新密碼
if (0 == js.trim().indexOf('include')) {
var name = js.trim().slice(7).trim();
if (!filename) throw new Error('filename option is required for includes');
// If it is not path, but variable name (Added)
var resolvedObj = null;
var objName = name.split(".");
if (objName) {
resolvedObj = options;
for (var idx=0; idx<objName.length; idx++) {
resolvedObj = resolvedObj[objName[idx]];
if ( ! resolvedObj) {break;}
}
}
if(resolvedObj)
var path = resolveInclude(resolvedObj, filename);
else
var path = resolveInclude(name, filename);
include = read(path, 'utf8');
include = exports.parse(include, options); // Added transfer whole options
buf += "' + (function(){" + include + "})() + '";
js = '';
}
來源
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.