CakePHP3のレイアウトを使ってデザインを統一したい

CakePHPにはレイアウトという機能があります。

テンプレートの上位互換バージョンみたいなものです。

これを用いることでデザインの統一が図れます。

自分はかなり使ってます。

このレイアウトについてご紹介します。

【自分の環境】
macOS Catalina
PHP7.4.2
CakePHP3.8
MAMP5.7
Apache2.2
MySQL5.7

レイアウトはどこにあるのか

[アプリ名]/src/Templatesディレクトリの中にあります。

Layoutというディレクトリです。

ここにテンプレートとして保存します。

そしてコントローラで読み込めば使えるようになります。

その方法を説明していきます。

まずはレイアウトテンプレートを作る

自分のサービスで作ったレイアウトテンプレートのコードを示します。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8mb4">
    (中略)
    <?php
        echo $this->Html->css('reset');
        echo $this->Html->css('common');
    ?>
</head>
<body>
    <header class="header">
      (中略)
    </header>
    <nav class="header_nav">
      (中略)
    </nav>
    
    <article>
        <?= $this->fetch('content') ?>
    </article>

    <nav class="footer_nav">
      (中略)
    </nav>
    <footer class="footer">
      (中略)
    </footer>
</body>
</html>

いわゆる普通のHTMLみたいな構成です。

DOCTYPEを書いたり、headを書いたり…。

これらは基本要素で全てのページに書きたくないですよね。

なのでこのレイアウトを読み込むことで省略できるようになります。

自分の場合は①マイページや②マイページ外のページでそれぞれデザインを統一したいので、レイアウトを別々で作っています。

具体的にはヘッダーやフッターは同じものなので、レイアウトに書いています。

そして肝心のコンテンツだけ変えています。

どうやってコンテンツだけを変えるのか

どうやるのかですが、「$this->fetch('content')」と書くだけです。

この「$this->fetch('content')」がそれぞれのアクションに応じたコンテンツに化けてくれます。

もう1つの設定、コントローラでレイアウトを読み込む

そしてコントローラでレイアウトを読み込みます。

// 初期化処理
    public function initialize()
    {
        parent::initialize();
      (中略)
        // レイアウトをmypage.ctpに変更
        $this->viewBuilder()->setLayout('mypage');
    }

ファンクションinitializeに「$this->viewBuilder()->setLayout('mypage');」を書いてください。

これでこのコントローラはLayoutディレクトリにあるmypage.ctpを読み込むようになります。

実例の説明

例えば、自分はPagesControllerにはexternal_page.ctp(外部ページ)というレイアウトを適用しています。

external_page.ctpには「$this->fetch('content')」を記述しています。

そして普通に[アプリ名]/src/Templatesディレクトリの中のPagesディレクトリにビューテンプレートを作成します。

これがコンテンツとなります。

するとPagesControllerの各ページにはヘッダーやフッターなどはexternal_page.ctpが、コンテンツは上記のビューテンプレートが入ります。

違うコントローラでマイページのレイアウトを読み込んでいるので、マイページもデザインを統一できています。

終わりに

以上となります。

デザインを統一できるのは、かなり便利です。

レイアウトを超える全体を制御できるような、もっと上位のものもあるのかもしれませんが、正直わかっていません。

良い方法があるよという方は、教えていただければ幸いです。

ありがとうございました。