Javascript 带Express.js和Node.js的Swig的条件扩展标记

Javascript 带Express.js和Node.js的Swig的条件扩展标记,javascript,node.js,express,swig-template,Javascript,Node.js,Express,Swig Template,是否有人知道如何使Swig模板引擎的extend标记有条件或能够使用传递的变量 与此相反: {% extends '../layouts/layout.view' %} 我想这样做 {% extends layout %} 在express.js中使用此文件呈现文件时 res.render('jobs/index', { title: 'Jobs', layout: '../layouts/layout.view' }); 以前有人这样做过吗?使模板扩展有条件或传递变量而不是字符串。非常感

是否有人知道如何使Swig模板引擎的extend标记有条件或能够使用传递的变量

与此相反:

{% extends '../layouts/layout.view' %}
我想这样做

{% extends layout %}
在express.js中使用此文件呈现文件时

res.render('jobs/index', { title: 'Jobs', layout: '../layouts/layout.view' });

以前有人这样做过吗?使模板扩展有条件或传递变量而不是字符串。非常感谢您的帮助。

Swig中不允许有条件扩展。这是为了更快的模板呈现和更好的预编译而设计的。当解析模板时,它的父链将立即解析并为给定模板一起编译,从而删除以后每次使用不同的本地上下文运行模板时需要执行的任何必要步骤

另一种解决方案(虽然不是很漂亮)是使用includes:将主要内容放在一个文件中,但呈现两个单独的文件,具体取决于要使用的布局:

如果需要布局1,请渲染此文件:

{% extends "layout1.html" %}
{% block body %}
    {% include "content.html" %}
{% endblock %}
{% extends "layout2.html" %}
{% block body %}
    {% include "content.html" %}
{% endblock %}
如果需要布局2,请渲染此文件:

{% extends "layout1.html" %}
{% block body %}
    {% include "content.html" %}
{% endblock %}
{% extends "layout2.html" %}
{% block body %}
    {% include "content.html" %}
{% endblock %}

我设法解决了这个问题。至少我换了几行就得到了我想要的

解决方案的基本功能是将
locals
参数从
renderFile
函数传递到
compileFile
函数,如下所示:

  this.renderFile = function (pathName, locals, cb) {
    if (cb) {
      exports.compileFile(pathName, locals, function (err, fn) { 
        if (err) {
          cb(err);
          return; 
       }
       cb(null, fn(locals));
     });
     return;
   }

   return exports.compileFile(pathName, locals)(locals);
 };
这发生在
/lib/swig.js
文件的
514行和
524行。局部变量本质上变成了
选项

然后我只在同一个文件的
405行添加了这个

if(options.layout) 
  parentName = options.layout;
在express的路由定义中调用res.render命令时,我只添加了一个布局选项,其中包含布局的相对位置

res.render('index', { title: 'Express', layout: 'layouts/main.layout' });
这完全解决了我的问题。保持正常的
{%extend%}
功能(不使用
布局
选项覆盖时),同时能够动态设置布局

唯一的缺点是,
layout
成为一个保留选项,我认为您可以重构它,使其不成问题


希望这对别人有帮助。两行更改和两行代码使动态布局成为可能。性能是一样的。

看看代码,我会说这是不可能的。是的,后来意识到类似的东西可能是一个解决方案。感谢Paul的回答,我意识到这是当前设置的方式。不过,为相同的内容呈现不同的布局似乎很方便(可能基于身份验证角色)。我们将尝试这一点并进一步调查,也许还有另一种解决方案。我正在努力防止重复的html…这对我很有帮助。但是我在缓存模板时遇到了一个问题。我通过在
lib/swig.js
compile
函数中向缓存键添加布局名称来解决这个问题:
if(options.layout&&key!==null){key+=options.layout;}