RitoLabo

CakePHP3のテンプレート基本記法とレイアウトを用いたビュー開発を行う

  • 公開:
  • カテゴリ: PHP CakePHP
  • タグ: PHP,Beginner,MVC,CakePHP,3.5,Template,Layout,View

MVCの「V」=「View」にあたる画面表示部分の構築を、CakePHP3では「テンプレート」と呼ばれる領域のファイルを作成する事で進めていきますが、いくつもあるビューテンプレートの中の共通部分を切り出し「レイアウト」という領域のファイルにまとめておく事ができます。

今回は、テンプレートの基本的な記法とレイアウトを用いてビュー開発を行います。

アジェンダ
  1. 開発環境
  2. レイアウト
  3. コントローラ作成
  4. レイアウト作成
  5. ビュー(テンプレート)作成
  6. CSS作成
    1. リセットCSS
    2. レイアウト用CSS
    3. コンテンツページ用CSS
  7. コントローラ実装
  8. 動作確認

開発環境

今回の開発環境は以下の通りです。

  • Linux CentOS 7
  • Apache 2.4
  • PHP 7.1
  • CakePHP 3.5

CakePHPのバージョンは3系であれば同一手順で進めていけます。

CakePHPのルートディレクトリを「cakephp/」とします。

レイアウト

PHPフレームワークで言う「レイアウト」とは、ビュー(テンプレート)に使われる手法で、同一のHTMLなどをレイアウトとしてまとめておく事で、各コンテンツのビューはそのコンテンツの内容のみをコーディングすれば良くなり、効率化を図ることの出来る手法です。

例えば、HTMLヘッダやフッタをレイアウトとして作成しておくことで、各コンテンツのビューには、そのコンテンツのビューのみを記述すればよく、最終的にレイアウトとコンテンツのビューを合算したHTMLとしてブラウザに描画する事ができます。

ちなみに、CakePHPの初期ページなどにもレイアウトが導入されており、そのレイアウトファイルは
cakephp/src/Template/Layout/default.ctp
になります。

このように、cakephp/src/Template/Layout 配下にctpファイルを設置する事で、レイアウトファイルとして認識されます。

コントローラ作成

まずはコントローラから作成していきます。cakephpのルートディレクトリへ移動し、以下のbakeコマンドを叩いてSamplesコントローラを生成します。

# CakePHPのルートディレクトリへ移動する
cd /path/to/cakephp

# bakeコマンドでコントローラを生成する
bin/cake bake controller Samples

# 実行結果
[demo@localhost cakephp]# bin/cake bake controller Samples

Baking controller class for Samples...

Creating file /var/www/html/cakephp/src/Controller/SamplesController.php
Wrote `/var/www/html/cakephp/src/Controller/SamplesController.php`
Bake is detecting possible fixtures...

Baking test case for App\Controller\SamplesController ...

Creating file /var/www/html/cakephp/tests/TestCase/Controller/SamplesControllerTest.php
Wrote `/var/www/html/cakephp/tests/TestCase/Controller/SamplesControllerTest.php`

cakephp/src/Controller 配下に SamplesController.php

cakephp
├─ src
│   ├─ Controller
│   │   ├─
SamplesController.php

せっかく生成されたコントローラクラスですが、今回必要なものだけを残してあとは削除してしまい、それ(以下)を初期ソースとしてスタートします。

cakephp/src/Controller/SamplesController.php
<?php
namespace App\Controller;

use App\Controller\AppController;

class SamplesController extends AppController
{
public function index()
{
}
}

レイアウト作成

それではレイアウトファイルを作成していきます。

cakephp/src/Template/Layout 配下に samples.ctp を作成します

cakephp
├─ src
│   ├─ Template
│   │   ├─ Layout
│   │   │   ├─ ajax.ctp
│   │   │   ├─ default.ctp
│   │   │   ├─ Email
│   │   │   ├─ error.ctp
│   │   │   ├─ rss
│   │   │   └─
samples.ctp

samples.ctp を以下のように記述します。

cakephp/src/Template/Layout/samples.ctp
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, maximum-scale=1.0, minimum-scale=0.5,user-scalable=yes,initial-scale=1.0" />
<title><?= h($title) ?></title>
<?php
echo $this->Html->css('reset.css');
echo $this->Html->css('common.css');
echo $this->Html->css('samples/index.css');
?>
</head>
<body>
<div class="header">
<p class="logo"><?= env('APP_NAME') ?></p>
</div>
<h1><?= h($title) ?></h1>

<?= $this->fetch('content') ?>

<div class="footer">
<small>&copy; 2018 <?= env('APP_NAME') ?></small>
</div>
</body>
</html>

レイアウトには共通化出来そうな以下の要素をコーディングしました。

  1. DOCTYPEからheadタグまでの、いわゆるメタ部分
  2. HTMLヘッダー
  3. ページタイトル(h1)
  4. HTMLフッタ

そして、その間に記述されている

<?= $this->fetch('content') ?>

この部分が、コンテンツを表示する部分になります。

その他、各記述について少し解説します。

<?= h($title) ?>

コントローラから渡されるタイトル変数を表示します。

  <?php
echo $this->Html->css('reset.css');
echo $this->Html->css('common.css');
echo $this->Html->css('samples/index.css');
?>

CSSファイルを読み込んでいます。階層が異なっても、スラッシュ区切りで指定する事で読み込む事が出来ます。

ちなみに読み込むCSSを分けているのは、複数読み込む記述を行いたかっただけなので、そこは適宜最適化してください。

