模板片段是服务器端渲染 (SSR) 模板库中一个相对罕见的特性,它允许您渲染模板中的一段片段或部分内容,而不是整个模板。此功能在超媒体驱动应用程序中非常方便,因为它允许您分解特定视图以进行部分更新内部,而无需将模板的片段提取到单独的文件中进行渲染,从而创建大量单个模板文件。
通过将所有 HTML 保留在一个文件中,也更容易推断功能的工作原理。这遵循行为局部性设计原则。
让我们看看模板片段如何在一种名为 chill 模板 的用于 java 的晦涩模板语言中帮助我们构建 HDA。
这是一个简单的 chill 模板,/contacts/detail.html
,用于显示联系方式
<html>
<body>
<div hx-target="this">
#if contact.archived
<button hx-patch="/contacts/${contact.id}/unarchive">Unarchive</button>
#else
<button hx-delete="/contacts/${contact.id}">Archive</button>
#end
</div>
<h3>Contact</h3>
<p>${contact.email}</p>
</body>
</html>
在模板中,我们有一个存档功能,根据联系人的存档状态,我们显示“存档”或“取消存档”按钮,这两个按钮都由 htmx 提供支持,并向不同的端点发出 HTTP 请求。
当我们点击显示的两个按钮中的任何一个时,我们希望用更新的按钮替换包围按钮的div
中的内容。(注意 div
上的 hx-target="this"
,所以我们针对该 div
的 innerHTML 进行替换。)这将有效地翻转“存档”和“取消存档”之间的来回切换。
现在,不幸的是,如果我们想只渲染按钮而不渲染模板的其余部分,这通常需要将按钮拆分成自己的模板文件,并将其包含在该模板中,如下所示
<html>
<body>
<div hx-target="this">
#include archive-ui.html
</div>
<h3>Contact</h3>
<p>${contact.email}</p>
</body>
</html>
#if contact.archived
<button hx-patch="/contacts/${contact.id}/unarchive">Unarchive</button>
#else
<button hx-delete="/contacts/${contact.id}">Archive</button>
#end
现在我们有两个模板。我们现在可以单独渲染 archive-ui.html
模板,但这种拆分降低了存档功能的可见性:当您只查看 detail.html
模板时,不太清楚发生了什么。
当这种分解模板的做法被推向极端时,可能会导致许多小的模板片段,这些片段加起来难以管理和推断。
为了解决这个问题,chill 模板有一个 #fragment
指令。该指令允许您在模板中指定一段内容,并只渲染那部分内容
<html>
<body>
<div hx-target="this">
#fragment archive-ui
#if contact.archived
<button hx-patch="/contacts/${contact.id}/unarchive">Unarchive</button>
#else
<button hx-delete="/contacts/${contact.id}">Archive</button>
#end
#end
</div>
<h3>Contact</h3>
<p>${contact.email}</p>
</body>
</html>
通过在模板中定义此片段,我们现在可以渲染整个模板
Contact c = getContact();
ChillTemplates.render("/contacts/detail.html", "contact", c);
或者我们也可以只渲染模板的 archive-ui
片段
Contact c = getContact();
ChillTemplates.render("/contacts/detail.html#archive-ui", "contact", c);
当我们想渲染联系人的整个详细信息页面时,我们会使用第一个选项。
当我们处理存档/取消存档操作并希望仅重新渲染按钮时,我们会使用第二个选项。
请注意,使用片段,我们能够将我们的 UI 保持在一个文件中,并准确了解该功能的工作原理,而无需在不同的模板文件之间切换。这为该功能提供了更简洁、更清晰的实现方式。
片段(以及直接在控制器中渲染它们的可能性)似乎是模板库中一个相对罕见的特性,并为在使用 htmx 和其他面向超媒体的库时改进开发人员体验提供了极好的机会。
以下是片段概念的一些已知实现
$Latte_Engine->render('path/to/template.latte', [ 'foo' => 'bar' ], 'content');
$template->renderBlock('block_name', ['the' => 'variables', 'go' => 'here']);
如果您知道其他实现,请告诉我,以便我将它们添加到此列表中。