部分装饰器
使用部分装饰器创建可重用的包装器组件,用于封装和组合模板内容。
概述
partial decorator(部分装饰器)是一种特定类型的 partial(部分),用?wrapper component(包装器组件)。标准的部分只是在固定模板中渲染数据,而装饰器使用组合来包围整个内容块。它使用 templates.Inner 函数作为占位符,精确指定外部内容应该注入到包装器布局中的位置
这种方法在两个文件之间创建连接。调用模板提供代码块,部分装饰器确定该代码出现的位置。这允许部分包装内容,而无需了解封闭块的具体标记或内部逻辑。
实现
要使用部分装饰器,在模板中使用块式调用。with 语句用于启动部分并为内容创建容器。此块可以包括任何有效的模板代码,包括页面方法和函数。
layouts/home.html
{{ with partial "components/wrapper.html" . }}
<p>此块中的所有内容都将被包装。</p>
<p>{{ .Content | transform.Plainify | strings.Truncate 200 }}</p>
{{ end }}在部分模板中,将 templates.Inner 函数调用放置在应出现包装内容的位置。
layouts/_partials/components/wrapper.html
<div class="wrapper-styling">
{{ templates.Inner . }}
</div>with 语句创建一个新的 作用域。在 with 块外定义的变量在块内不可用。要在包装内容中使用外部数据,您必须确保它是部分调用中传递的 上下文 的一部分。
templates.Inner 函数的一个关键功能是它能够接受上下文参数。通过向函数传递上下文,您定义了点 (.) 在包装块内代表什么。这确保注入的内容即使在嵌套在多层包装器中时也能访问正确的数据。
组合的好处
使用部分装饰器构建包装器组件提供了几个优势:
- 它消除了在使用单独的部分来封装代码块时使用开始和结束标签的需要。
- 它防止参数膨胀,因为标准部分不再需要大量的参数列表来考虑其内部内容的每种可能变化。
- 它实现了清晰的组合,其中包装块可以执行任何模板逻辑,而包装器无需接收或处理该数据。
这种方法将容器逻辑与内容逻辑分离。包装器处理结构要求,如特定的类层次结构或 CSS 网格容器。调用模板保留对内部标记以及如何显示数据的控制。
示例
以下模板说明了如何嵌套三个包装器组件,包括部分、列和卡片,同时通过每一层传递上下文。
主页模板通过调用部分、列和卡片部分作为装饰器来启动结构:
layouts/home.html
{{ $ctx := dict
"page" .
"label" "最新文章"
"pageCollection" ((site.GetPage "/posts").RegularPages)
}}
{{ with partial "components/section.html" $ctx }}
<div class="grid-wrapper">
{{ range .pageCollection }}
{{ with partial "components/column.html" (dict "page" . "class" "col-half") }}
{{ with partial "components/card.html" (dict "page" .page "url" .page.RelPermalink "title" .page.LinkTitle) }}
<p>
{{ .page.Content | plainify | strings.Truncate 240 }}
</p>
{{ end }}
{{ end }}
{{ end }}
</div>
{{ end }}部分组件提供语义容器和可选标题:
layouts/_partials/components/section.html
<section class="content-section">
{{ with .label }}
<h2 class="section-label">{{ . }}</h2>
{{ end }}
<div class="section-content">
{{ templates.Inner . }}
</div>
</section>列组件通过应用 CSS 类管理布局宽度:
layouts/_partials/components/column.html
<div class="{{ .class | default `column-default` }}">
{{ templates.Inner . }}
</div>卡片组件定义内容的视觉边界:
layouts/_partials/components/card.html
<div class="card">
{{ with .title }}
<h2 class="card-title">
{{ if $.url }}
<a href="{{ $.url }}">{{ . }}</a>
{{ else }}
{{ . }}
{{ end }}
</h2>
{{ end }}
<div class="card-body">
{{ templates.Inner . }}
</div>
{{ with .url }}
<div class="card-footer">
<a href="{{ . }}">阅读更多</a>
</div>
{{ end }}
</div>