我正在使用ejs作为模板引擎构建基于express的节点应用程序。
为了支持网站的不同外观我想将文件放在名为base holding vanilla stuff的文件夹中,并为每个样式/主题/客户端添加一个叠加层。我希望系统首先在叠加层中查找文件,并且只有在未找到时才使用基础中的文件。
对于像图像和css文件这样的静态内容,这可以使用静态中间件两次,首先是覆盖,然后是基础。
我想对通过ejs呈现的模板执行相同的操作。我找到了:
Multiple View paths on Node.js + Express
只要我调用简单的ejs视图,那个线程中提供的BananaAcids答案几乎适用于我。如果我想使用布局或包含它,则会因覆盖视图而分解,因为基本目录现在已覆盖,并且不再找到与基础相同的布局。以下是一个简化的例子。
文件库/布局/ root.ejs:
<!DOCTYPE html>
<html lang="en">
<body>
<!-- Main content of pages using this layout goes here -->
<%- body %>
</body>
</html>
文件库/ index.ejs:
<% layout('layouts/root') -%>
<p>
A page in base using the root layout
</p>
文件覆盖/ index.ejs:
<% layout('layouts/root') -%>
<p>
Totally different page in the overlay.
</p>
使用BananaAcids方法并将两个路径设置为view-sources express / ejs现在可以正确地将overlay / index.ejs定位为要渲染的视图,但由于我没有覆盖布局/ root它失败,因为生成的文件覆盖/布局/ root.ejs不存在。
有没有办法将我的方法进一步修改为ejs,以便我可以帮助它在base / layout / root.ejs中找到这个文件?
感谢您阅读本文以及您已经花费的任何脑力循环。
答案 0 :(得分:0)
以下是我用来修补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);
};
}
答案 1 :(得分:0)
我修补了EJS以支持Express v.4.10中添加的多视图文件夹功能。您可以在此处找到待处理的拉取请求:https://github.com/mde/ejs/pull/120。如果你的项目仍然需要这个解决方案,你可以将我的fork作为EJS替换包含在你的package.json中:
public static StudentManager sm = new StudentManager();
// GET: Student
public ActionResult Index()
{
return View(sm.sList);
}
public ActionResult Edit(int? id)
{
Students student = sm.sList.Where(s => s.Sid == id).First();
return View(student);
}
[HttpPost]
public ActionResult Edit(Students s)
{
sm.Edit(s);
return RedirectToAction("Index");
}
..或者你加一个拉请求,希望很快就会被接受。