3秒でわかる
共通の骨組みを一度だけ定義し、変わる部分に値を差し込んで出力を作る仕組み。同じ形の繰り返しを1か所にまとめて直せるようにします。
もう少し詳しく
どういうものか
テンプレートは、固定の骨組みと差し替える穴を持ったひな型です。HTMLの中に {{ name }} のような差し込み口を書いておき、値を渡すと完成した文字列が出てきます。Webの画面生成が代表例ですが、メール文面、設定ファイル、コードの雛形など、同じ形を繰り返し作るあらゆる場面で同じ考え方が使われます。
なぜ必要か
同じヘッダーとフッターを持つページが50枚あるとき、HTMLを50回書くと、ロゴを差し替える日に50か所を直すことになります。共通部分をテンプレートに追い出しておけば修正は1か所です。文字列連結でHTMLを組み立てるのと比べて、多くのテンプレートエンジンが自動でHTMLエスケープを行う点も利点です。
具体例
# Jinja2 の例。差し込み口と繰り返しを持つ
from jinja2 import Template
rows = "{% for item in items %}<li>{{ item.name }} は {{ item.price }} 円</li>{% endfor %}"
tpl = Template("<ul>" + rows + "</ul>")
print(tpl.render(items=[{"name": "珈琲", "price": 480}]))// <a href="/glossary/template-literal" class="text-primary font-medium underline underline-offset-2 hover:text-primary-dark">テンプレートリテラル</a>でも同じ発想で書ける
const row = (u) => `<tr><td>${u.name}</td><td>${u.age}</td></tr>`;
const html = users.map(row).join("");つまずきやすいところ
テンプレートの中に条件分岐と計算を書き足していくうちに、ロジックがビューへ染み出す例が非常に多く見られます。合計金額の計算や表示条件の判定は呼び出す側で済ませ、テンプレートには整形済みの値だけを渡します。もうひとつはエスケープの扱いです。利用者が入力した文字列に対して |safe や dangerouslySetInnerHTML のような無効化を使うと、そこがそのままスクリプト混入の入口になります。
似た用語との違い
コンポーネントは、見た目と振る舞いをまとめて再利用する単位で、状態を持てます。テンプレートは値を差し込んで文字列を作る仕組みで、それ自体は状態を持ちません。
覚え方
テンプレートを見て「これは表示か、判断か」と問い、判断が混ざっていたら呼び出す側へ移します。表示の骨組みだけが残っている状態が、直しやすいテンプレートです。
共通部分の切り出し方は、変わらない骨組みと、毎回変わる中身の境目で決めます。迷ったら、2回目に同じ形を書いた時点で切り出します。
