视图助手(View Helper)在你的视图脚本中,经常需要执行某些特定的复杂的功能:例如,格式化日期,生成表单对象,或者显示action的链接等等。你可以使用助手类来完成这些工作。
助手就是简单的类。假设你想要一个名为'fooBar'的助手,缺省地,类的前缀是
在视图脚本中,你可以用 基本的助手
以上helper的使用非常简单,下面是个例子。注意你只需要调用即可,它们会根据需要自己加载并实例化。 <?php
// 在你的view脚本内部, $this 指向 Zend_View 实例.
//
// 假设你已经为select对应的变量$countries指定一系列option值,
// array('us' => 'United States', 'il' =>
// 'Israel', 'de' => 'Germany').
?>
<form action="action.php" method="post">
<p><label>Your Email:
<?php echo $this->formText('email', 'you@example.com', array('size' => 32)) ?>
</label></p>
<p><label>Your Country:
<?php echo $this->formSelect('country', 'us', null, $this->countries) ?>
</label></p>
<p><label>Would you like to opt in?
<?php echo $this->formCheckbox('opt_in', 'yes', null, array('yes', 'no')) ?>
</label></p>
</form>
以上视图脚本会输出这样的结果: <form action="action.php" method="post">
<p><label>Your Email:
<input type="text" name="email" value="you@example.com" size="32" />
</label></p>
<p><label>Your Country:
<select name="country">
<option value="us" selected="selected">United States</option>
<option value="il">Israel</option>
<option value="de">Germany</option>
</select>
</label></p>
<p><label>Would you like to opt in?
<input type="hidden" name="opt_in" value="no" />
<input type="checkbox" name="opt_in" value="yes" checked="checked" />
</label></p>
</form>
动作视图助手
内部调用
Example #1 动作视图助手的基本用法
例如,假设你有一个
<div id="sidebar right">
<div class="item">
<?= $this->action('list', 'comment', null, array('count' => 10)); ?>
</div>
</div>
区域助手(Partial Helper)
Example #2 Partials 的基本用法 partials 的基本用法是在它自己的视图范围内解析一个模板的片段。
<?php // partial.phtml ?>
<ul>
<li>From: <?= $this->escape($this->from) ?></li>
<li>Subject: <?= $this->escape($this->subject) ?></li>
</ul>
你可以这样从视图脚本里调用它:
<?= $this->partial('partial.phtml', array(
'from' => 'Team Framework',
'subject' => 'view partials')); ?>
解析结果如下:
<ul>
<li>From: Team Framework</li>
<li>Subject: view partials</li>
</ul>
Example #3 使用 PartialLoop 来解析可迭代的(Iterable)的模型 可能你常常会需要在一个循环里使用 partials 来输出相同的内容片段多次,这时你就可以把大块的重复的内容或复杂的显示逻辑放到一个地方。然而这对性能有影响,因为partial助手需要在每个迭代里调用一次。
让我们看一下下面的 partial 视图脚本:
<? // partialLoop.phtml ?>
<dt><?= $this->key ?></dt>
<dd><?= $this->value ?></dd>
添加下列 "model": <?php
$model = array(
array('key' => 'Mammal', 'value' => 'Camel'),
array('key' => 'Bird', 'value' => 'Penguin'),
array('key' => 'Reptile', 'value' => 'Asp'),
array('key' => 'Fish', 'value' => 'Flounder'),
);
?>
在视图脚本中,你可以这样调用
<dl>
<?= $this->partialLoop('partialLoop.phtml', $model) ?>
</dl>
<dl></dl>
<dt>Mammal</dt>
<dd>Camel</dd>
<dt>Bird</dt>
<dd>Penguin</dd>
<dt>Reptile</dt>
<dd>Asp</dd>
<dt>Fish</dt>
<dd>Flounder</dd>
</dl>
Example #4 在其它模块中解析 Partials
有时候 partial 存在于不同的模块(Module)。如果你知道模块的名称,你可以把它当作第二个参数传递给 例如,如果一个你想用一个在 'list' 模块的 pager partial,就象下面这样来运用:
<?= $this->partial('pager.phtml', 'list', $pagerData) ?>
这样,你可以重用原来是特别供给其它模块使用的 partials 。所以,在共享的视图脚本路径里放置可重用的 partials 很可能是个好习惯。 占位符助手(Placeholder Helper)
Example #5 占位符的基本用法
占位符的基本用法是将视图中的数据持久化。每个
<?php $this->placeholder('foo')->set("Some text for later") ?>
<?php
echo $this->placeholder('foo');
// outputs "Some text for later"
?>
Example #6 用占位符来聚合内容 通过占位符来聚合内容有时候很有用。例如视图脚本可拥有一个变量数组来存放数据,而视图脚本可以决定这些数据如何显示出来。
<!-- first view script -->
<?php $this->placeholder('foo')->exchangeArray($this->data) ?>
<!-- later view script -->
<?php
$this->placeholder('foo')->setPrefix("<ul>\n <li>")
->setSeparator("</li><li>\n")
->setIndent(4)
->setPostfix("</li></ul>\n");
?>
<?php
echo $this->placeholder('foo');
//输出一个带有漂亮缩进的HTML无序列表
?>
因为
<?php $this->placeholder('foo')->bar = $this->data ?>
<?php echo $this->placeholder('foo')->bar ?>
<?php
$foo = $this->placeholder('foo');
echo $foo['bar'];
?>
Example #7 使用占位符(Placeholders)来抓取内容
有时你可能会在视图脚本(最容易的模板)为占位符放些内容,
<!-- Default capture: append -->
<?php $this->placeholder('foo')->captureStart();
foreach ($this->data as $datum): ?>
<div class="foo">
<h2><?= $datum->title ?></h2>
<p><?= $datum->content ?></p>
</div>
<?php endforeach; ?>
<?php $this->placeholder('foo')->captureEnd() ?>
<?php echo $this->placeholder('foo') ?>
<!-- Capture to key -->
<?php $this->placeholder('foo')->captureStart('SET', 'data');
foreach ($this->data as $datum): ?>
<div class="foo">
<h2><?= $datum->title ?></h2>
<p><?= $datum->content ?></p>
</div>
<?php endforeach; ?>
<?php $this->placeholder('foo')->captureEnd() ?>
<?php echo $this->placeholder('foo')->data ?>
具体占位符实现Zend Framework 自带有若干个具体实现的占位符,包括常用的占位符:doctype、page title、以及各种 <head> 元素。对所有情况,不带参数调用占位符将返回元素自己。 每个元素的文档,请查看如下链接: 文档类型助手(Doctype Helper)
有效的HTML和XHTML文档应当包括一个
你也可以指定一个自己定制的带有良好结构的文档类型。
Example #8 Doctype 助手的基本用法 在任何时候都可以指定 doctype。然而,依赖 doctype 输出的助手只在你设置后才认识它,所以最简单的用法是在 bootstrap 脚本中指定:
$doctypeHelper = new Zend_View_Helper_Doctype();
$doctypeHelper->doctype('XHTML1_STRICT');
然后在布局脚本中输出: <?php echo $this->doctype() ?> Example #9 获取 Doctype
如果需要知道文档类型,可以在由调用助手返回的对象中调用 <?php $doctype = $view->doctype()->getDoctype(); ?>
很常见地,你需要知道doctype是否XHTML;那么, <?php
if ($view->doctype()->isXhtml()) {
// do something differently
}
?>HeadLink 助手
HTML的
另外,
Example #10 HeadLink 助手的基本用法
任何时候可以指定
<?php // 在视图脚本中设置链接:
$this->headLink()->appendStylesheet('/styles/basic.css')
->headLink(array('rel' => 'favicon', 'href' => '/img/favicon.ico'), 'PREPEND')
->prependStylesheet('/styles/moz.css', 'screen', true);
?>
<?php // 解析链接:?>
<?= $this->headLink() ?>
HeadMeta 助手
HTML
也可以用
Example #11 HeadMeta 助手基本用法 你可以在任何时候指定一个新的meta标签。例如指定客户端缓冲规则或SEO关键字。 例如,如果想指定SEO关键字,要创建带有名为'keywords'和内容(在页面上和关键字有关联的)的meta名称标签:
<?php // setting meta keywords
$this->headMeta()->appendName('keywords', 'framework php productivity');
?>
如果想设置一些客户端缓冲规则,最好设置带有想执行的规则的 http-equiv 标签:
<?php // 禁止客户端缓存
$this->headMeta()->appendHttpEquiv('expires', 'Wed, 26 Feb 1997 08:21:57 GMT')
->appendHttpEquiv('pragma', 'no-cache')
->appendHttpEquiv('Cache-Control', 'no-cache');
?>
meta标签的另一个流行用法是设置内容类型,字符集和语言:
<?php // setting content type and character set
$this->headMeta()->appendHttpEquiv('Content-Type', 'text/html; charset=UTF-8')
->appendHttpEquiv('Content-Language', 'en-US');
?>
最后一个例子,可以使用"meta refresh" 来让页面转向,一个简单的办法来显示过渡消息:
<?php // 设置以下meta可使页面3秒钟后转向一个新的url
$this->headMeta()->appendHttpEquiv('Refresh', '3;URL=http://www.some.org/some.html');
?>
在布局脚本(layout)中放置所有meta标签后,简单地echo助手,把所有内容输出: <?= $this->headMeta() ?> HeadScript 助手
HTML
对于所有
最后,你也可以用
The
Example #12 HeadScript 助手基本用法 在任何时候可以指定一个新的脚本。如上所述,可以链接到外部资源文件或脚本自己。
<?php // adding scripts
$this->headScript()->appendFile('/js/prototype.js')
->appendScript($onloadScript);
?>
在客户端脚本编程中,顺序常常很重要,因为依赖的缘故,需要确保按特定的顺序来加载库,使用 append、 prepend 和 offsetSet 指令来帮助完成任务:
<?php // 按顺序放置脚本文件
//设置偏移量来确保这个文件最后加载
$this->headScript()->offsetSetScript(100, '/js/myfuncs.js');
//使用scriptaculous效果文件,这时append动作使用索引101,接上行代码的索引
$this->headScript()->appendScript('/js/scriptaculous.js');
//但总是保证prototype文件首先加载
$this->headScript()->prependScript('/js/prototype.js');
?>
当准备好输出所有脚本到布局脚本,简单地 echo 这个助手: <?= $this->headScript() ?> Example #13 Capturing Scripts Using the HeadScript Helper
有时候,需要“编程式”地生成客户端脚本。你可以使用字符串串联、heredoc或类似的技术(字符串串联即$string1.$string2这种形式,heredoc即使用<<<操作符--Haohappy注),通常通过创建脚本和在PHP标签里做手脚会更容易些。
<?php $this->headScript()->captureStart() ?>
var action = '<?= $this->baseUrl ?>';
$('foo_form').action = action;
<?php $this->headScript()->captureEnd() ?>
下面是上例中的一些假设:
HeadStyle 助手
在 HTML
对于所有情况,
最后,你也可以用
Example #14 HeadStyle 助手的基本用法 在任何时候都可以指定一个新的样式标签: <?php // adding styles $this->headStyle()->appendStyle($styles); ?> 对 CSS 来说,顺序非常重要,因为层叠的顺序(the order of the cascade),你需要确保样式表中的声明按特定的顺序加载。使用append、 prepend 和 offsetSet 指令可帮助你达到目的: <?php // Putting styles in order // place at a particular offset: $this->headStyle()->offsetSetStyle(100, $customStyles); // place at end: $this->headStyle()->appendStyle($finalStyles); // place at beginning $this->headStyle()->prependStyle($firstStyles); ?> 当准备好在布局脚本里输出所有样式声明,简单地 echo 助手: <?= $this->headStyle() ?> Example #15 用 HeadStyle 助手抓取样式声明
有时候需要用程序生成 CSS 样式声明。当你可以使用字符串串联,heredoc等等, 通常通过创建脚本和在PHP标签里做手脚会更容易些。
<?php $this->headStyle()->captureStart() ?>
body {
background-color: <?= $this->bgColor ?>;
}
<?php $this->headStyle()->captureEnd() ?>
下面是一些假设:
HeadTitle 助手
HTML
Example #16 HeadTitle 助手基本用法 你可以在任何时候指定一个标题标签。一般的用法可以让你在应用程序的每一个层次来设置标题段:站点、控制器、动作和潜在的资源。 <?php
// setting the controller and action name as title segments:
//把控制器和动作的名称设置为标题的一部分
$request = Zend_Controller_Front::getInstance()->getRequest();
$this->headTitle($request->getActionName())
->headTitle($request->getControllerName());
// setting the site in the title; possibly in the layout script:
//添加标题内容,这种写法常用于布局脚本中
$this->headTitle('Zend Framework');
// setting a separator string for segments:
//为标题的各部分设置分隔符
$this->headTitle()->setSeparator(' / ');
?>
在布局脚本中准备好标题后,使用echo即可输出: <!-- renders <action> / <controller> / Zend Framework --> <?= $this->headTitle() ?> HTML 对象助手
HTML 有四个初始的对象助手:
所有这些助手使用相似的接口。这样,本文档只包含两个助手的例子。 Example #17 Flash 助手 使用助手嵌入 Flash 到你的页面相当简单。唯一需要的参数是资源 URI。 <?php echo $this->htmlFlash('/path/to/flash.swf'); ?>它输出下列 HTML:
<object data="/path/to/flash.swf" type="application/x-shockwave-flash"
classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
</object>
另外你可以指定可以和 Example #18 通过传递另外的参数来定制对象
对象助手里的第一个参数总是必需的,它是你想嵌入的资源的 URI。
第二个参数只对
echo $this->htmlObject(
'/path/to/file.ext',
'mime/type',
array(
'attr1' => 'aval1',
'attr2' => 'aval2'
),
array(
'param1' => 'pval1',
'param2' => 'pval2'
),
'some content'
);
/*
这将输出:
<object data="/path/to/file.ext" type="mime/type"
attr1="aval1" attr2="aval2">
<param name="param1" value="pval1" />
<param name="param2" value="pval2" />
some content
</object>
*/
InlineScript 助手
HTML
JSON 助手当创建返回 JSON 的视图,设置适当的响应头也非常重要,JSON 视图助手就是来做这个的。另外,缺省地,它关闭(disable)了布局(如果布局是打开(enable)的),因为布局一般不和 JSON 响应一起使用。 JSON 助手设置下列的头: Content-Type: application/json 当解析响应来决定如何处理内容,大部分 AJAX 库寻找这个头。 JSON 助手的用法相当简单: <?php <?= $this->json($this->data) ?> ?> 翻译助手
通常,网站支持多种语言。使用 Zend 翻译 来翻译网站的内容并且 使用
在下面所有的例子里我们使用简单的数组翻译适配器(Array Translation Adapter)。当然你也可以使用任何
Example #19 已注册的实例
为使用已注册的实例就是创建一个 <?php
// 我们的例子适配器
$adapter = new Zend_Translate('array', array('simple' => 'einfach'), 'de');
Zend_Registry::set('Zend_Translate', $adapter);
// 在视图中
echo $this->translate('simple');
// 返回 'einfach'
?>如果你熟悉 fluent interface ,那么也可以在视图里创建一个实例然后实例化这个助手。 Example #20 在视图里
为了使用 fluent interface ,创建一个 <?php
// 在视图里
$adapter = new Zend_Translate('array', array('simple' => 'einfach'), 'de');
$this->translate()->setTranslator($adapter)->translate('simple');
// 返回 'einfach'
?>
如果你使用没有 Example #21 直接用法 <?php
// 我们的例子适配器
$adapter = new Zend_Translate('array', array('simple' => 'einfach'), 'de');
// 实例化适配器
$translate = new Zend_View_Helper_Translate($adapter);
print $translate->translate('simple'); // this returns 'einfach'
?>
如果你不用
就象已经知道, Example #22 单个参数 使用单个参数就把它添加到这个方法。 <?php
// 在视图里
$date = "Monday";
$this->translate("Today is %1\$s", $date);
// 应当返回 'Heute ist Monday'
?>
Example #23 参数列表 使用参数列表并添加给方法。 <?php
// 在视图里
$date = "Monday";
$month = "April";
$time = "11:20:55";
$this->translate("Today is %1\$s in %2\$s. Actual time: %3\$s", $date, $month, $time);
// 应当返回 'Heute ist Monday in April. Aktuelle Zeit: 11:20:55'
?>Example #24 参数数组 使用参数数组并添加到方法。 <?php
// 在视图里
$date = array("Monday", "April", "11:20:55");
$this->translate("Today is %1\$s in %2\$s. Actual time: %3\$s", $date);
// 应当返回 'Heute ist Monday in April. Aktuelle Zeit: 11:20:55'
?>有时候必需要修改翻译的地点。可以通过动态翻译或者把所有的静态翻译来完成。并且你可以使用参数类表和参数数组。在这两种情况下,地点被当作最后一个单个参数给出。 Example #25 动态修改地点 (locale) <?php
// 在视图里
$date = array("Monday", "April", "11:20:55");
$this->translate("Today is %1\$s in %2\$s. Actual time: %3\$s", $date, 'it');
?>这个例子为 messageid 返回意大利语的翻译。但它将只能用一次。下个翻译将从适配器里设置地点。通常地在添加它到注册表之前你将在翻译适配器里设置期望的地点。但你也可以从助手里设置地点: Example #26 静态修改地点 (locale) <?php
// 在视图里
$date = array("Monday", "April", "11:20:55");
$this->translate()->setLocale('it');
$this->translate("Today is %1\$s in %2\$s. Actual time: %3\$s", $date);
?>
在上面的例子里设置
当然,还有 Example #27 获得当前设置的地点 <?php
// 在视图里
$date = array("Monday", "April", "11:20:55");
// 从上面的例子里返回 'de' 作为缺省地点
$this->translate()->getLocale();
$this->translate()->setLocale('it');
$this->translate("Today is %1\$s in %2\$s. Actual time: %3\$s", $date);
// 返回 'it' 为新的缺省地点
$this->translate()->getLocale();
?>助手的路径
就像可以指定视图脚本的路径,控制器也可以为 <?php
$view = new Zend_View();
// 设置路径为:/path/to/more/helpers, 通过使用前缀 'My_View_Helper'
$view->setHelperPath('/path/to/more/helpers', 'My_View_Helper');
你可以用 <?php
$view = new Zend_View();
// Add /path/to/some/helpers with class prefix 'My_View_Helper'
$view->addHelperPath('/path/to/some/helpers', 'My_View_Helper');
// Add /other/path/to/helpers with class prefix 'Your_View_Helper'
$view->addHelperPath('/other/path/to/helpers', 'Your_View_Helper');
// now when you call $this->helperName(), Zend_View will look first for
// "/path/to/some/helpers/HelperName" using class name "Your_View_Helper_HelperName",
// then for "/other/path/to/helpers/HelperName.php" using class name "My_View_Helper_HelperName",
// and finally for "Zend/View/Helper/HelperName.php" using class name "Zend_View_Helper_HelperName".
编写自定义的助手类编写自定义的助手类很容易,只要遵循以下几个原则即可:
把助手类的文件放在你的助手路径下,
下面是一个 <?php
class My_View_Helper_SpecialPurpose
{
protected $_count = 0;
public function specialPurpose()
{
$this->_count++;
$output = "I have seen 'The Jerk' {$this->_count} time(s).";
return htmlspecialchars($output);
}
}
在视图代码中,可以调用 <?php
// remember, in a view script, $this refers to the Zend_View instance.
echo $this->specialPurpose();
echo $this->specialPurpose();
echo $this->specialPurpose();
输出结果如下所示: I have seen 'The Jerk' 1 time(s).
I have seen 'The Jerk' 2 time(s).
I have seen 'The Jerk' 3 time(s).
有时候需要访问调用 <?php
class My_View_Helper_ScriptPath
{
public $view;
public function setView(Zend_View_Interface $view)
{
$this->view = $view;
}
public function scriptPath($script)
{
return $this->view->getScriptPath($script);
}
}
如果助手类有一个
|