簡體   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