在Jade中使用变量进行包含文件

52

我正在使用Jade和Express,并且我想在我的include语句中使用一个变量。例如:

app.js

app.get('/admin', function (req, res) {
  var Admin = require('./routes/admin/app').Admin;

  res.render(Admin.view, {
    title: 'Admin',
    page: 'admin'
  });
});

layout.jade

- var templates = page + '/templates/'

include templates

我这样做时会出现错误:EBADF, Bad file descriptor 'templates.jade'

我甚至尝试了

include #{templates}

毫无结果。


我也在寻找这个功能。惊讶的是,这个功能还没有被添加。我复制了该存储库以查看实现此功能的难度。 - AE Grey
5个回答

43
据我所知,JADE不支持动态包含。我的建议是在模板之外进行“包含”,即:

app.js

app.get('/admin', function (req, res) {
    var Admin = require('./routes/admin/app').Admin;
    var page = 'admin';

    var templates = page + '/templates/';

    // render template and store the result in html variable
    res.render(templates, function(err, html) {

        res.render(Admin.view, {
            title: 'Admin',
            page: page,
            html: html
        });

    });

});

layout.jade

|!{ html }

2
调用 render() 两次似乎会对性能产生负面影响。 - Steve Davis
@StephenDavis 是的,但我怀疑这永远不会成为问题(数据库始终是瓶颈)。 - freakish
@freakish 的确如此,但一秒钟的时间总是一秒钟之后 ;) - Diosney
+1 话虽如此,这是我到目前为止找到的最佳解决方案。 - Diosney
2
这太糟糕了,我们不应该为这样一个常见的问题需要一个复杂的解决方案。 - superluminary

20

这也可以工作:

//controller
var jade = require('jade');
res.render('show', {templateRender: jade.renderFile});


//template
!= templateRender('my/path/'+dynamic+'.jade', options)

使用此方法可能无法提高您使用'视图缓存'设置所期望的性能(在 NODE_ENV === 'production' 默认开启)。甚至可能会破坏应用程序(例如,在部署新代码时硬盘上的文件不可用)。另外,在客户端或同构应用程序中尝试使用此技巧将无法正常工作,因为模板无法编译。


1
这非常棒。 - Kenny Ki
1
但是,调用函数时应该使用locals而不是context - Kenny Ki
一个选项对象,也被用作本地对象。它两者兼备。 - antpaw
1
是的,那是正确的。但是我尝试传递 context ,它是 _未定义的_,而 locals 则让我可以在子模板中访问当前上下文。 - Kenny Ki
好的,这更像话了! - superluminary

7

我在谷歌上搜索同样的问题,但是在不同的情境下,所以我想在这里分享我的解决方案(即:变通方法)以供后人参考:

我希望从变量中提取更多的上下文信息来包含我的include,例如(简化):

- var templates = page + '/templates/'
- var headid = page + 'head'
- var imgsrc = '/images/' + page
div(id=headid)    
  h1 #{page}
  img(src=imgsrc)
div(id=page)
  include templates

由于这种方法行不通(正如freakish所指出的,Jade不支持动态包含),因此我混合使用了一个mixin:

(编辑-比我之前的解决方法更加优雅:)

mixin page1
  include page1/templates

mixin page2
  include page2/templates

...

- for (var i = 0; i < 3; i++)
  - var page = 'page' + i
  - var headid = page + 'head'
  - var imgsrc = '/images/' + page
  div(id=headid)    
    h1 #{page}
    img(src=imgsrc)
  div(id=page)
    +page

我之前的回答:

mixin templates(page)
  - var headid = page + 'head'
  - var imgsrc = '/images/' + page
  div(id=headid)    
    h1 #{page}
    img(src=imgsrc)

+templates('page1')
#page1
  include page1/templates/

+templates('page2')
#page2
  include page2/templates/

...

这种方法并不优雅,如果您需要以这种方式包含多个内容,则无法正常工作,但至少Jade的一部分是动态的。


1
为什么不使用Jade继承?
在中间件层级渲染所需内容:
res.render('templates/' + template_name + '.jade')

编写常见的common.jade

h1 This is a page
.container
  block sublevel
    h2 Default content

然后编写一个扩展了common.jade的文件:

extends common.jade
block sublevel
  h2 Some things are here

0

现在是2019年,在 Pug(之前被称为 Jade) mixin 中使用变量已经变得简单。

创建 mixin 时,您可以根据期望传递给 mixin 的值来为其提供参数。您可以使用点符号访问任何嵌套值。

mixinFile.pug:

mixin myMixin(parameter1, parameter2, parameter3)
    h2.MyHeading #{parameter1}
    p.MyParagraph #{parameter2.myVariable}
    .MyBox(id= parameter3.id)

index.pug:

include mixinFile
block content
    +MyMixin(variable1, variable2, variable3)

您可以在 官方 Pug 混入文档 中阅读更多内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接