1 <?xml version="1.0" encoding="UTF-8"?>
3 <!-- EN-Revision: 20799 -->
4 <sect1 id="zend.view.scripts">
6 <title>ビュースクリプト</title>
9 コントローラが変数を代入して <methodname>render()</methodname> をコールすると、
10 指定されたビュースクリプトを <classname>Zend_View</classname> が読み込み、<classname>Zend_View</classname>
11 インスタンスのスコープでそれを実行します。したがって、
12 ビュースクリプトの中で $this を参照すると、
13 実際には <classname>Zend_View</classname> のインスタンスを指すことになります。
18 ビューインスタンスのプロパティとして参照できます。例えば、
19 コントローラで変数 'something' を代入したとすると、
20 ビュースクリプト内ではそれを $this->something で取得できます
21 (これにより、どの値がコントローラから代入されたもので、
22 どの値がスクリプト内部で作成されたものなのかを追いかけられるようになります)。
26 <classname>Zend_View</classname> の導入の部分で示したビュースクリプトの例を思い出してみましょう。
29 <programlisting language="php"><![CDATA[
30 <?php if ($this->books): ?>
39 <?php foreach ($this->books as $key => $val): ?>
41 <td><?php echo $this->escape($val['author']) ?></td>
42 <td><?php echo $this->escape($val['title']) ?></td>
55 <sect2 id="zend.view.scripts.escaping">
57 <title>出力のエスケープ</title>
60 ビュースクリプトで行うべき仕事のうち最も重要なもののひとつは、
61 出力を適切にエスケープすることです。これは、
62 クロスサイトスクリプティング攻撃を防ぐのを助けます。
63 それ自身がエスケープを行ってくれるような関数、メソッド、
64 あるいはヘルパーを使用しているのでない限り、
65 変数を出力する際には常にそれをエスケープしなければなりません。
69 <classname>Zend_View</classname> の escape() というメソッドが、このエスケープを行います。
72 <programlisting language="php"><![CDATA[
77 echo $this->escape($this->variable);
81 デフォルトでは、escape() メソッドは <acronym>PHP</acronym> の htmlspecialchars()
82 関数でエスケープを行います。しかし環境によっては、
83 別の方法でエスケープしたくなることもあるでしょう。
84 コントローラから setEscape() メソッドを実行することで、
85 エスケープに使用するコールバックを <classname>Zend_View</classname> に通知できます。
88 <programlisting language="php"><![CDATA[
89 // Zend_View のインスタンスを作成します
90 $view = new Zend_View();
92 // エスケープに htmlentities を使用するように通知します
93 $view->setEscape('htmlentities');
95 // あるいは、クラスの静的メソッドを使用するように通知します
96 $view->setEscape(array('SomeClass', 'methodName'));
98 // あるいは、インスタンスメソッドを指定することもできます
99 $obj = new SomeClass();
100 $view->setEscape(array($obj, 'methodName'));
103 echo $view->render(...);
108 エスケープする値を最初のパラメータとして受け取ります。
109 それ以外のパラメータはオプションとなります。
114 <sect2 id="zend.view.scripts.templates">
115 <title>別のテンプレートシステムの使用</title>
118 <acronym>PHP</acronym> 自身も強力なテンプレートシステムではありますが、
119 開発者の多くは、デザイナにとっては高機能すぎる/複雑すぎる
120 と感じており、別のテンプレートエンジンをほしがっているようです。
121 <classname>Zend_View</classname> では、そのような目的のために二種類の仕組みを提供します。
122 ビュースクリプトを使用することによるものと、
123 <classname>Zend_View_Interface</classname> 実装することによるものです。
126 <sect3 id="zend.view.scripts.templates.scripts">
127 <title>ビュースクリプトを使用したテンプレートシステム</title>
130 ビュースクリプトを使用して、PHPLIB 形式のテンプレートのような
131 別のテンプレートオブジェクトのインスタンスを作成し、
132 それを操作できます。ビュースクリプトをこのように使用する方法は、
136 <programlisting language="php"><![CDATA[
137 include_once 'template.inc';
138 $tpl = new Template();
142 "booklist" => "booklist.tpl",
143 "eachbook" => "eachbook.tpl",
146 foreach ($this->books as $key => $val) {
147 $tpl->set_var('author', $this->escape($val['author']);
148 $tpl->set_var('title', $this->escape($val['title']);
149 $tpl->parse("books", "eachbook", true);
152 $tpl->pparse("output", "booklist");
154 $tpl->setFile("nobooks", "nobooks.tpl")
155 $tpl->pparse("output", "nobooks");
160 関連するテンプレートファイルは、このようになります。
163 <programlisting language="html"><![CDATA[
164 <!-- booklist.tpl -->
173 <!-- eachbook.tpl -->
185 <sect3 id="zend.view.scripts.templates.interface">
186 <title>Zend_View_Interface を使用したテンプレート</title>
189 <classname>Zend_View</classname> 互換のテンプレートエンジンを使用するほうが簡単だという人もいるでしょう。
190 <classname>Zend_View_Interface</classname> では、
191 互換性を保つために最低限必要なインターフェイスを定義しています。
194 <programlisting language="php"><![CDATA[
196 * テンプレートエンジンオブジェクトを返します
198 public function getEngine();
201 * ビュースクリプト/テンプレートへのパスを設定します
203 public function setScriptPath($path);
206 * すべてのビューリソースへのベースパスを設定します
208 public function setBasePath($path, $prefix = 'Zend_View');
211 * ビューリソースへのベースパスを追加します
213 public function addBasePath($path, $prefix = 'Zend_View');
218 public function getScriptPaths();
221 * テンプレート変数をオブジェクトのプロパティとして代入するためのオーバーロードメソッド
223 public function __set($key, $value);
224 public function __isset($key);
225 public function __unset($key);
228 * テンプレート変数を手動で代入したり、複数の変数を
231 public function assign($spec, $value = null);
234 * 代入済みのテンプレート変数を削除します
236 public function clearVars();
239 * $name というテンプレートをレンダリングします
241 public function render($name);
246 サードパーティのテンプレートエンジンをラップして
247 <classname>Zend_View</classname> 互換のクラスを作成することが簡単になります。
248 例として、Smarty 用のラッパーはこのようになります。
251 <programlisting language="php"><![CDATA[
252 class Zend_View_Smarty implements Zend_View_Interface
263 * @param string $tmplPath
264 * @param array $extraParams
267 public function __construct($tmplPath = null, $extraParams = array())
269 $this->_smarty = new Smarty;
271 if (null !== $tmplPath) {
272 $this->setScriptPath($tmplPath);
275 foreach ($extraParams as $key => $value) {
276 $this->_smarty->$key = $value;
281 * テンプレートエンジンオブジェクトを返します
285 public function getEngine()
287 return $this->_smarty;
293 * @param string $path パスとして設定するディレクトリ
296 public function setScriptPath($path)
298 if (is_readable($path)) {
299 $this->_smarty->template_dir = $path;
303 throw new Exception('無効なパスが指定されました');
307 * 現在のテンプレートディレクトリを取得します
311 public function getScriptPaths()
313 return array($this->_smarty->template_dir);
317 * setScriptPath へのエイリアス
319 * @param string $path
320 * @param string $prefix Unused
323 public function setBasePath($path, $prefix = 'Zend_View')
325 return $this->setScriptPath($path);
329 * setScriptPath へのエイリアス
331 * @param string $path
332 * @param string $prefix Unused
335 public function addBasePath($path, $prefix = 'Zend_View')
337 return $this->setScriptPath($path);
343 * @param string $key 変数名
344 * @param mixed $val 変数の値
347 public function __set($key, $val)
349 $this->_smarty->assign($key, $val);
353 * empty() や isset() のテストが動作するようにします
358 public function __isset($key)
360 return (null !== $this->_smarty->get_template_vars($key));
364 * オブジェクトのプロパティに対して unset() が動作するようにします
369 public function __unset($key)
371 $this->_smarty->clear_assign($key);
377 * 指定したキーを指定した値に設定します。あるいは、
378 * キー => 値 形式の配列で一括設定します
381 * @param string|array $spec 使用する代入方式 (キー、あるいは キー => 値 の配列)
382 * @param mixed $value (オプション) 名前を指定して代入する場合は、ここで値を指定します
385 public function assign($spec, $value = null)
387 if (is_array($spec)) {
388 $this->_smarty->assign($spec);
392 $this->_smarty->assign($spec, $value);
398 * Zend_View に {@link assign()} やプロパティ
399 * ({@link __get()}/{@link __set()}) で代入された変数をすべて削除します
403 public function clearVars()
405 $this->_smarty->clear_all_assign();
409 * テンプレートを処理し、結果を出力します
411 * @param string $name 処理するテンプレート
412 * @return string 出力結果
414 public function render($name)
416 return $this->_smarty->fetch($name);
422 この例では、<classname>Zend_View</classname> ではなく
423 <classname>Zend_View_Smarty</classname> クラスのインスタンスを作成し、
424 それを使用して <classname>Zend_View</classname> と同じようなことをしています。
427 <programlisting language="php"><![CDATA[
428 //例 1. InitializerのinitView()で
429 $view = new Zend_View_Smarty('/path/to/templates');
431 Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
432 $viewRenderer->setView($view)
433 ->setViewBasePathSpec($view->_smarty->template_dir)
434 ->setViewScriptPathSpec(':controller/:action.:suffix')
435 ->setViewScriptPathNoControllerSpec(':action.:suffix')
436 ->setViewSuffix('tpl');
438 //例 2. アクションコントローラでも同様に...
439 class FooController extends Zend_Controller_Action
441 public function barAction()
443 $this->view->book = 'Zend PHP 5 Certification Study Guide';
444 $this->view->author = 'Davey Shafik and Ben Ramsey'
448 //例 3. アクションコントローラでのビューの初期化
449 class FooController extends Zend_Controller_Action
451 public function init()
453 $this->view = new Zend_View_Smarty('/path/to/templates');
454 $viewRenderer = $this->_helper->getHelper('viewRenderer');
455 $viewRenderer->setView($this->view)
456 ->setViewBasePathSpec($view->_smarty->template_dir)
457 ->setViewScriptPathSpec(':controller/:action.:suffix')
458 ->setViewScriptPathNoControllerSpec(':action.:suffix')
459 ->setViewSuffix('tpl');