COLUMN

cakephp elementの使い方について

今更感がありますが、cakephpのelementについて書いてみようと思います。
基本的な使い方と弊社のコードでも使用している実践的な活用方法を紹介します。

cakephp-560-420.png


elementはview内の共通部分などをパーツ化して簡単に使い回せるようにできる機能です。
解りやすい例をだすと、header, footer, sidemenu などですね。

1. 基本的な使い方

まずelementファイルの作り方ですが、 views/elements/ 以下に拡張子 ctp で作成し、中身については基本的にviewファイルと同じです。

下記のように呼び出せます。

echo $this->element( 'element名' );

elements/ 以下にディレクトリを作成して階層化することも可能です。
その場合は呼び出し方は elements/ 以下の elementファイル名までのパスを指定すればokです。

例えば、 views/elements/pages/header.ctp にelementファイルを作成した場合は
echo $this->element( 'pages/header' );

として呼び出せます。

element内から参照できる変数ですが、普通のviewと同じようにcontroller->set でセットした変数と、 それとは別に呼び出し時の第2引数に配列で、 変数名 => 値 の形で設定できます。
またview内と同じく $this->params も参照できます。
controllerで設定した変数と同名の変数を呼び出し時に設定した場合は呼び出し時のものが優先されます。

呼び出し時の変数の設定例

echo $this->element( 'pages/header', array( 'title' => 'RealiDブログ' ) );

2. 実際の使用例

一般的な業務システムなどを想定した場合に header, footer などの他にも記述の重複を避けて element化したほうが良い箇所が多く出てくると思います。
そういった場合の解決策の1つになるのではないかというパターンを紹介させていただきます。

単純な記事を投稿できるシステムを想定します。
必要な機能は
・記事登録ページ
・記事登録内容確認ページ
・記事一覧ページ
・記事内容閲覧ページ
・記事内容編集ページ
とします。

上記の機能のviews部分で重複してしまいそうな部分を考えてみましょう。
・記事登録ページの入力フォームと記事編集ページの入力フォーム
・記事登録内容確認ページと記事内容閲覧ページの表示箇所
とりあえず上記2点は重複してしまいそうですね。

こういった場合に毎回どうelement化するか悩むのはめんどうなので、下記のようにパターン下してしまっています。
例えば記事のモデル名を Article とした場合は下記のような構造で elememtファイルを作成します。
elements/articles/ 以下
input_table.ctp //入力フォームテーブル
show_table.ctp //閲覧用テーブル
list_table.ctp //一覧表示用テーブル
footer.ctp //フッター

list_table は複数タイプの一覧表示が必要な場合結構便利に使えます。
footer は閲覧、編集画面でのフッターを想定していて、閲覧、編集、削除等の制御エリアです。 もっとふさわしい名前がありそうですね。

入力フォームテーブルの実装例です。
elements/articles/input_table.ctp

<?php if(!empty($this->validationErrors)): ?>
<div id='flashMessage' class='flash-error'>入力に誤りのある項目があります</div>
<?php endif; ?>
<table>
<tr>
<th class='span3'>タイトル</th>
<td><?php echo $form->input('title') ?></td>
</tr>
<tr>
<th>本文</th>
<td><?php echo $form->input('content') ?><</td>
</tr>
</table>

登録ページ (views/articles/register.ctp)
<?php echo $form->create('Article',array('url' => 'register') ?>
<?php echo $this->element('articles/input_table') ?>
<input type='submit' value='入力内容の確認'  />
</form>

編集ページ (views/articles/edit.ctp)
<?php echo $form->create('Article',array('url' => 'edit') ?>
<?php echo $this->element('articles/input_table') ?>
<input type='submit' value='変更'  />
</form>

上記のように入力フォームテーブルをelement化することで重複を避けることができました。
例えば入力項目に変更があった場合でも、input_table, show_table を変更すれば最低限機能するので、急な変更に強い設計になっているのではないかなと思います。

まとめ

element機能自体とてもシンプルなので、いろいろな使い方のパターンが考えられると思います。
紹介したパターン以外に実用的なパターンや改善点などありましたらご指摘いただけると助かります。