Skip to content

逻辑标签用 {% ... %} 控制哪些内容会被渲染。标签本身不产生输出。

条件

{% if %} 仅在表达式为真时包含内容。用 elseifelse 提供其他分支。这里的 published 为真。

Template
knap
{% if published %}
Published
{% else %}
Draft
{% endif %}
Output
md
Published

比较与逻辑运算符

运算符含义示例
==等于status == "draft"
!=不等于status != "archived"
> < >= <=大小比较price >= 100
contains字符串子串或数组成员tags contains "reference"
and / &&两侧都为真author and published
or / ||任一侧为真draft or archived
not / !对表达式取反not hidden

用圆括号让组合表达式的作用范围更明确。

knap
{% if (premium or featured) and published %}
Featured reading
{% endif %}

真值与假值

条件把 falsenullundefined、空字符串、0 和空数组视为假。其他取值视为真。

knap
{% if content %}
{{ content }}
{% endif %}

回退值

?? 运算符返回第一个被视为真的取值。被视为假的取值——包括 0false——会使用回退值。过滤器先于回退判断执行,因为 ?? 的优先级最低。

knap
{{ title ?? headline ?? "Untitled" }}
{{ title | upper ?? "UNTITLED" }}

循环

{% for %} 为数组中的每个取值渲染一次区块。这里的 tags 包含 science fictionnovel

Template
knap
{% for tag in tags %}
- #{{ tag | kebab }}
{% endfor %}
Output
md
- #science-fiction
- #novel

循环可以遍历宿主提供的变量、用 set 创建的取值,以及嵌套数据中的数组。

迭代之间以换行分隔。{% endfor %} 之前的额外空行会被保留,因此在循环内留一个空行即可分隔重复的段落或表格。

循环取值

取值说明
loop.index当前迭代序号,从 1 开始
loop.index0当前迭代序号,从 0 开始
loop.first首次迭代时为真
loop.last末次迭代时为真
loop.length条目总数
item_index以迭代器命名的、从 0 开始的向后兼容索引
knap
{% for author in authors %}
{{ loop.index }}. {{ author.name }}{% if loop.last %}.{% else %};{% endif %}
{% endfor %}

组合与嵌套逻辑

条件、循环与赋值可以嵌套,以配合结构化数据使用。

knap
{% for section in sections %}
## {{ section.title }}
{% for item in section.items %}
{% if item.active %}- {{ item.name }}{% endif %}
{% endfor %}
{% endfor %}

注释

{# ... #} 在模板中留下注释。注释会从输出中移除,其中的变量、过滤器和逻辑不会被求值。

Template
knap
Hello{# A note for template authors #} world!
Output
md
Hello world!

注释可以跨多行:

knap
{#
This template is used for reading notes.
{{ title }} is ignored inside this comment.
#}

包围的空格与换行会被保留。独占一行的注释会让该行保持为空行。注释在第一个 #} 处结束,且不支持嵌套。未闭合的注释是语法错误。

要在渲染出的 Markdown 中留下 Obsidian 风格的 %% 注释,请使用 comment 过滤器。

参考

  • if。条件为真时渲染内容。
  • for。为数组中的每个条目重复渲染内容。
  • set。保存一个取值,供模板后续使用。