ビューの継承とブロック

ビューの継承

共通部分はレイアウトに書くことでビューを細分化できましたが、ビューを親子関係にすることでさらに細分化できます。

app/View/Layouts/default.ctp
app/View/Common/common.ctp
app/View/Sample/foo.ctp app/View/Sample/bar.ctp

という3つのファイルでビューを構成します。一番の親であるレイアウトは以下のようにします。

app/View/Layouts/default.ctp

<!DOCTYPE html>
<html>
<head>
    <title><?php echo $this->fetch('pageTitle') ?></title>
</head>
<body>
    <header>
        <p>Global Header</p>
    </header>
    <?php echo $this->fetch('content') ?>
</body>
</html>

app/View/Common/common.ctpには、レイアウトの中の<?php echo $this->fetch('content') ?>部分を記述します。

app/View/Common/common.ctp

<div class="main">
    <?php echo $this->fetch('content') ?>
</div>
<div class="sub">
     <?php echo $this->fetch('subContent') ?>
</div>

ここでsubContentをfetchするようにしました。このsubContentをブロックといいます。subContentブロックは、app/View/Sample/foo.ctpとapp/View/Sample/bar.ctpで定義します。
この2つのファイルでは、app/View/Common/common.ctpの<?php echo $this->fetch('content') ?>部分を記述します。

app/View/Sample/foo.ctp

<?php
$this->extend('Common/common');
$this->assign('pageTitle', 'foo title');
?>

<?php $this->start('subContent'); ?>
<p>foo subContent</p>
<?php $this->end(); ?>

<p> foo mainContent</p>

extend('Common/common')で継承するビューを指定します。
start('subContent')でブロックを開始し、end()で終了します。
どのブロックにも属さない部分は、自動でcontentブロックになります。

同じようにもうひとつのビューファイルも作ってみます。

app/View/Sample/bar.ctp

<?php
$this->extend('Common/common');
$this->assign('pageTitle', 'bar title');
?>

<?php $this->start('subContent'); ?>
<p>bar subContent</p>
<?php $this->end(); ?>

<p> bar mainContent</p>

ブラウザでアクセスできるように、Sampleコントローラにfooアクション、barアクションを実装してみます。結果は以下になります。

f:id:myhateno:20180529122645p:plain

/sample/barにアクセスすると、ページ内容がbarのものに変わっています。