我正在尝试使用Jade将内容块中的变量包含到更大的页面布局中。
我想为页面<title>
标记添加语义内容标题。
我正在使用优秀的roots.cx工具包在Jade和Stylus中建立一个网站。
我有两个文件:pagelayout.jade
和page142.jade
。
pagelayout
文件包含一个基本的Jade页面模板(为简单起见而编辑):
!!!
html
head
title #{page.title} | My Great Site
body
!= content
page142
文件包含一些将包含在!= content
中的唯一内容:
- var page = { title: 'Page 142' }
h1 Content header of page 142
我希望最终的HTML看起来像:
<html><head><title>Page 142 | My Great Site</title></head>
<body><h1>Content header of page 142</h1></body></html>
目前,我得到了一个编译器TypeError:
Cannot read property 'title' of undefined
我认为我得到了这个错误,因为Jade变量的范围可能仅适用于模板到内容,反之亦然。
如何将页面变量从内容传递到页面布局? 我发现的所有StackOverflow posts只显示从页面布局到内容的变量。
答案 0 :(得分:10)
我看到Jeff已经在Twitter上为你解答了这个问题,但是为了StackOverflow,我会在这里再次为你解答。
Jade提供对“blocks”的支持,它类似于includes,但允许你传递Jade块。将块视为“块级包含”,只需使用独特的语法即可生成传递给它的块的内容。
在layout.jade
中,您可以执行此操作:
html
head
block head
title My Website
body
block content
在你的index.jade
中,你可以这样做:
extends layout
block head
title A Specific Page of My Website
block content
p Hello World!
呈现index.jade
时会发生什么,是否会“看到”它展开layout.jade
(第1行),然后看到它有block head
后跟一些内容,因此,它会在layout.jade
中搜索block head
并将其找到的内容替换为自己的内容。
根据您的Roots项目的设置方式,这可能有效,也可能无效。 Roots的当前稳定版本为默认的Roots模板提供了自己的包含系统,该模板与任何模板引擎无关。
此默认根模板是$ roots new projectname
使用的模板。
我不确定是否可以覆盖项目的当前模板,或者当前是否可以更改模板引擎的工作方式(无论是使用Roots包含系统还是自己的),但是我要知道,与$ roots new projectname --min
一起使用的最小根模板将使该块包括工作。
所以,你可以在这里做两件事之一:
$ roots new <projectname> --min
仅供参考,杰夫和我都使用--min
作为首选模板,但我已将其扩展为包含各种跨浏览器的polyfills。
编辑:
现在,您可能想知道是否更换整个块只是为了更改块中某处的标签内容效率有点低 - 从维护角度看它效率低 - 我无法真正评论处理速度。但是如果你记得在Jade中,你可以定义变量,那么在Jade中,你可以将任何东西放在一个块中 - 你将这两个结构组合在一起 - 它们会变得更有用。
例如,如果我知道我将在项目中广泛使用Jade,我将创建一个configuration.jade
文件,其中我将所有配置/设置变量列为块。然后我将在我的主要布局中包含该文件(这只是为了简单起见,包括设置标题):
config.jade
:
- var siteTitle = "My Cool Website";
layout.jade
:
block config
include config
html
head
title #{siteTitle}
body
block content
p Hello World
我们include
配置文件而不是仅仅在新布局顶部定义的原因仅仅是因为某些项目需要多个布局,因此卸载存储配置变量的责任是有意义的到另一个文件,以便我们可以在任何我们想要的布局中include
。但请注意,我们include
我们的配置文件在内block config
。这允许我们用我们文件中的配置变量替换那个块,所以 - 如果我有一个博客页面,我从layout
延伸,我可以这样写:
blog.jade
extends layout
block config
- var siteTitle = "Blog - My Cool Website";
block content
each post in posts
p #{post.content}
看看有多简单? :)