繁体   English   中英

如何使用Node.js,EJS模板和动态文件名进行多重渲染

[英]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.jslib / ejs.jsligne〜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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM