視覺內容片段 — 範本 visual-content-fragments-templates

在Adobe Experience Manager (AEM) as a Cloud Service中,HTML範本可用來將內容片段視覺化並以HTML格式傳送。

NOTE
視覺內容片段和視覺內容片段圖形作業目前為有限可用性。
如果您想要參與,請將您的正式電子郵件地址傳送至experience-production-agent@adobe.com

HTML範本可讓您控制內容片段的顯示方式。 您可以在選擇的程式碼編輯器中建立HTML範本,然後上傳並指派給AEM中的內容片段模型。 使用Handlebars.js的內容預留位置允許將範本對應到內容片段模型中的資料型別。 指派給模型後,範本即可用於任何基於模型的內容片段,以視覺化片段或以HTML格式的模組化體驗形式將其傳送至任何管道,例如網頁、電子郵件、行動應用程式或其他。

本文說明如何使用Handlebars語法建立自訂HTML範本,以呈現視覺內容片段。

建立範本後,您可以:

NOTE
檢視視覺化內容片段,以在AEM中上傳、指派及使用您的範本。
NOTE
使用Figma to Visual Content Fragments工作自動載入HTML設計。

您將瞭解的內容 what-you-will-learn

在提供(非常快速)的簡介之後:

  • 如何在AEM中使用範本
  • 使用發佈URL

本頁涵蓋(更詳細):

  • Handlebars — 語法的必要基本概念
  • 如何存取內容片段資料
  • 使用巢狀內容片段
  • 處理多值欄位
  • 建立回圈和條件式邏輯
  • 內容片段範本設計的最佳實務

先決條件 prerequisites

若要瞭解並運用此處說明的技術,您應該具備:

  • 對HTML的基本瞭解
  • 熟悉AEM內容片段和內容片段模型
  • 瞭解您的內容片段模型

使用內容片段HTML範本 using-a-content-fragment-html-template

在AEM中使用內容片段HTML範本 using-a-content-fragment-html-template-in-aem

如需如何在AEM中使用範本的詳細資訊,請參閱:

使用視覺內容片段發佈URL using-the-visual-content-fragment-publish-url

使用範本建立視覺內容片段後,您就可以使用視覺內容片段的發佈URL

Handlebars - (非常)基本知識 handlebars-the-very-basics

Handlebars是一種簡單的範本化語言,使用雙大括弧(括弧) {{ }}將動態內容插入HTML。

基本語法 basic-syntax

基本Handlebars語法的範例:

<!-- Output a variable (HTML-escaped) -->
{{snippet-not-found:variableName}}

<!-- Output raw HTML (unescaped) -->
{{{htmlContent}}}

<!-- Comment (not rendered) -->
{{! This is a comment }}

重要概念 key-concepts

Handlebars的主要概念:

語法
說明
使用時機
{{ }}
逸出HTML特殊字元
中繼資料、標籤、布林值
{{{ }}}
輸出原始HTML (未逸出)
RTF文字和資產輸出
{{! }}
Handlebars專用註解
範本檔案
IMPORTANT
對欄位值使用三大括弧({{{ }}}),因為值是預先轉譯的HTML。

範本內容參考 template-context-reference

呈現範本時,它會接收包含您的內容片段所有資料的內容物件。 內容涵蓋:

  • 您選取的片段

  • 從該所選片段引用的所有後續片段

    note
    NOTE
    可參考的片段:
    • 在UI中:深度上限5
    • 使用API時:可設定深度,最大深度為10

內容片段 content-fragment

(所選)內容片段的內容物件結構:

