内部の「ビュー」テンプレートを外部の「レイアウト」テンプレートでラップできるのと同様に、あるテンプレートを別のテンプレートで「拡張」することもできます。その違いは微妙ですが重要です。
以下はテンプレート継承の例です。まず、一連のブロックで構成される「親」テンプレート:
<!DOCTYPE html>
<html lang="en">
<head>
{{ setBlock ('head_title') }}{{= getBlock () ~}}
{{ setBlock ('head_meta') }}{{= getBlock () ~}}
{{ setBlock ('head_links') }}{{= getBlock () ~}}
{{ setBlock ('head_styles') }}
<link rel="stylesheet" href="/theme/basic.css" type="text/css" media="screen" />
{{= getBlock () ~}}
{{ setBlock ('head_scripts') }}{{= getBlock () ~}}
</head>
<body>
{{ setBlock ('body_header') }}{{= getBlock () ~}}
{{ setBlock ('body_content') }}{{= getBlock () ~}}
{{ setBlock ('body_footer') }}{{= getBlock () ~}}
</body>
</html>
上記のコードは setBlock()
を通じて一連のブロックを定義し、getBlock()
を通じて 最終的な ブロックの内容を表示します。(タグ後の改行を消費する閉じタグ ~}}
の使用に注目してください。これにより出力の空白行が圧縮されます。)
次に、「親」テンプレートを拡張する「子」テンプレートです。「親」テンプレートを extends()
で拡張し、親ブロックからの内容をオーバーライドまたは修正していることに注目してください:
{{ extends ('parent') }}
{{ setBlock ('head_title') }}
<title>
My Extended Page
</title>
{{ endBlock () }}
{{ setBlock ('head_meta') }}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
{{ endBlock () }}
{{ setBlock ('head_styles') }}
{{ parentBlock () }}
<link rel="stylesheet" href="/theme/custom.css" type="text/css" media="screen" />
{{ endBlock () }}
{{ setBlock ('body_content') }}
<p>The main content for my extended page.</p>
{{ endBlock () }}
最後に、「子」テンプレートをレンダリングすると...
$output = $template('child');
.....出力は以下のようになります:
<!DOCTYPE html>
<html lang="en">
<head>
<title>
My Extended Page
</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="/theme/basic.css" type="text/css" media="screen" />
<link rel="stylesheet" href="/theme/custom.css" type="text/css" media="screen" />
</head>
<body>
<p>The main content for my extended page.</p>
</body>
</html>
同様のアプローチはビューとレイアウトでも可能です。しかし、その方法では1層の拡張のみが可能です(つまり、ビューからレイアウトへ)。extends()
を使用すると、任意の数の層が可能になります。
ビューとレイアウトの両方が extends()
を使用できます。つまり、内部ビューは一連のテンプレートを拡張し、外部レイアウトは異なる一連のテンプレートを拡張することができます。
ブロックはビューとレイアウトの間で共有されます。レイアウトのブロックはビューから参照でき、その逆も可能です。
最後に、テンプレートを拡張する際、getContent()
が期待通りに機能しない場合があります。ブロック 以外 のコンテンツは extends()
の連続呼び出しごとに上書きされるため、最後にレンダリングされたテンプレートのコンテンツのみが捕捉されます。そのため、上記の例のように、ビューの「メイン」コンテンツを独自のブロック内に捕捉するのが最善で、getContent()
を使用するよりも良いでしょう。