カテゴリ: Symfony 更新日: 2026/02/16

Twigのテンプレート継承を完全ガイド!初心者でもわかるbase.html.twigの使い方と構造

Twigのテンプレート継承の仕組みと活用方法(base.html.twigなど)
Twigのテンプレート継承の仕組みと活用方法(base.html.twigなど)

先生と生徒の会話形式で理解しよう

生徒

「Twigで毎回HTMLの同じ部分を書くのって大変じゃないですか?」

先生

「そのとおりですね。そういうときには、テンプレート継承という仕組みを使うと便利です。」

生徒

「テンプレート継承ってなんですか?初心者でも使えますか?」

先生

「はい、Twigではbase.html.twigという親テンプレートを作って、子テンプレートで使い回すことができます。これから、やさしく説明していきますよ!」

1. Twigのテンプレート継承とは?初心者でもわかる仕組み

1. Twigのテンプレート継承とは?初心者でもわかる仕組み
1. Twigのテンプレート継承とは?初心者でもわかる仕組み

Twigのテンプレート継承とは、Webサイトの「土台(親)」となる共通の型を作り、各ページ(子)がその型を「再利用」する仕組みのことです。プログラミングの「継承」と聞くと難しく感じますが、実は身近なものに例えると非常にシンプルです。

たとえば、「たい焼き」をイメージしてみてください。

  • 親テンプレート(金型): たい焼きの外側の形。どのたい焼きも同じ形をしています。
  • 子テンプレート(中身): 「あんこ」「カスタード」「チョコ」など、中に入れる具材だけを変えます。

Webサイトで言えば、ヘッダー、メニュー、フッターといった「どのページでも変わらない部分」をbase.html.twig(親)に一度だけ書き、中身の文章や画像といった「ページごとに変わる部分」だけを子テンプレートで作成します。

もし継承を使わずに、100ページあるサイトのメニューを1箇所修正しようとしたら、100個のファイルをすべて書き直さなければなりません。しかし、テンプレート継承を使っていれば、親ファイルを1つ直すだけで、100ページすべてに修正が反映されます。

