部分裝飾器
使用部分裝飾器創建可重用的包裝器組件,用於封裝和組合模板內容。
概述
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>