變數
類型
說明
properties
地圖
片段中繼資料(請參閱屬性結構
fields
地圖
依名稱直接存取欄位值
allFields
清單
反複專案的{name, value}陣列
hasFields
布林值
如果片段有欄位,則為true

屬性結構 properties-structure

properties物件對於選取的片段和每個參照的片段具有相同的結構。

屬性
類型
說明
範例
id
字串
片段的UUID
title
字串
片段的標題
騎腳踏車去猶他州南部
description
字串
片段的說明
冒險……
path
字串
片段的JCR路徑
/content/dam/...
hasDescription
布林值
如果說明不為空白,則為True
true
createdDate
字串
ISO-8601建立日期
modifiedDate
字串
ISO-8601修改日期
publishedDate
字串
ISO-8601發佈日期
status
字串
發佈層的復寫狀態
DRAFT
model
地圖
包含: idpathnametechnicalNamedescription
validationStatus
清單
專案,例如{property, message}
previewReplicationStatus
字串
預覽層的復寫狀態
tags
清單
片段層級標籤。 每個專案: idtitletitlePathnamepathdescription
fieldTags
清單
欄位層級標籤。 與tags的結構相同。

範例:範本存取

針對(選取的)內容片段:

{{properties.title}}, {{properties.description}}, {{{fields.field_name}}}

引用的內容片段 referenced-content-fragments

任何參考片段的內容物件結構:

變數
類型
說明
hasReferencedFragments
布林值
存在參考時為true
referencedFragments
清單
參照的片段物件陣列
referencesError
布林值
載入參考時發生錯誤true
referencesErrorMessage
字串
referencesErrortrue時的錯誤訊息

引用的片段結構 referenced-fragment-structure

referencedFragments中的每個專案都包含:

屬性
類型
說明
anchorId
字串
HTML安全的錨點ID (位於片段層級;不是內容片段屬性)
properties
地圖
片段中繼資料(與上述結構相同)
hasFields
布林值
如果片段有欄位,則為真
fields
地圖
直接存取此片段中的欄位
allFields
清單
反複專案的{name, value}陣列

範例:第一個參照內容片段的範本存取(0索引清單中的第一個專案):

{{referencedFragments.[0].anchorId}}, {{referencedFragments.[0].properties.title}}, {{referencedFragments.[0].properties.description}}

或者從欄位地圖:

{{{ fields.referenced_cf_field_name.properties.description }}}

基本欄位存取權 basic-field-access

建議使用直接欄位存取,必要時您可以逐一檢視所有欄位。

使用欄位對應直接透過名稱存取欄位:

<!DOCTYPE html>
<html>
<head>
  <title>{{properties.title}}</title>
</head>
<body>
  <article>
    <h1>{{{fields.title}}}</h1>
    <p class="subtitle">{{{fields.subtitle}}}</p>
    <div class="content">
      {{{fields.description}}}
    </div>
    <div class="image">
      {{{fields.primaryImage}}}
    </div>
  </article>
</body>
</html>

請記住:

  • 如果欄位值包含預先轉譯的HTML (RTF),請使用三大括弧{{{ }}}
  • 欄位名稱(標題、子標題、說明、primaryImage) 必須​完全符合您的內容片段模式​
  • 未轉譯缺少的欄位 — 不會擲回錯誤,且Handlebars語法在轉譯的HTML片段中仍然存在(和可見)

循環檢視所有欄位 iterate-through-all-fields

當您事先不知道欄位名稱時,請使用allFields

<table>
  <thead>
    <tr>
      <th>Field Name</th>
      <th>Field Value</th>
    </tr>
  </thead>
  <tbody>
    {{#each allFields}}
    <tr>
      <td>{{name}}</td>
      <td>{{{value}}}</td>
    </tr>
    {{/each}}
  </tbody>
</table>

請記住:

  • {{name}}使用雙大括弧(純文字標籤)
  • {{{value}}}使用三大括弧(預先轉譯的HTML值)

巢狀內容片段 nested-content-fragments

當內容片段欄位參考另一個內容片段時,您可以使用點標籤法來直接存取參考片段中的欄位。

單級巢狀 single-level-nesting

單層巢狀結構範例:

<article>
  <h1>{{{fields.title}}}</h1>

  <!-- Access author (a referenced Content Fragment) -->
  <div class="author-info">
    <h3>Author</h3>
    <p>Name: {{{fields.author.name}}}</p>
    <p>Email: {{{fields.author.email}}}</p>
    <p>Bio: {{{fields.author.bio}}}</p>
  </div>

  <div class="content">
    {{{fields.content}}}
  </div>
</article>

模式: fields.referenceFieldName.nestedFieldName

多階層巢狀 multi-level-nesting

系統支援無限制的巢狀深度:

<article>
  <h1>{{{fields.title}}}</h1>

  <div class="author-details">
    <!-- Level 1: Author -->
    <p>Author: {{{fields.author.name}}}</p>

    <!-- Level 2: Author's Organization -->
    <p>Organization: {{{fields.author.organization.name}}}</p>
    <p>Website: {{{fields.author.organization.website}}}</p>

    <!-- Level 3: Organization's Address -->
    <p>Located in: {{{fields.author.organization.address.city}}},
    {{{fields.author.organization.address.country}}}</p>
  </div>

  <div class="content">
    {{{fields.content}}}
  </div>
</article>

模式: fields.level1.level2.level3.fieldName (有限的深度;預設為5,使用API時可延伸至10)

API引數需求:水化 api-parameter-requirements

若要啟用巢狀內容片段存取,您必須在API呼叫中包含hydration查詢引數:

若要啟用水合:

# Enable hydration with depth=2 for 2 levels of nesting
GET /adobe/sites/cf/fragments/{id}/preview?hydration=%7B%22enabled%22%3Atrue%2C%22maxDepth%22%3A2%7D
maxDepth
載入的內容
1
主要片段+直接參考
2
主要片段+直接參照+其參照
3+
最多繼續10個層級

多值欄位 multi-valued-fields

多值欄位有多種型別。

多值文字欄位 multi-valued-text-fields

多值時文字、數字、日期和其他簡單欄位會變成陣列:

<article>
  <h1>{{{fields.title}}}</h1>

  <!-- Access individual items by index (use dot before bracket) -->
  <div class="tags">
    <span class="tag">{{{fields.tags.[0]}}}</span>
    <span class="tag">{{{fields.tags.[1]}}}</span>
  </div>

  <!-- Better: Iterate through all tags -->
  <div class="tags">
    {{#each fields.tags}}
    <span class="tag">{{{this}}}</span>
    {{/each}}
  </div>
</article>

請記住,在Handlebars中按索引存取陣列專案時:

  • 建議內容:
    • .[0] (括弧前的點)
  • 非:
    • [0]

多值數字欄位 multi-valued-number-fields

數字會轉換為字串以供轉譯:

<div class="pricing">
  <h3>Available Prices:</h3>
  {{#each fields.prices}}
  <span class="price">${{{this}}}</span>
  {{/each}}
</div>

多值內容片段參考 multi-valued-content-fragment-references

當欄位參考多個內容片段時:

<div class="authors">
  <h3>Authors:</h3>
  {{#each fields.authors}}
  <div class="author">
    <h4>{{{this.name}}}</h4>
    <p>Email: {{{this.email}}}</p>
    {{#if this.bio}}
    <p class="bio">{{{this.bio}}}</p>
    {{/if}}
  </div>
  {{/each}}
</div>

多值資產參考 multi-valued-asset-references

針對資產內容型別(例如影像和檔案)設定的內容參考欄位會預先轉譯為HTML。 多值資產會變成陣列:

<!-- Single asset -->
<div class="hero-image">
  {{{fields.heroImage}}}
</div>

<!-- Multi-valued: iterate through all images -->
<div class="gallery">
  {{#each fields.gallery}}
  <div class="image">{{{this}}}</div>
  {{/each}}
</div>

巢狀多值參照 nested-multi-valued-references

多值參照可以包含任何深度的多值參照:

{{#each fields.chapters}}
<div class="chapter">
  <h3>Chapter: {{{this.title}}}</h3>

  {{#each this.authors}}
  <p>Author: {{{this.name}}}</p>

  {{#each this.publications}}
  <p>Publication: {{{this.title}}}</p>
  {{/each}}
  {{/each}}
</div>
{{/each}}

回圈與反複專案 loops-and-iteration

Handlebars提供{{#each}}協助程式,可反複處理陣列和物件。

反複處理陣列 iterating-over-arrays

反複處理陣列的範例:

<!-- Simple array iteration -->
{{#each fields.tags}}
<span class="tag">{{{this}}}</span>
{{/each}}

<!-- Array of objects -->
{{#each fields.authors}}
<div class="author">
  <h4>{{{this.name}}}</h4>
  <p>{{{this.email}}}</p>
</div>
{{/each}}

<!-- With empty-state fallback -->
{{#each fields.tags}}
<span class="tag">{{{this}}}</span>
{{snippet-not-found:else}}
<p>No tags available.</p>
{{/each}}

回圈中的特殊變數 special-variables-in-loops

{{#each}}區塊內,Handlebars提供特殊變數:

{{#each fields.items}}
<div class="item">
  <p>Index: {{@index}}</p>     <!-- 0-based index -->
  <p>Number: {{@number}}</p>   <!-- 1-based index -->
  <p>First: {{@first}}</p>     <!-- true for first item -->
  <p>Last: {{@last}}</p>       <!-- true for last item -->
  <p>Value: {{{this}}}</p>     <!-- current item -->
</div>
{{/each}}

<!-- Example: numbered steps with first/last CSS classes -->
<ul>
  {{#each fields.steps}}
  <li class="{{#if @first}}first{{/if}} {{#if @last}}last{{/if}}">
    Step {{@number}}: {{{this}}}
  </li>
  {{/each}}
</ul>

反複處理引用的片段 iterating-over-referenced-fragments

反複處理參考片段的範例:

{{#if hasReferencedFragments}}
<section class="references">
  <h2>Related Content</h2>
  {{#each referencedFragments}}
  <article id="{{anchorId}}">
    <h3>{{title}}</h3>
    {{#if hasDescription}}
    <p>{{description}}</p>
    {{/if}}
    {{#if hasFields}}
    <ul>
      {{#each allFields}}
      <li><strong>{{name}}:</strong> {{{value}}}</li>
      {{/each}}
    </ul>
    {{/if}}
  </article>
  {{/each}}
</section>
{{/if}}

巢狀回圈 nested-loops

巢狀回圈的範例:

{{#each fields.categories}}
<section class="category">
  <h2>{{{this.name}}}</h2>

  {{#each this.products}}
  <article class="product">
    <h3>{{{this.name}}}</h3>
    <p>{{{this.description}}}</p>
  </article>
  {{/each}}
</section>
{{/each}}

條件式演算 conditional-rendering

根據資料可用性,使用條件來顯示或隱藏內容。

基本If/Else basic-if-else

基本if-else建構的範例:

{{#if hasMainDescription}}
<p class="description">{{properties.description}}</p>
{{snippet-not-found:else}}
<p class="no-description">No description available.</p>
{{/if}}

<!-- Check field existence before rendering -->
{{#if fields.author}}
<div class="author">
  <p>By {{{fields.author.name}}}</p>
</div>
{{/if}}

{{#if fields.publishDate}}
<time>{{{fields.publishDate}}}</time>
{{/if}}

Unless (負值條件式) unless-negative-conditional

unless協助程式:

<!-- Show author unless explicitly hidden -->
{{#unless fields.hideAuthor}}
<div class="author">{{{fields.author.name}}}</div>
{{/unless}}

巢狀條件 nested-conditials

巢狀條件式範例:

{{#if fields.author}}
<div class="author">
  <h3>{{{fields.author.name}}}</h3>

  {{#if fields.author.bio}}
  <p class="bio">{{{fields.author.bio}}}</p>
  {{/if}}

  {{#if fields.author.website}}
  <a href="{{{fields.author.website}}}">Visit Website</a>
  {{/if}}
</div>
{{/if}}

內建Handlebars協助程式 built-in-handlebars-helpers

Handlebars包含數個內建協助程式,超出{{#if}}{{#each}}

協助程式
說明
{{#if condition}}
如果條件為真,則呈現內容。 假值: falseundefinednull0""[]
{{#unless condition}}
條件為假時轉譯內容(與#if相反)
{{#each array}}
為每個專案重複內容;空白陣列支援{{else}}
{{#with object}}
為巢狀物件建立新範圍,減少路徑重複
{{lookup this "key"}}
依名稱動態查詢屬性

使用協助程式 with-helper

為巢狀物件建立新範圍,以減少重複的路徑字首:

{{#with fields.author}}
<div class="author">
  <h3>{{{name}}}</h3>     <!-- same as fields.author.name -->
  <p>{{{email}}}</p>      <!-- same as fields.author.email -->
  <p>{{{bio}}}</p>        <!-- same as fields.author.bio -->
</div>
{{/with}}

<!-- Useful for deeply nested objects -->
{{#with fields.author.organization}}
<div class="organization">
  <h4>{{{name}}}</h4>
  <p>{{{website}}}</p>
  {{#with address}}
  <address>
    {{{street}}}<br/>
    {{{city}}}, {{{country}}}
  </address>
  {{/with}}
</div>
{{/with}}

進階模式 advanced-patterns

以下是一些進階模式的範例。

在巢狀回圈中存取父項前後關聯 accessing-parent-context-in-nested-loops

使用../從巢狀回圈記憶體取父系範圍:

<h1>{{{fields.title}}}</h1>

{{#each fields.chapters}}
<section class="chapter">
  <h2>Chapter {{@number}}: {{{this.title}}}</h2>

  {{#each this.sections}}
  <article>
    <!-- Access parent chapter via ../ -->
    <p>Chapter: {{{../title}}}</p>

    <!-- Access root context via ../../ -->
    <p>Book: {{{../../fields.title}}}</p>

    <h3>{{{this.title}}}</h3>
    <div>{{{this.content}}}</div>
  </article>
  {{/each}}
</section>
{{/each}}

動態CSS類別 dynamic-css-classes

動態CSS類別的範例:

<article class="content-fragment {{#if hasMainDescription}}with-description{{/if}} {{#if hasReferencedFragments}}has-refs{{/if}}">
  <h1>{{properties.title}}</h1>
</article>

<ul class="tag-list">
  {{#each fields.tags}}
  <li class="tag {{#if @first}}first{{/if}} {{#if @last}}last{{/if}}">
    {{{this}}}
  </li>
  {{/each}}
</ul>

完整範例 complete-examples

提供幾個完整的範例以供參考。

有作者的部落格

含有作者詳細資料的部落格:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>{{properties.title}}</title>
  <style>
    body { font-family: Arial, sans-serif; margin: 40px; }
    .author-card { background: #f5f5f5; padding: 20px; border-radius: 8px; }
    .tags { display: flex; gap: 10px; }
    .tag { background: #007bff; color: white; padding: 5px 10px; border-radius: 4px; }
  </style>
</head>
<body>
  <article>
    <header>
      <h1>{{{fields.title}}}</h1>
      {{#if fields.publishDate}}
      <time datetime="{{{fields.publishDate}}}">{{{fields.publishDate}}}</time>
      {{/if}}
      {{#if fields.tags}}
      <div class="tags">
        {{#each fields.tags}}
        <span class="tag">{{{this}}}</span>
        {{/each}}
      </div>
      {{/if}}
    </header>

    {{#if fields.heroImage}}
    <figure>
      {{{fields.heroImage}}}
      {{#if fields.imageCaption}}
      <figcaption>{{{fields.imageCaption}}}</figcaption>
      {{/if}}
    </figure>
    {{/if}}

    <div class="content">
      {{{fields.content}}}
    </div>

    {{#if fields.author}}
    <aside class="author-card">
      <h3>About the Author</h3>
      <h4>{{{fields.author.name}}}</h4>
      {{#if fields.author.profilePicture}}
      <div class="author-image">{{{fields.author.profilePicture}}}</div>
      {{/if}}
      {{#if fields.author.bio}}
      <p>{{{fields.author.bio}}}</p>
      {{/if}}
      {{#if fields.author.email}}
      <p>Contact: <a href="mailto:{{{fields.author.email}}}">{{{fields.author.email}}}</a></p>
      {{/if}}
    </aside>
    {{/if}}
  </article>
</body>
</html>

必要的API呼叫:

GET /adobe/sites/cf/fragments/{id}/preview?hydration=%7B%22enabled%22%3Atrue%2C%22maxDepth%22%3A1%7D

通用表格檢視(沒有欄位先前的知識) generic-table-view-no-prior-knowledge-of-fields

一般表格檢視,不具欄位固有的知識。 與​ 一般範本 ​類似:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>{{properties.title}}</title>
  <style>
    body { font-family: Arial, sans-serif; margin: 40px; }
    table { width: 100%; border-collapse: collapse; margin: 20px 0; }
    th, td { border: 1px solid #ddd; padding: 12px; text-align: left; }
    th { background-color: #f4f4f4; font-weight: bold; }
    .ref-section { background: #f9f9f9; padding: 20px; margin: 20px 0; border-radius: 8px; }
  </style>
</head>
<body>
  <header>
    <h1>{{properties.title}}</h1>
    {{#if properties.description}}<p>{{properties.description}}</p>{{/if}}
    <p><small>Path: {{properties.path}}</small></p>
  </header>

  {{#if hasFields}}
  <section>
    <h2>Fields</h2>
    <table>
      <thead>
        <tr><th>Field Name</th><th>Field Value</th></tr>
      </thead>
      <tbody>
        {{#each allFields}}
        <tr>
          <td><strong>{{name}}</strong></td>
          <td>{{{value}}}</td>
        </tr>
        {{/each}}
      </tbody>
    </table>
  </section>
  {{/if}}

  {{#if hasReferencedFragments}}
  <section class="ref-section">
    <h2>Referenced Content Fragments</h2>
    {{#each referencedFragments}}
    <article id="{{anchorId}}" style="margin-bottom: 30px;">
      <h3>{{title}}</h3>
      {{#if hasDescription}}<p>{{description}}</p>{{/if}}
      <p><small>Path: {{path}}</small></p>
      {{#if hasFields}}
      <table>
        <thead>
          <tr><th>Field Name</th><th>Field Value</th></tr>
        </thead>
        <tbody>
          {{#each allFields}}
          <tr>
            <td><strong>{{name}}</strong></td>
            <td>{{{value}}}</td>
          </tr>
          {{/each}}
        </tbody>
      </table>
      {{/if}}
    </article>
    {{/each}}
  </section>
  {{/if}}
</body>
</html>

最佳做法 best-practices

最佳實務包括:

  1. 包含HTML標籤內容的欄位值一律使用三大括弧。

    • 欄位值是預先轉譯的HTML。

      note
      NOTE
      雙大括弧會將原始HTML標籤顯示為純文字。
    code language-handlebars
    <!-- CORRECT -->
    {{{fields.description}}}
    
    <!-- WRONG - displays HTML tags as text -->
    {{fields.description}}
    
  2. 存取巢狀欄位之前,請先檢查是否存在。

    code language-handlebars
    <!-- GOOD: check before accessing nested fields -->
    {{#if fields.author}}
    <p>By {{{fields.author.name}}}</p>
    {{/if}}
    
    <!-- RISKY: may render empty if author is not set -->
    <p>By {{{fields.author.name}}}</p>
    
  3. 儘可能使用直接欄位存取。

    • 它比重複allFields及依名稱比對更易讀取及維護。
  4. 含有區段註解的結構範本。

    code language-handlebars
    {{! ===== HEADER SECTION ===== }}
    <header>
      <h1>{{properties.title}}</h1>
    </header>
    
    {{! ===== MAIN CONTENT ===== }}
    <main>
      {{#if hasFields}}
      <!-- fields rendering -->
      {{/if}}
    </main>
    
    {{! ===== REFERENCES ===== }}
    {{#if hasReferencedFragments}}
    <!-- references rendering -->
    {{/if}}
    
  5. 使用遞補功能順利處理遺失的資料。

    code language-handlebars
    {{#if fields.title}}
    <h1>{{{fields.title}}}</h1>
    {{snippet-not-found:else}}
    <h1>Untitled</h1>
    {{/if}}
    
  6. 請一律使用正確的HTML檔案結構。

    code language-handlebars
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>{{properties.title}}</title>
    </head>
    <body>
      <!-- your content here -->
    </body>
    </html>
    
  7. 使用多種內容案例進行測試:

    • 所有欄位已完整填入
    • 缺少選用欄位
    • 清空多值欄位
    • 深層巢狀(多層)
    • 無法載入的參考
  8. 使用語意HTML元素:

    • 如需更好的協助工具,請使用<article><header><main><footer><time><address>或類似專案。
  9. 將樣式保留在CSS中。

    • 使用<style>標籤或外部樣式表。
    • 儘可能避免使用內嵌樣式。
  10. 檔案複雜邏輯:

    • 使用Handlebars註解({{! }})
    • 請勿使用HTML註解,這些註解會出現在轉譯的輸出中。

疑難排解 troubleshooting

部分疑難排解提示包括:

問題
症狀
解決方案
欄位會將HTML標籤顯示為文字
<p>Hello World</p>按字面顯示
使用三大括弧: {{{fields.description}}}
巢狀內容片段欄位是空的或顯示[物件物件]
{{{fields.author.name}}}為空白
在API呼叫中啟用水合;驗證欄位名稱拼字;檢查maxDepth是否足夠深
多值欄位只會顯示第一個專案
含有五個專案的陣列只會呈現一個
使用{{#each fields.tags}}來迭代所有專案
陣列索引存取無法運作
{{{fields.tags[0]}}}呈現為空白
使用點括弧語法: {{{fields.tags.[0]}}}
引用的片段未出現
hasReferencedFragments一律為false
啟用水合: ?hydration=%7B%22enabled%22%3Atrue%7D;也檢查{{#if referencesError}}
範本不會呈現任何內容
空白頁面或空白輸出
檢查未關閉的{{#if}}{{#each}}區塊;新增診斷輸出: <pre>hasFields: {{hasFields}} | title: {{properties.title}}</pre>
註解會顯示在轉譯的頁面中
一般使用者可見的HTML註解文字
使用Handlebars註解{{! comment }}而非HTML <!-- comment -->
條件式一律會評估為true
{{#if fields.enabled}}一律為真
注意:字串"false"在Handlebars中為truthy。 只有實際的falsenullundefined0""[]是假的。
特殊字元呈現為實體
已顯示&lt;&amp;而非<&
使用三大括弧呈現預先呈現的HTML內容: {{{fields.content}}}
無法從內部回圈存取外部回圈變數
來自父系#each的變數未定義
../用於父系領域: {{{../name}}};將../../用於祖系領域
空白清單未顯示遞補訊息
專案為零的多值欄位不顯示任何內容
{{#each}}內使用{{else}}{{#each fields.tags}}...{{else}}<p>No tags</p>{{/each}}

使用資產 working-with-assets

從內容片段參考的Assets會由AEM預先轉譯為HTML。 因此,所有資產參考都必須使用三大括弧。

資產類型
呈現為
影像
<img src="..." alt="...">
影片
<video>元素
文件
<a href="...">連結

請記住:

  • 資產欄位一律使用三大括弧。
    使用雙大括弧將逸出產生的HTML標籤,並將其顯示為原始文字,而非轉譯影像、視訊或連結。

資產欄位使用狀況 asset-field-usage

資產欄位使用方式的範例:

<!-- CORRECT - triple braces render the image -->
{{{fields.heroImage}}}
<!-- Output: <img src="path/to/image.jpg" alt="Hero"> -->

<!-- WRONG - double braces escape the tag, showing it as text -->
{{fields.heroImage}}
<!-- Output: &lt;img src="path/to/image.jpg" alt="Hero"&gt; -->

自訂範本協助程式 customer-template-helpers

系統提供自訂Handlebars協助程式,用於產生具有自訂HTML屬性的HTML元素。 這些協助程式可讓您控制產生的標籤,同時處理從預先轉譯的內容擷取來源URL的複雜性。

可用的協助程式:

  1. asset — 產生具有自訂屬性的<img>標籤
  2. text — 產生<span>標籤以自訂屬性將文字內容換行

asset協助程式 asset-helper

語法:

{{{asset fieldValue attribute1="value1" attribute2="value2"}}}

請記住:

  • 使用三大括弧{{{ }}}搭配資產協助程式,不要使用雙大括弧!

四個基本範例 four-basic-examples

以下是四個基本範例:

<!-- Add a CSS class to an image -->
{{{asset fields.heroImage class="hero-image"}}}
<!-- Output: <img src="..." alt="..." class="hero-image"> -->

<!-- Add multiple CSS classes -->
{{{asset fields.productImage class="product-img responsive shadow"}}}

<!-- Add id and class -->
{{{asset fields.logo class="brand-logo" id="main-logo"}}}

<!-- Add data attributes -->
{{{asset fields.thumbnail class="thumb" data-category="product" data-id="123"}}}

支援的屬性 supported-attributes

您可以新增任何有效的HTML屬性:

屬性
範例
class
class="my-class another-class"
id
id="unique-id"
alt
alt="Custom alt text" (overrides existing alt)
data-*
data-index="1" data-type="hero"
aria-*
aria-label="Description" aria-hidden="true"
width
width="300"
height
height="200"
loading
loading="lazy"
style
style="border-radius: 8px;"

覆寫替代文字 override-alt-text

可以覆寫原始影像的alt屬性:

{{{asset fields.photo alt="Custom description for accessibility"}}}

複雜範例 complex-example

一個複雜的範例是:

<article class="blog-post">
<header>
{{{asset fields.featuredImage
class="featured-image responsive"
id="post-hero"
loading="lazy"
data-post-id="12345"}}}
</header>
</article>

搭配回圈使用 using-with-loops

回圈中的資產協助程式:

{{#each fields.galleryImages}}
{{{asset this class="gallery-item" data-index=@index}}}
{{/each}}

text協助程式 text-helper

文字協助程式會產生使用自訂CSS類別和HTML屬性繞排文字內容的<span>標籤。 適合用於設定個別文字欄位的樣式。

語法:

{{{text fieldValue attribute1="value1" attribute2="value2"}}}

請記住:

  • 文字協助程式使用三大括弧{{{ }}},不要使用雙大括弧!

三個基本範例 three-basic-examples

以下是三個基本範例:

<!-- Add a CSS class to text -->
{{{text fields.title class="article-title"}}}
<!-- Output: <span class="article-title">The Title Text</span> -->

<!-- Add multiple attributes -->
{{{text fields.price class="price-tag" id="product-price" data-currency="USD"}}}

<!-- Style inline text -->
{{{text fields.highlightedText class="highlighted" style="background: yellow;"}}}

常見使用案例 common-use-cases

常見的使用案例包括:

<!-- Styling article metadata -->
<article>
<header>
{{{text fields.category class="category-badge"}}}
<h1>{{{fields.title}}}</h1>
{{{text fields.author class="byline"}}}
{{{text fields.publishDate class="date"}}}
</header>
</article>

<!-- Creating styled labels -->
<div class="product-card">
{{{text fields.productName class="product-name"}}}
{{{text fields.brand class="brand-label" data-brand-id="abc"}}}
{{{text fields.price class="price" id="main-price"}}}
</div>

<!-- Accessibility enhancements -->
{{{text fields.importantNote class="alert" role="alert" aria-live="polite"}}}

含回圈 with-loops

含有回圈的常見使用案例包括:

{{#each fields.tags}}
{{{text this class="tag-badge"}}}
{{/each}}

協助程式 — 屬性驗證 helpers-attribute-validation

兩個協助程式都會先驗證屬性名稱,再將其納入輸出中。

有效的屬性名稱:

  • 開頭必須是字母(a-z、A-Z)

  • 只能包含字母、數字、連字型大小和底線;請參閱命名慣例

  • 不區分大小

  • 例如:

    • 有效:
      • class, id, data-value, aria-label, my_attr, dataIndex1
    • 無效:
      • 123-attr, -class, @special, $money

系統會以無訊息方式略過無效的屬性名稱,但記錄檔中會顯示警告:

{{{asset fields.image class="valid" 123-invalid="skipped" id="also-valid"}}}
<!-- Output: <img src="..." alt="..." class="valid" id="also-valid"> -->
<!-- 123-invalid is skipped because it starts with a number -->

請記住:

  • 檢查伺服器記錄檔中是否有「封鎖的無效屬性名稱格式」警告。

比較直接輸出與協助程式 comparing-direct-output-to-helpers

何時產生直接輸出{{{fields.xxx}}}

  • 您不需要自訂樣式
  • 您希望預設輸出保持原樣
  • 欄位包含您不想修改的複雜HTML

何時使用協助程式:

  • 您需要新增CSS類別以使用樣式
  • 您需要新增自訂HTML屬性(data-*aria-*等)
  • 想要一致且受控制的HTML結構

比較:

<!-- Direct output - uses whatever HTML the system generates -->
{{{fields.heroImage}}}
<!-- Output: <img src="/path/image.jpg" alt="Hero Image"> -->

<!-- With asset helper - full control over attributes -->
{{{asset fields.heroImage class="hero responsive" id="main-hero" loading="lazy"}}}
<!-- Output: <img src="/path/image.jpg" alt="Hero Image" class="hero responsive" id="main-hero" loading="lazy"> -->

快速參考 quick-reference

提供一些快速參考資訊以供參考。

內容變數 context-variables

上下文變數:

{{properties}}                <!-- Main fragment metadata -->
{{fields}}                    <!-- Map keyed by field name to rendered values (such as strings, lists, nested maps for Content Fragment references, commerce maps, HTML, and others) -->
{{allFields}}                 <!-- List of { name, value } maps (uniform iteration) -->
{{hasFields}}.                <!-- Boolean -->
{{hasReferencedFragments}}.   <!-- Boolean -->
{{referencedFragments}}       <!-- List of referenced-fragment maps -->

欄位存取權 field-access

如何存取欄位:

{{{fields.fieldName}}}                    <!-- Direct field -->
{{{fields.author.name}}}                  <!-- Nested Content Fragment field -->
{{{fields.author.org.address.city}}}      <!-- Multi-level nesting -->
{{{fields.tags.[0]}}}                     <!-- Array by index -->
{{#each fields.tags}}...{{/each}}         <!-- Array iteration -->
{{{fields.authors.[0].name}}}             <!-- Multi-valued Content Fragment reference -->

控制流程 control-flow

控制流程:

{{#if condition}}...{{/if}}               <!-- Conditional -->
{{#if condition}}...{{else}}...{{/if}}    <!-- If/else -->
{{#unless condition}}...{{/unless}}       <!-- Negative conditional -->
{{#each array}}...{{/each}}               <!-- Iteration -->
{{#each array}}...{{else}}...{{/each}}    <!-- Iteration with fallback -->
{{#with object}}...{{/with}}              <!-- Change scope -->

回圈變數 loop-variables

回圈變數:

{{@index}}        <!-- 0-based index -->
{{@number}}       <!-- 1-based index -->
{{@first}}        <!-- true for first item -->
{{@last}}         <!-- true for last item -->
{{@key}}          <!-- Object property name -->
{{this}}          <!-- Current item -->
{{../parent}}     <!-- Access parent scope -->

自訂範本協助程式 custom-template-helpers

自訂範本協助程式:

{{{asset fields.image class="css-class"}}}                <!-- Image with class -->
{{{asset fields.image class="c1" id="my-id"}}}            <!-- Image with multiple attrs -->
{{{asset fields.image alt="Custom alt text"}}}            <!-- Override alt text -->
{{{asset fields.image loading="lazy" data-x="val"}}}      <!-- Custom attributes -->

{{{text fields.title class="title-class"}}}               <!-- Span with class -->
{{{text fields.price class="price" id="p1"}}}             <!-- Span with multiple attrs -->
{{{text this class="item" data-index=@index}}}            <!-- In loops -->

其他資源 additional-resources

其他資源可供使用:

recommendation-more-help
experience-manager-cloud-service-help-main-toc