この仕組みは「DRY原則(Don't Repeat Yourself:同じことを繰り返さない)」という、プログラミングにおいて最も大切な考え方のひとつに基づいています。初心者の方こそ、この「楽をするための仕組み」を味方につけることで、ミスが少なくメンテナンスしやすいサイト作りができるようになります。

2. base.html.twigを作成する

2. base.html.twigを作成する
2. base.html.twigを作成する

まずは、共通部分をまとめたbase.html.twigというファイルを作成します。これは、templates/フォルダに保存します。


<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>{% block title %}デフォルトタイトル{% endblock %}</title>
  </head>
  <body>
    <header>
      <h1>共通ヘッダー</h1>
    </header>

    <main>
      {% block body %}{% endblock %}
    </main>

    <footer>
      <p>共通フッター</p>
    </footer>
  </body>
</html>

{% block %}は「ここに子テンプレートの内容を入れてね」という印です。中身を差し込むための「空欄」を用意しておくようなイメージです。

3. 子テンプレートから継承する

3. 子テンプレートから継承する
3. 子テンプレートから継承する

次に、子テンプレートを作成して、先ほどのbase.html.twigを引き継いで使う方法を見てみましょう。

例えばhome.html.twigというファイルを作って、次のように書きます。


{% extends 'base.html.twig' %}

{% block title %}ホームページ{% endblock %}

{% block body %}
  <p>こんにちは、これはホームページの内容です。</p>
{% endblock %}

{% extends %}は、「このテンプレートはbase.html.twigを引き継ぎます」という意味です。そして、{% block title %}{% block body %}の中に、それぞれのページで表示したい内容を入れていきます。

4. 実際に表示されるHTML

4. 実際に表示されるHTML
4. 実際に表示されるHTML

上記の継承を使うと、Symfonyがテンプレートを合体させて、以下のようなHTMLを自動で作ってくれます。


<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>ホームページ</title>
  </head>
  <body>
    <header>
      <h1>共通ヘッダー</h1>
    </header>

    <main>
      <p>こんにちは、これはホームページの内容です。</p>
    </main>

    <footer>
      <p>共通フッター</p>
    </footer>
  </body>
</html>

このように、共通の部分はbase.html.twigに書いておいて、それ以外の部分だけを子テンプレートで書くことで、効率よくページを作ることができます。

5. よく使うblock名の例

5. よく使うblock名の例
5. よく使うblock名の例

実際のプロジェクトでは、いろいろなblockを使い分けて、細かい部分も柔軟に差し替えられるようにしておくと便利です。以下は、よく使われるblockの例です。

  • title:ブラウザのタイトルバーに表示する文字
  • stylesheets:CSSを追加する場所
  • javascripts:JavaScriptを追加する場所
  • body:ページのメインの内容

プロジェクトの設計に合わせて、自由にblockを増やすことができます。

6. テンプレート継承を使うメリット

6. テンプレート継承を使うメリット
6. テンプレート継承を使うメリット

テンプレート継承を使うことで、以下のような多くのメリットがあります。

  • 同じHTMLを何度も書かなくていい
  • デザインの変更が1か所で済む(共通部分を直せば全ページに反映)
  • ファイルが見やすく、読みやすい
  • 他の人との共同作業がしやすい

つまり、テンプレート継承は、ウェブページを効率よく、キレイに作っていくための大切な仕組みなのです。

まとめ

まとめ
まとめ

今回の記事では、PHPのモダンな開発現場で欠かせないテンプレートエンジン「Twig」の核心的な機能である「テンプレート継承」について詳しく解説してきました。Web制作やシステム開発において、保守性の高さと開発効率の向上は常に求められる課題です。Twigの継承システムを正しく理解し活用することで、DRY(Don't Repeat Yourself:同じことを繰り返さない)原則を高いレベルで実現できるようになります。

テンプレート継承の重要ポイント

改めて整理すると、テンプレート継承の基本は「共通構造を定義する親テンプレート」と「個別のコンテンツを定義する子テンプレート」の役割分担にあります。親テンプレート(通常は base.html.twig)には、HTMLの骨組みやメタタグ、共通のヘッダー・フッター、外部ライブラリの読み込み設定などを記述します。そして、変化させたい部分を {% block ブロック名 %} で囲んで「差し込み口」を作っておくのがコツです。

子テンプレート側では、先頭で必ず {% extends '親ファイル名' %} を宣言します。これにより、親の全構造を継承した上で、必要なブロックだけを上書き(オーバーライド)することが可能になります。もし子テンプレートで特定のブロックを定義しなければ、親テンプレートに書かれたデフォルトの内容がそのまま表示されるため、フォールバック(予備)の仕組みとしても非常に優秀です。

さらなる応用:複数のブロック活用と親要素の継承

実際の現場では、単にコンテンツを差し替えるだけでなく、特定のページだけ追加でCSSやJavaScriptを読み込みたい場面が多々あります。そのような場合は、親テンプレートに以下のようなブロックを用意しておくと柔軟性が増します。


<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}マイシステム{% endblock %}</title>
    {% block stylesheets %}
    <link rel="stylesheet" href="/css/main.css">
    {% endblock %}
</head>
<body>
    <div id="content">
        {% block body %}{% endblock %}
    </div>

    {% block javascripts %}
    <script src="/js/common.js"></script>
    {% endblock %}
</body>
</html>

例えば、特定のページだけで特別なスタイルを適用したい場合は、子テンプレートで parent() 関数を使う手法もあります。これを使えば、親のブロック内容を保持したまま、新しい要素を追記することができます。


{% extends 'base.html.twig' %}

{% block stylesheets %}
    {{ parent() }}
    <link rel="stylesheet" href="/css/specific-page.css">
{% endblock %}

{% block body %}
    <h1>詳細設定ページ</h1>
    <p>ここには特定のページ専用のコンテンツが入ります。</p>
{% endblock %}

開発効率と運用のメリット

テンプレート継承を採用する最大のメリットは、将来的なデザイン変更やメタタグの修正が発生した際の影響範囲を最小限に抑えられる点にあります。100ページあるサイトでも、共通部分の修正は base.html.twig 一箇所を直すだけで全てのページに即座に反映されます。これは手動で全ファイルを修正する手間を省くだけでなく、人為的な修正漏れというリスクを回避することにも繋がります。

また、PHPエンジニアとしてSymfonyなどのフレームワークを扱う場合、このTwigの概念は必須の知識となります。コードの記述量が減ることで可読性が向上し、自分以外の開発者がソースコードを見たときにも、どこに何が書かれているのかを瞬時に把握できるようになります。

初心者の方は、まずは「ヘッダー・メイン・フッター」というシンプルな3段構成から始めてみてください。慣れてきたら、サイドバーの有無を切り替えたり、ページごとに異なるmetaキーワードを設定したりと、徐々にブロックの数を増やしてカスタマイズしていくのが上達への近道です。Twigをマスターして、スマートでメンテナンス性の高いWebアプリケーション開発を目指しましょう。

先生と生徒の振り返り会話

生徒

先生、テンプレート継承について詳しく教えていただきありがとうございました! 「親」で枠組みを作って「子」で中身を埋めるという考え方が、実際にコードを書いてみてやっと腑に落ちました。 これを使えば、今までコピペで増やしていたHTMLファイルがすごくスッキリしますね。

先生

その通りです!「コピペを減らす」というのは、プログラミングにおいて非常に大切な姿勢なんですよ。 実際に子テンプレートを動かしてみたときに、HTMLのソースコードはどう見えましたか?

生徒

はい、ブラウザでソースを確認したら、親の base.html.twig のコードと、僕が書いた {% block body %} の中身が完璧に合体して一つのHTMLになっていました。 まるで最初から一つのファイルだったみたいに綺麗に出力されていて感動しました。

先生

それは素晴らしい気づきですね。実はPHPの側でも、この継承関係を正しく処理するために、内部で高速なキャッシュを生成しているんです。 ちなみに、もし子テンプレートで {% extends %} を書き忘れたらどうなると思いますか?

生徒

えーっと、そうなると親のレイアウトを呼び出せなくなっちゃうから、真っ白な画面になったり、子テンプレートに書いた文字だけがポツンと表示されたりしそうですね。

先生

正解です。継承は「親を呼ぶ宣言」があって初めて成立します。 あと、よくあるミスとして {% block %} の名前を親と子で打ち間違えてしまうことがあります。 名前が一致しないと、Twigはどこに流し込めばいいかわからず、デフォルトの内容を表示してしまいます。

生徒

なるほど、ブロックの名前はしっかり合わせる必要がありますね。 あと、先生に教えてもらった parent() 関数も便利そうです。 「基本のCSSは読み込みつつ、このページだけ追加したい」っていう場面は多そうなので、さっそく使ってみます!

先生

いいですね。その調子でどんどん試してみてください。 テンプレート継承を使いこなせれば、大規模なサイト制作でも怖くありません。 次は、データを配列で渡して for ループで表示する方法など、もっと実践的なTwigの使い方も学んでいきましょう。

生徒

はい!もっと複雑なレイアウトにも挑戦して、スマートなコードが書けるように頑張ります!

関連記事:
カテゴリの一覧へ
新着記事
New1
Symfony
Symfonyのルーティングの基本を完全ガイド!YAML・PHP・アノテーションの違いもわかりやすく解説
New2
Laravel
LaravelでAPIのレスポンスをテストする方法を完全解説!assertJsonで初心者も安心
New3
CodeIgniter
CodeIgniterでRESTful API開発!初心者でもわかる全体構成ガイド
New4
Symfony
Symfonyのコントローラとは?作成・構造・役割を初心者向けにやさしく解説!
人気記事
No.1
Java&Spring記事人気No1
Laravel
Laravelのシングルアクションコントローラとは?使い方と利点
No.2
Java&Spring記事人気No2
Laravel
Laravelで動的パラメータをルートに渡す方法!初心者にもやさしいルートパラメータの使い方入門
No.3
Java&Spring記事人気No3
Symfony
Symfonyの依存性注入(DI)とは?コンストラクタでの注入方法を初心者向けに徹底解説
No.4
Java&Spring記事人気No4
Laravel
Laravelでキャッシュを使う方法(ファイル・Redis・Memcached)
No.5
Java&Spring記事人気No5
Laravel
Laravelのマイグレーション履歴を確認する方法を徹底解説!migrate:statusの使い方
No.6
Java&Spring記事人気No6
Laravel
LaravelのBlade構文まとめ!@if @foreach など基本ディレクティブ解説
No.7
Java&Spring記事人気No7
Laravel
Laravelで名前付きルートを設定する方法!初心者でもわかるroute()関数の使い方
No.8
Java&Spring記事人気No8
Laravel
Laravelのrefreshとfreshの違いを初心者でもわかる解説