Node.js 在express/ejs中查找布局并包含多个路径上的文件

Node.js 在express/ejs中查找布局并包含多个路径上的文件,node.js,express,ejs,Node.js,Express,Ejs,我正在使用ejs作为模板引擎构建一个基于express的节点应用程序 为了支持该网站的不同外观,我想把文件放在名为base的文件夹中,其中包含vanilla stuff和每个样式/主题/客户机的覆盖层。我希望系统首先查找覆盖中的文件,并且只有在未找到时才使用基础中的文件 对于静态内容,如图像和css文件,这将使用静态中间件两次,首先用于覆盖,然后用于基础 我希望对通过ejs呈现的模板执行相同的操作。我发现: 只要我调用简单的ejs视图,该线程中提供的答案几乎适用于我。如果我想使用布局或包含,它

我正在使用ejs作为模板引擎构建一个基于express的节点应用程序

为了支持该网站的不同外观,我想把文件放在名为base的文件夹中,其中包含vanilla stuff和每个样式/主题/客户机的覆盖层。我希望系统首先查找覆盖中的文件,并且只有在未找到时才使用基础中的文件

对于静态内容,如图像和css文件,这将使用静态中间件两次,首先用于覆盖,然后用于基础

我希望对通过ejs呈现的模板执行相同的操作。我发现:

只要我调用简单的ejs视图,该线程中提供的答案几乎适用于我。如果我想使用布局或包含,它会分解为覆盖视图,因为基本目录现在是覆盖的,并且不再找到与基本目录相同的布局

下面是一个简化的例子

文件基/layouts/root.ejs:

<!DOCTYPE html>
<html lang="en">
  <body>
    <!-- Main content of pages using this layout goes here -->
    <%- body %>
  </body>
</html>

文件base/index.ejs:

<% layout('layouts/root') -%>
<p>
    A page in base using the root layout
</p>
<% layout('layouts/root') -%>
<p>
    Totally different page in the overlay.
</p>


使用根布局的基本页面

文件覆盖/index.ejs:

<% layout('layouts/root') -%>
<p>
    A page in base using the root layout
</p>
<% layout('layouts/root') -%>
<p>
    Totally different page in the overlay.
</p>


完全不同的页面在覆盖。

使用BananaAcids方法并将两条路径设置为视图源express/ejs,现在可以正确地将overlay/index.ejs定位为要渲染的视图,但由于我没有覆盖layouts/root,因此失败,因为生成的文件overlayouts/root.ejs不存在

是否有一种方法可以将我的方法进一步修补到ejs中,以便我可以帮助它在base/layout/root.ejs中找到这个文件


感谢您阅读本文以及您为此花费的所有脑力周期。

以下是我使用monkey patch Express(4.x)添加布局支持的内容:

/*
   Usage:
     Set a global/default layout with:
        app.set('view layout', 'foo');
     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);
  };
}

我修补了EJB以支持Express v.4.10中添加的多视图文件夹功能。当前有一个挂起的拉取请求,您可以在此处找到:。如果您的项目仍然需要此解决方案,您可以将my fork作为EJS替代品包含在package.json中:


{
...
“依赖项”:{
“ejs”:git://github.com/MarcelloDiSimone/ejs.git#feature/multi-观点”
}
}

…或者你加上一个拉请求,希望它能很快被接受