I'm attending CakeFest 2010!

10.1.8 Postビューの作成

現在、モデルにはデータが入り、コントローラにはアプリケーションロジックと流れが定義されています。今度は、作成したindexアクション用のビューを作成しましょう。

Cakeのビュー(view)は、アプリケーションのレイアウト(layout)の内側にはめこまれる、データ表示用の断片部品です。たいていのアプリケーションでは、PHPのコードが含まれるHTMLになりますが、XML、CSV、バイナリのデータにもなりえます。

レイアウト(Layout)は、ビューを囲む表示用のコードで、独自に定義したり、切り替えたりすることも可能ですが、今のところは、デフォルト(default)のものを使用することにしましょう。

一つ前のセクションのset()メソッドによって、ビューから'posts'変数が使えるように割り当てたのを覚えていますか。ビューに渡されたデータは次のようなものになっています。

// print_r($posts) の出力:

Array
(
	[0] => Array
		(
			[Post] => Array
				(
					[id] => 1
					[title] => タイトル
					[body] => これは、記事の本文です。
					[created] => 2008-02-13 18:34:55
					[modified] =>
				)
		)
	[1] => Array
		(
			[Post] => Array
				(
					[id] => 2
					[title] => またタイトル
					[body] => そこに本文が続きます。
					[created] => 2008-02-13 18:34:56
					[modified] =>
				)
		)
	[2] => Array
		(
			[Post] => Array
				(
					[id] => 3
					[title] => タイトルの逆襲
					[body] => こりゃ本当に面白そう!うそ。
					[created] => 2008-02-13 18:34:57
					[modified] =>
				)
		)
)
  1. // print_r($posts) の出力:
  2. Array
  3. (
  4. [0] => Array
  5. (
  6. [Post] => Array
  7. (
  8. [id] => 1
  9. [title] => タイトル
  10. [body] => これは、記事の本文です。
  11. [created] => 2008-02-13 18:34:55
  12. [modified] =>
  13. )
  14. )
  15. [1] => Array
  16. (
  17. [Post] => Array
  18. (
  19. [id] => 2
  20. [title] => またタイトル
  21. [body] => そこに本文が続きます。
  22. [created] => 2008-02-13 18:34:56
  23. [modified] =>
  24. )
  25. )
  26. [2] => Array
  27. (
  28. [Post] => Array
  29. (
  30. [id] => 3
  31. [title] => タイトルの逆襲
  32. [body] => こりゃ本当に面白そう!うそ。
  33. [created] => 2008-02-13 18:34:57
  34. [modified] =>
  35. )
  36. )
  37. )

Cakeのビューファイルは、/app/viewsの中の、コントローラ名に対応するフォルダの中に保存されています。(この場合は、'posts'というフォルダを作成します。)この投稿記事データをテーブル表示するには、ビューのコードは次のようなものにできます。

/app/views/posts/index.ctp

<h1>Blog posts</h1>
<table>
	<tr>
		<th>Id</th>
		<th>Title</th>
		<th>Created</th>
	</tr>

	<!-- ここから、$posts配列をループして、投稿記事の情報を表示 -->

	<?php foreach ($posts as $post): ?>
	<tr>
		<td><?php echo $post['Post']['id']; ?></td>
		<td>
			<?php echo $html->link($post['Post']['title'], 
"/posts/view/".$post['Post']['id']); ?>
		</td>
		<td><?php echo $post['Post']['created']; ?></td>
	</tr>
	<?php endforeach; ?>

</table>
  1. /app/views/posts/index.ctp
  2. <h1>Blog posts</h1>
  3. <table>
  4. <tr>
  5. <th>Id</th>
  6. <th>Title</th>
  7. <th>Created</th>
  8. </tr>
  9. <!-- ここから、$posts配列をループして、投稿記事の情報を表示 -->
  10. <?php foreach ($posts as $post): ?>
  11. <tr>
  12. <td><?php echo $post['Post']['id']; ?></td>
  13. <td>
  14. <?php echo $html->link($post['Post']['title'],
  15. "/posts/view/".$post['Post']['id']); ?>
  16. </td>
  17. <td><?php echo $post['Post']['created']; ?></td>
  18. </tr>
  19. <?php endforeach; ?>
  20.  
  21. </table>

シンプルですよね。

$htmlというオブジェクトを使っていることに気づいたかもしれません。これは、CakePHPのHtmlHelperクラスのインスタンスです。CakePHPには一連のビューヘルパーがあり、リンクの作成、フォームの出力、JavaScript、Ajaxなどをすぐに使えます。使い方の詳細については、"組み込みのヘルパー"の章を参照してください。ここで重要なのは、link()メソッドが、指定されたタイトル(最初のパラメータ)とURL(二つ目のパラメータ)でHTMLリンクを生成する、ということです。

Cake内でURLを指定する場合、単にアプリケーションの基本パスに対する相対パスを書くだけでかまいません。Cakeが残りの部分を処理します。なのでURLは通常、/コントローラ/アクション/パラメータ1/パラメータ2という形になります。

この時点で、ブラウザから http://www.example.com/posts/index を開いてみてください。タイトルと投稿内容のテーブル一覧がまとめられているビューが表示されるはずです。

ビューの中のリンク(投稿記事のタイトルから/posts/view/some_idというURLへのリンク)をクリックすると、CakePHPは、そのアクションはまだ定義されていません、という表示を出します。もしそういう表示が出ない場合には、何かおかしくなってしまったか、もうすでにあなたがその定義作業をしてしまったから(仕事がハヤイ!)か、のどちらかです。そうでないなら、これからPostControllerの中に作ってみましょう。

<?php
class PostsController extends AppController {

	var $name = 'Posts';

	function index() {
		 $this->set('posts', $this->Post->find('all'));
	}

	function view($id = null) {
		$this->Post->id = $id;
		$this->set('post', $this->Post->read());
	}
}
?>
  1. <?php
  2. class PostsController extends AppController {
  3. var $name = 'Posts';
  4. function index() {
  5. $this->set('posts', $this->Post->find('all'));
  6. }
  7. function view($id = null) {
  8. $this->Post->id = $id;
  9. $this->set('post', $this->Post->read());
  10. }
  11. }
  12. ?>

set()の呼び出しはもう知っていますね。find('all')の代わりに、read()を使っていることに注目してください。今回は、ひとつの投稿記事の情報しか必要としないからです。

ビューのアクションが、ひとつのパラメータを取っていることに注意してください。それは、これから表示する投稿記事のID番号です。このパラメータは、リクエストされたURLを通して渡されます。ユーザが、/posts/view/3とリクエストすると、'3'という値が$idとして渡されます。

では、新しい'view'アクション用のビューを作って、/app/views/posts/view.ctpというファイルで保存しましょう。

/app/views/posts/view.ctp

<h1><?php echo $post['Post']['title']?></h1>

<p><small>Created: <?php echo $post['Post']['created']?></small></p>

<p><?php echo $post['Post']['body']?></p>
  1. /app/views/posts/view.ctp
  2. <h1><?php echo $post['Post']['title']?></h1>
  3. <p><small>Created: <?php echo $post['Post']['created']?></small></p>
  4. <p><?php echo $post['Post']['body']?></p>

/posts/indexの中にあるリンクをクリックしたり、手動で、/posts/view/1にアクセスしたりして、動作することを確認してください。