ビュー

ビューとは?

ビューは、ブラウザにデータを提供するファイルです。アプリケーションのロジックとプレゼンテーションを分離することができます。ビューは典型的には html、javascript あるいは css ですが、コントローラからから渡される変数を含むことがあります。

ビューを作成する

FuelPHP では、 ビューは fuel/app/views ディレクトリに置きます。サブディレクトリに置くこともできます。fuel/app/views からのディレクトリパスとファイル名から命名します。従って、fuel/app/views/user/join.php にあるビューファイルは user/join と命名されます。

例:

<html>
	<head>
		<title><?php echo $title; ?></title>
	</head>
	<body>
		Welcome, <?php echo $username; ?>.
	</body>
</html>

ビューを使用する

FuelPHP フレームワークのビューは柔軟です。単一ビューを作成し、ビューを他のビューの中に入れ子にすることができます。複数の方法で可能です。

ビューの例 (fuel/app/views/home/index.php):

<html>
	<head>
		<title><?php echo $title; ?></title>
	</head>
	<body>
		Welcome, <?php echo $username; ?>.
	</body>
</html>

方法 1 (上記ビューを使用):

class Controller_Home extends Controller
{
	public function action_index()
	{
		$data = array(); //stores variables going to views

		$data['username'] = 'Joe14';
		$data['title'] = 'Home';

		//assign the view to browser output
		return View::forge('home/index', $data);
	}
}

方法 2 (上記ビューを使用):

class Controller_Home extends Controller
{
	public function action_index()
	{
		//create the view
		$view = View::forge('home/index');

		//assign variables for the view
		$view->username = 'Joe14';
		$view->title = 'Home';

		//another way to assign variables for the view
		$view->set('username', 'Joe14');
		$view->set('title', 'Home');

		//assign the view to browser output
		return $view;
	}
}

セキュリティ

ビューに渡される変数は全てサニタイズされて出力されます。デフォルトの状態では、セキュリティ関数である Security::htmlentities() が出力フィルタとして定義されています。フィルタはアプリケーションの config.php ファイルにて修正できます。 もしフィルタリングせずに変数を渡したい場合、set($name, $value, false) メソッドを使います。

class Controller_Example extends Controller
{
	public function action_index()
	{
		$view = \View::forge('example');

		// フィルタして追加する、出力: &lt;strong&gt;not bold because filtered&lt;/strong&gt;
		$view->title = '<strong>not bold because filtered</strong>';

		// フィルタせず追加する、出力: <strong> bold because unfiltered</strong>
		$view->set('title', '<strong> bold because unfiltered</strong>', false);

		// または、set_safe() メソッドを使う。これは set() メソッドと同じだが、'false' が初期値
		$view->set_safe('title', '<strong> bold because unfiltered</strong>');

		return $view;
	}
}

もしこのように View を出力させたくない場合、falseView::forge() の第三引数として渡すことで、 その View オブジェクトに追加されるものがフィルタリングされないようにできます。 その後、フィルタリングさせたい変数があれば、set($name, $value, true) を使います。
また、アプリケーションの設定値である security.auto_filter_outputfalse にすることで、 出力フィルタをグローバルに無効化することができます。しかし、セキュリティ上の理由から、この設定を行わないしないことを 強く推奨します。

オブジェクトについての注意: 渡されるオブジェクトが View、ViewModel あるいは Closure のインスタンスでない限り、 オブジェクトは __toString() メソッドを持つことが期待され、出力フィルタリングが有効なとき文字列に強制変換されます。どうしても渡したい場合は、 set($name, $value, false) を使用する必要がありますが、 フィルタすることを決して忘れないで ください。
View と ViewModels は HTML を含み、サニタイズされないものを独自にフィルタリングすることが期待されます。 Closures はサニタイズできませんので、必要ならば内部でサニタイズが確実に行われるように 注意すべきです。

遅延レンダリング

ビューオブジェクトを初期化するとき、出力を生成するのに必要な環境のみがセットアップされます。ビューファイルは読み込まれず、 変数は解釈されず、出力はレンダリングされません。

これは render() メソッドを明示的に呼び出す場合、あるいは ビューオブジェクトを文字列にキャストする(echo すると自動的にそうなります)ときのみ起きます。つまり、ビューは完全に必要になるまで処理されません。 FuelPHP はブラウザに出力する時が来るまで、レンダリングしたビューをメモリに保存しない、 ということでもあります。

ビューを入れ子にする

ビューは入れ子にすることができます。複数の方法が可能です。

ビューの例

fuel/app/views/layout.php

<html>
	<head>
		<?php echo $head; ?>
	</head>
	<body>
		<?php echo $header; ?>
		<?php echo $content; ?>
		<?php echo $footer; ?>
	</body>
</html>

fuel/app/views/head.php

<title><?php echo $title; ?></title>

fuel/app/views/header.php

<div class="logo"></div>
<div class="logo_text"><?php echo $site_title; ?></div>

fuel/app/views/content.php

<h1><?php echo $title; ?></h1>
<div class="welcome_user">Welcome <?php echo $username; ?></div>

fuel/app/views/footer.php

<div class="footer">
	&copy; Copyright <?php echo date('Y');?> <?php echo $site_title; ?>
</div>

方法 1 (上記の例と遅延レンダリングを使用):

class Controller_Home extends Controller
{
	public function action_index()
	{
		// レイアウトビューを作成する
		$view = View::forge('layout');

		// グローバル変数(すべてのビューがアクセスできる)を割り当てる
		$view->set_global('username', 'Joe14');
		$view->set_global('title', 'Home');
		$view->set_global('site_title', 'My Website');

		//変数としてビューを割り当てる、遅延レンダリング
		$view->head = View::forge('head');
		$view->header = View::forge('header');
		$view->content = View::forge('content');
		$view->footer = View::forge('footer');

		// ビューオブジェクトをリクエストに返す
		return $view;
	}
}

方法 2 (上記の例と強制レンダリングを使用):

class Controller_Home extends Controller
{
	public function action_index()
	{
		//変数を割り当てる
		$data = array();
		$data['title'] = 'Home';
		$data['site_title'] = 'My Website';
		$data['username'] = 'Joe14';

		//変数としてビューを割り当てる、強制レンダリング
		$views = array();
		$views['head'] = View::forge('head', $data)->render();
		$views['header'] = View::forge('header', $data)->render();
		$views['content'] = View::forge('content', $data)->render();
		$views['footer'] = View::forge('footer', $data)->render();

		// レンダリングした HTML をリクエストに返す
		return View::forge('layout', $views)->render();
	}
}

Method 3 (using example views above, no global data, lazy rendering):

class Controller_Home extends Controller
{
	public function action_index()
	{
		// レイアウトビューを生成
		$view = View::forge('layout');

		// ローカルなビュー内の変数(遅延ロード)
		$view->head = View::forge('head', array('title' => 'Home'));
		$view->header = View::forge('header', array('site_title' => 'My Website'));
		$view->content = View::forge('content', array('username' => 'Joe14', 'title' => 'Home'));
		$view->footer = View::forge('footer', array('site_title' => 'My Website'));

		// リクエストに対し view オブジェクトを返す
		return $view;
	}
}

View の関数についての説明は、「クラス」の項の View クラスを参照して下さい。