テンプレートフラグメント

カーソン・グロス

テンプレートフラグメントは、サーバーサイドレンダリング(SSR)テンプレートライブラリの比較的珍しい機能で、テンプレート全体ではなく、テンプレート内のフラグメントまたは部分的なコンテンツをレンダリングすることができます。 この機能は、ハイパーメディア駆動アプリケーションで非常に役立ちます。なぜなら、テンプレートのフラグメントをレンダリング用に個別のファイルに分割することなく、部分的な更新のために特定のビューを内部的に分解することができ、多数の個別のテンプレートファイルを作成する必要がなくなるからです。

すべてのHTMLを単一のファイルに保持することで、機能の仕組みを理解しやすくなります。これは、行動の局所性の設計原則に従っています。

#動機

Javaのあまり知られていないテンプレート言語であるchill templatesのテンプレートフラグメントが、HDAの構築にどのように役立つかを見てみましょう。

連絡先を表示する単純なchillテンプレート、/contacts/detail.htmlを次に示します。

#/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リクエストを発行します。

表示されている2つのボタンのいずれかをクリックすると、ボタンを囲むdiv内のコンテンツを更新されたボタンに置き換えたいと考えています。(divhx-target="this"に注意してください。このdivのinnerHTMLを置き換えのターゲットとしています。) これにより、「アーカイブ」と「アーカイブ解除」が効果的に切り替わります。

さて、残念ながら、このテンプレートの残りの部分ではなく、ボタンだけをレンダリングしたい場合、通常はボタンを独自のテンプレートファイルに分割し、このテンプレートに含める必要があります。次のようにします。

#/contacts/detail.html
<html>
    <body>
        <div hx-target="this">
          #include archive-ui.html
        </div>
        <h3>Contact</h3>
        <p>${contact.email}</p>
    </body>
</html>
#/contacts/archive-ui.html
#if contact.archived
<button hx-patch="/contacts/${contact.id}/unarchive">Unarchive</button>
#else
<button hx-delete="/contacts/${contact.id}">Archive</button>
#end

これで、2つのテンプレートができました。これでarchive-ui.htmlテンプレートを個別にレンダリングできますが、この分割によりアーカイブ機能の可視性が低下します。detail.htmlテンプレートだけを見ていると、何が起こっているのか分かりにくくなります。

極端に走ると、このようなテンプレートの分解は、非常に多くの小さなテンプレートフラグメントにつながる可能性があり、全体として管理と理解が難しくなります。

#テンプレートフラグメントによる解決

この問題に対処するために、chill templatesには#fragmentディレクティブがあります。このディレクティブを使用すると、テンプレート内のコンテンツのブロックを指定し、そのコンテンツの部分だけをレンダリングできます。

#フラグメントを使用した/contacts/detail.html
<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);

連絡先の詳細ページ全体をレンダリングする場合には、最初のオプションを使用します。

アーカイブ/アーカイブ解除アクションを処理し、ボタンのみを再レンダリングする場合には、2番目のオプションを使用します。

フラグメントを使用すると、UIを単一のファイルにまとめて、異なるテンプレートファイル間を行き来することなく、機能で何が起こっているかを正確に確認できることに注意してください。これにより、機能の実装がよりクリーンで明確になります。

#既知のテンプレートフラグメント実装

フラグメント(およびコントローラーで直接レンダリングする機能)は、テンプレートライブラリでは比較的珍しい機能のようです。htmxやその他のハイパーメディア指向のライブラリを使用する場合の開発エクスペリエンスを向上させる絶好の機会を提供します。

フラグメントの概念の既知の実装を次に示します。

他に知っている方がいれば、お知らせください。リストに追加します。

</>