<?= env('APP_NAME') ?>

envファイルから値を読み込む場合には以下のようにします。ここでは、アプリケーションの名前を読み込んでいます。

ビュー(テンプレート)作成

レイアウトが出来たので、コンテンツ部分のビューを作成していきます。

cakephp/src/Template 配下に Samples ディレクトリを作成し、index.ctp を作成します。

cakephp
├─ src
│   ├─ Template
│   │   ├─
Samples
│   │   │   └─
index.ctp

index.ctp を以下のようにコーディングします。

cakephp/src/Template/samples/index.ctp
<ul class="php_list">
<?php foreach ($list as $li): ?>
<li><?= $li ?></li>
<?php endforeach; ?>
</ul>

極めてシンプルですが、レイアウトを作成したので、ここでコーディングするのは本当にコンテンツ部分のみで良くなります。これが、レイアウトを導入するメリットの1つです。

CSS作成

軽く見た目を整えるために、簡単にCSSを作成していきます。

リセットCSS

若干本編からは趣旨がずれますが、気持ち悪いのでリセットCSSを適用します。

cakephp/webroot/css/reset.css
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}

Eric Meyer's "Reset CSS" 2.0のスタイルを採用させていただきました。

レイアウト用CSS

レイアウトのsamples.ctpに係るスタイルを記述します。

cakephp/webroot/css/common.css
.header, .footer {
padding: 20px;
width: 100%;
background-color: #2a88bd;
}
.logo {
font-size: 20px;
color: #FFFFFF;
}
.footer {
text-align: center;
}
.footer small {
font-size: 14px;
color: #FFFFFF;
}
h1 {
margin: 20px;
font-size: 20px;
}

コンテンツページ用CSS

今回のコンテンツページに係るスタイルを記述します。

cakephp/webroot/css/samples/index.css
.php_list {
margin: 30px;
}
.php_list li {
margin-bottom: 10px;
}

コントローラ実装

それでは最後に、作成したレイアウトなどをコントローラに適用していきます。

cakephp/src/Controller/SamplesController.php
<?php
namespace App\Controller;

use App\Controller\AppController;

class SamplesController extends AppController
{
public function initialize()
{
// レイアウトの設定
$this->viewBuilder()->setLayout('samples');
}

public function index()
{
// ビューに渡す変数
$title = 'PHPフレームワークのリスト';
$list = [
"Laravel",
"CakePHP",
"Symfony",
"Zend Framework",
"CodeIgniter",
"Phalcon",
"Slim",
"Yii",
"FuelPHP",
"Silex",
"Flight",
"BEAR.Sunday",
"Kohana",
"Ethna",
"Ice Framework"
];

// 変数をセットしビューに渡す
$this->set(compact('title', 'list'));
}
}

initialize()(コンストラクタ)で、レイアウトの指定を行っています。先ほど作成した、samples.ctpを指定しています。

cakephp/src/Template/Layout 配下にレイアウトファイルを設置する事で、拡張子を除いたファイル名を記述すれば指定できるようになっています。

もちろん、Layoutディレクトリ配下に新たにディレクトリを作ってそこへ設置した場合でも「XXXX/samples」のように記述すれば指定可能です。

変数は2つ設定しました。ビューに渡すタイトルと、コンテンツに渡す配列です。それらを、compact()メソッドにてビューへset()しています。

動作確認

それではブラウザからアクセスして表示を確認してみます。
http://YOUR-DOMAIN/samples

レイアウトを使ったビュー画面

ブラウザ右クリックから「ページのソースを表示」で、ソースコードも参照してみます

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, maximum-scale=1.0, minimum-scale=0.5,user-scalable=yes,initial-scale=1.0" />
<title>PHPフレームワークのリスト</title>
<link rel="stylesheet" href="/css/reset.css"/>
<link rel="stylesheet" href="/css/common.css"/>
<link rel="stylesheet" href="/css/samples/index.css"/>
</head>
<body>
<div class="header">
<p class="logo">test_app</p>
</div>
<h1>PHPフレームワークのリスト</h1>

<ul class="php_list">
<li>Laravel</li>
<li>CakePHP</li>
<li>Symfony</li>
<li>Zend Framework</li>
<li>CodeIgniter</li>
<li>Phalcon</li>
<li>Slim</li>
<li>Yii</li>
<li>FuelPHP</li>
<li>Silex</li>
<li>Flight</li>
<li>BEAR.Sunday</li>
<li>Kohana</li>
<li>Ethna</li>
<li>Ice Framework</li>
</ul>
<div class="footer">
<small>&copy; 2018 test_app</small>
</div>
</body>
</html>

レイアウトとコンテンツのビューテンプレートが合算され、一連のHTMLが問題なく表示されました。

まとめ

以上で作業は完了です。今回はデモンストレーションという事でコンテンツファイルは1つのみの作成でしたが、実際に開発を行うWEBアプリケーションはいくつもページがあるでしょう。そんな時にこうしてレイアウトで共通部分を定義しておけば、コンテンツのビューはそれだけをコーディングすれば良く、非常に効率的です。

また、共通部分に変更の必要が出た場合にも、レイアウトファイル1つだけを変更すれば良いので、更新漏れも防げますし、何より楽です。

このレイアウトという概念はCakePHPならずとも、ほとんどのPHPフレームワークには導入されていますので、結構必須の機能です。覚えておけばどのPHPフレームワークを使ってもスムーズに導入できると思うので是非試してみてください。