自定义列表
概述
除了内置的3种列表类型外,您还可以构建一个完全自定义的项目显示方式。这种自定义显示可以生成任何HTML,并且可以选择仍然利用列表提供的排序、过滤和分页功能。
列表模板
要构建自定义列表显示,您需要创建一个EJS模板,该模板将用于生成传递给模板的一组项目的HTML。EJS模板允许您使用普通的javascript生成HTML,从而可以轻松地循环遍历项目并在自定义HTML中输出它们的值。
要使用自定义模板,请在列表的 template
选项中传递它:
listing:
template: gallery.ejs
当使用自定义模板的列表被渲染时,列表内容将被读取并处理成一组传递给模板的项进行渲染。例如,在这种情况下,posts目录中的所有文档将被读取为项目并传递给 gallery.ejs
模板。
listing:
contents: posts
template: gallery.ejs
一个简单的模板,用于输出文档列表,可能如下所示:
<ul>
<% for (const item of items) { %>
<li><a href="<%- item.path %>"><%= item.title %></a></li>
<% } %>
</ul>
这将产生如下简单的HTML输出:
渲染时,上述模板将接收一个名为 items
的列表项数组。当列表的内容从一组文档中加载时,每个项目将填充在列表字段中描述的字段。此外,文档元数据中包含的任何其他字段都将作为项目的属性传递,从而可以在文档和列表显示中使用自定义元数据。
请注意,Quarto使用 lodash
来渲染EJS模板。lodash
在模板中对文本进行HTML转义时使用不同的语法。
HTML转义值: <%- value %>
HTML未转义值: <%= value %>
元数据列表
列表的 contents
选项通常包含路径或通配符列表,但它也可以包含元数据。当内容是元数据时,元数据将被读取为项目并传递给模板。例如:
listing:
template: custom.ejs
contents:
- name: 第一项
href: https://www.quarto.org
custom-field: 自定义值
- name: 第二项
href: https://www.rstudio.org
custom-field: 第二个自定义值
可以使用以下方式渲染:
```{=html}<ul>
<% for (const item of items) { %>
<li>
<a href="<%- item.href %>"><%= item.name %></a><br/>
<%= item['custom-field'] %>
</li>
<% } %>
</ul>
```
这将产生如下简单的HTML显示:
元数据文件列表
列表的 contents
选项也可以指向一个或多个包含元数据的 yaml
文件。在这种情况下,元数据将从文件中读取为项目并传递给模板。例如:
listing:
template: custom.ejs
contents:
- items.yml
其中 items.yml
的内容是:
- name: 第一项
href: https://www.quarto.org
custom-field: 自定义值
- name: 第二项
href: https://www.rstudio.org
custom-field: 第二个自定义值
模板示例
本网站的部分内容是使用自定义列表构建的。最好的起点是我们的画廊,这是一个使用自定义模板和元数据文件构建的列表。您可以在我们的Github仓库中查看用于创建画廊页面的源代码。
文件 | 描述 |
---|---|
gallery.yml | 控制画廊列表中显示哪些项目的元数据。 |
gallery.ejs | 用于在页面上显示项目的模板。 |
index.qmd | 配置并将列表放置在 #gallery div 中的Quarto文档。 |
排序、过滤和分页
默认情况下,自定义列表模板的排序、过滤和分页是禁用的,但通过在模板和列表选项中进行一些简单的更改,您可以为自定义列表添加此功能。为此,您需要在自定义模板中包含以下三项内容: 1. 在包含项目列表的HTML标签中包含一个list
类。
对于每个项目,在包含该项目的HTML标签中包含
<%= metadataAttrs(item) %>
。这将允许Quarto编写用于排序和过滤的自定义属性。在每个项目中,包含一个类,用于标识其文本表示项目字段内容的标签。该类必须是字段名称前缀为
listing-
,例如,其内部文本是item.name
的标签应包含一个类listing-name
。
例如,我们可以将上述custom.ejs
模板修改如下:
<ul class="list">
<% for (const item of items) { %>
<li <%= metadataAttrs(item) %>>
<a href="<%- item.href %>" class="listing-name"><%= item.name %></a><br/>
<span class="listing-custom-field"><%= item['custom-field'] %><span>
</li>
<% } %>
</ul>
一旦您在模板中包含了这些项目,您就可以在列表中启用以下选项:
listing:
sort-ui: true
filter-ui: true
page-size: 10
现在,UI元素将出现在页面上,并且应该与您的自定义列表正确交互。
字段显示名称
您可能希望为字段提供自定义显示名称,以提供比字段名称更好的名称。例如,字段名称将出现在排序UI中。您可以使用field-display-names
创建从字段到显示名称的映射。例如:
listing:
template: custom.ejs
contents:
- items.yml
sort-ui: true
filter-ui: true
page-size: 10
field-display-names:
name: "名称"
custom-field: "自定义字段"
日期排序和格式化
为了正确格式化和排序日期值,您可以在项目字段中指定类型信息。如果您指定字段为日期,它将自动使用指定的日期格式(默认或使用date-format
指定)进行格式化,并支持按升序或降序进行日期排序。如果您指定字段为数字,它将支持升序和降序的数值排序。
您可以按如下方式指定字段类型:
listing:
template: custom.ejs
contents:
- items.yml
field-types:
custom-date: date
custom-number: number
必需字段
由于列表是使用在其他文档中指定或通过元数据指定的字段生成的,因此确保必需字段存在可能会有所帮助。您可以按如下方式标注必需字段:
listing:
template: custom.ejs
contents:
- items.yml
field-required: [name, custom-field]
如果渲染列表页面时内容中缺少任何必需字段的值,将抛出一个错误,指出所需的字段以及省略该字段的文件或元数据。
模板参数
您还可以通过使用参数来控制其行为,使自定义模板更加动态。您可以使用template-params
选项为自定义模板提供参数,例如:
listing:
template: custom.ejs
contents:
- items.yml
template-params:
param1: "param-value"
然后,可以在模板中使用<%= templateParams.param1 %>
访问模板参数。例如,我们可以将上述custom.ejs
模板修改如下:
<h3><%= templateParams.param1 %></h3>
<ul class="pub-list list">
<% for (const item of items) { %>
<li <%= metadataAttrs(item) %>>
<span class="listing-title"><%= item.title %>.</span>
</li>
<% } %>
</ul>