Nunjucks 教程

适用于 Eleventy、Express 或任何 Node 模板流水线的服务端渲染宏——采用 GOV.UK 风格的做法,搭配 Lily 的目录和类名钩子。

你将构建什么

一个小型服务端渲染的联系表单——带标签的输入框、提交按钮、零 JavaScript 负载——先是不带样式的版本,再加上样式,大约 10 分钟完成。

开始之前

你需要 git、Node 22 或更高版本,以及 pnpm 10 或更高版本。任何 Nunjucks 流水线都可以——Eleventy、Express 或纯 Nunjucks。

第 1 步——获取代码

git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-nunjucks-headless
pnpm install
pnpm test        # vitest rendering every macro

每个组件都是 components/ 中的一个目录,包含一个 macro.njk、它的测试和它的文档——例如 components/button/macro.njk。把你的 Nunjucks 加载器指向 components/(在 Eleventy 中,把它加入 includes 路径),然后导入你需要的宏。

第 2 步——你的第一个组件

{% from "components/button/macro.njk" import button %}

{{ button({ text: "Save", type: "submit" }) }}

渲染为 <button class="button" type="submit">Save</button>。 宏接收单个参数对象:text(会转义)或 html(原样输出)、type、用于 aria-label 的 label,以及追加类名钩子的参数。

第 3 步——组合一个小表单

{% from "components/form/macro.njk" import form %}
{% from "components/label/macro.njk" import label %}
{% from "components/text-input/macro.njk" import textInput %}
{% from "components/button/macro.njk" import button %}

<form class="form" method="post">
  <div class="field">
    {{ label({ for: "name", text: "Full name" }) }}
    {{ textInput({ id: "name", name: "name", required: true }) }}
  </div>
  {{ button({ text: "Save", type: "submit" }) }}
</form>

因为一切都在服务端渲染,浏览器收到的是带有类名钩子的纯语义化 HTML——JavaScript 负载为零字节。

检查你的成果:加载页面,表单看起来很朴素——这正是预期:样式还在后面。按下 Tab:焦点会依次经过每个控件,标签会被朗读,提交也能正常工作。行为已经完成;外观由你决定,这就是下一步。

第 4 步——添加样式

在你的样式表中为这些钩子设置样式——.button、.text-input、 .label、.field——或者在基础布局中链接一个现成的主题:

<link rel="stylesheet" href="/themes/united-kingdom-government-digital-service.css" />

第 5 步——看看它的完整效果

Nunjucks + Eleventy 示例应用把完整目录构建成静态站点,并为每个组件提供演示页面:

git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-nunjucks-eleventy-examples
pnpm install && pnpm run dev

下一步

  • 主题——包括用于无闪烁服务端渲染主题切换的 Eleventy cookie 模式。
  • 偏好设置辅助包——语言与文字大小。
  • 组件目录——每个组件的 props、ARIA 和键盘操作。

过程中有疑问?帮助页面里有大量解答——如果某一步可以写得更清楚, 请告诉我们,我们很乐意改进教程。