模板入门
模板是一个文字档,定义了一个输出档的结构或者排版,使用定位符号表示,当模板被绘制时,资料将插入到何处(在 Express,模板被称为视图)。
Express 模板选择
Express 可以与许多不同的模板渲染引擎一起使用。在本教程中,我们使用Pug(以前称为 Jade)作为模板。这是最流行的 Node 模板语言,并且官方将自身描述为“用于编写 HTML,语法干净且空格敏感,受 Haml影响很大”。
不同的模板语言使用不同的方法,来定义布局和标记数据的占位符 — 一些使用 HTML 来定义布局,而另一些则使用可以编译为 HTML 的不同标记格式。Pug 是第二种类型;它使用 HTML 的表示形式,其中任何行中的第一个单词,通常表示 HTML 元素,后续行中的缩进,用于表示嵌套在这些元素中的任何内容。结果是一个页面定义直接转换为 HTML,但可以说更简洁,更容易阅读。
备注: 使用 Pug 的缺点,是它对缩进和空格敏感(如果在错误的位置添加额外的空格,可能会得到没什么帮助的错误代码)。但是,一旦你的模板到位,它们就很容易阅读和维护。
模板组态
在我们创建骨架网站时,LocalLibrary 配置为使用 Pug。你应该看到 Pug 模块作为依赖项,包含在网站的 package.json文件中,以及 app.js文件中的以下配置设置。设置告诉我们,使用 Pug 作为视图引擎,Express 应该在 /views子目录中搜索模板。
// View engine setup.
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "pug");
如果查看 views 目录,你将看到项目默认视图的 .pug 文件。这包括需要用自己的内容替换的主页(index.pug)和基本模板(layout.pug)的视图。
/express-locallibrary-tutorial //the project root /views error.pug index.pug layout.pug
模板语法
下面的示例模板文件,展示了许多 Pug 最有用的功能。
首先要注意的是,该文件映射典型 HTML 文件的结构,其中(几乎)每一行中的第一个单词是 HTML 元素,并且缩进用于指示嵌套元素。因此,例如,body
本文元素位于 html
元素内,而段落元素(p
)位于 body
元素内等。非嵌套元素(例如,各个段落)位于不同的行上。
doctype html
html(lang="en")
head
title= title
script(type='text/javascript').
body
h1= title
p This is a line with #[em some emphasis] and #[strong strong text] markup.
p This line has un-escaped data: !{'<em> is emphasised</em>'} and escaped data: #{'<em> is not emphasised</em>'}.
| This line follows on.
p= 'Evaluated and <em>escaped expression</em>:' + title
<!-- You can add HTML comments directly -->
// You can add single line JavaScript comments and they are generated to HTML comments
//- Introducing a single line JavaScript comment with "//-" ensures the comment isn't rendered to HTML
p A line with a link
a(href='/catalog/authors') Some link text
| and some extra text.
#container.col
if title
p A variable named "title" exists.
else
p A variable named "title" does not exist.
p.
Pug is a terse and simple template language with a
strong focus on performance and powerful features.
h2 Generate a list
ul
each val in [1, 2, 3, 4, 5]
li= val
元素属性被定义在其关联元素之后的括号中。在括号内,属性定义在以逗号或空格分隔的属性名称和属性值对的列表中,例如:
script(type='text/javascript')
,link(rel='stylesheet', href='/stylesheets/style.css')
meta(name='viewport' content='width=device-width initial-scale=1')
所有属性的值都被转义(例如“>
”等字符转换为 HTML 代码等效项,如“>
”),以防止注入 JavaScript 或跨站点脚本攻击。
如果标记后跟着等号,则以下文本将被视为 JavaScript 表达式。因此,打个比方,在下面的第一行中,h1
标记的内容将是标题变量title
(在文件中定义,或从 Express 传递到模板中)。在第二行中,段落内容是与标题变量title
连接的文本字符串。在这两种情况下,默认行为是转义该行。
h1= title
p= 'Evaluated and <em>escaped expression</em>:' + title
如果标记后面没有等号,则将内容视为纯文本。在纯文本中,你可以使用#{}
和!{}
语法,插入转义和非转义数据,如下所示。你还可以在纯文本中添加原始 HTML。
p This is a line with #[em some emphasis] and #[strong strong text] markup.
p This line has an un-escaped string: !{'<em> is emphasised</em>'}, an escaped string: #{'<em> is not emphasised</em>'}, and escaped variables: #{title}.
备注:
你几乎总是希望转义来自用户的数据(通过 #{}
语法)。可信任的数据(例如,生成的记录计数等)可以不先转义就显示。
你可以在行的开头使用管道(“|”)字符来表示“纯文本”。例如,下面显示的附加文本,将显示在与前一个锚点相同的行上,但不会链接。
a(href='http://someurl/') Link text
| Plain text
Pug 允许你使用if
, else
, else if
和 unless
执行条件操作 - 例如:
if title
p A variable named "title" exists
else
p A variable named "title" does not exist
以使用each-in
或 while
语法执行循环/迭代操作。在下面的代码片段中,我们循环遍历数组,以显示变量列表(注意,使用 'li =' 来评估“val” ,以作为下面的变量。)迭代的值也可以传递给模板作为变量!
ul
each val in [1, 2, 3, 4, 5]
li= val
语法还支持注释(可以在输出中呈现 - 或者不是 - 可自行选择),支持 mixins 创建可重用的代码块,case 语句和许多其他功能。有关更多详细信息,请参阅Pug文档。
扩展模板
在一个站点中,通常所有页面都有一个共同的结构,包括页首,页脚,导航等的标准 HTML 标记。比起强迫开发人员在每个页面中复制这个“样板”的做法,Pug 允许你声明一个基本模板,然后扩展它,只替换每个特定页面不同的地方。
例如,在我们的骨架项目中,创建的基本模板 layout.pug,如下所示:
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content
块标记block
用于标记“可在派生模板中替换的内容部分“(如果未重新定义块,则使用其在基类中的实现)。
默认的 index.pug(为我们的骨架项目所创建),显示了我们如何覆盖基本模板。extends
标记,标识要使用的基本模板,然后我们使用 block section_name
,来指示我们将覆盖的部分的新内容。
extends layout
block content
h1= title
p Welcome to #{title}
下一步
- 回到 Express 教程 5: 呈现图书馆数据
- 继续教程 5 下一个部分:图书馆基本模板