Zend_View-Helpers.xml 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. <sect1 id="zend.view.helpers" xmlns:xi="http://www.w3.org/2001/XInclude">
  2. <title>视图助手(View Helper)</title>
  3. <para>
  4. 在你的视图脚本中,经常需要执行某些特定的复杂的功能:例如,格式化日期,生成表单对象,或者显示action的链接等等。你可以使用助手类来完成这些工作。
  5. </para>
  6. <para>
  7. 助手就是简单的类。假设你想要一个名为'fooBar'的助手,缺省地,类的前缀是<code>'Zend_View_Helper_'</code> (当设定助手路径时,你可以指定定制的前缀),类名的最后一部分就是助手名称;这一部分应该是TitleCapped(即像英文文章的标题一样,例如fooBar就要写成FooBar,by Jason Qi);所以,类的全名就是<code>Zend_View_Helper_FooBar</code> 。这个类应当至少有一个在助手之后命名的方法,并且是驼峰格式(即首字母小写,之后的每个单词首字母大写,例如thisIsAnExample。详见http://c2.com/cgi/wiki?CamelCase -- Haohappy注):<code>fooBar()</code> 。
  8. </para>
  9. <note>
  10. <title> 注意大小写 </title>
  11. <para>
  12. 助手名称总是遵循驼峰格式,例如,它们从不以大写字母开头。类名是混合大小写字格式,但方法在执行时是驼峰格式。
  13. </para>
  14. </note>
  15. <note>
  16. <title> 缺省助手路径 </title>
  17. <para>
  18. 即使调用 <code>setHelperPath()</code> 来重写当前的路径,缺省助手路径总是指向 Zend Framework 视图助手, 例如:'Zend/View/Helper/',设置这个路径来确保缺省的助手工作。
  19. </para>
  20. </note>
  21. <para>
  22. 在视图脚本中,你可以用<code>$this->helperName()</code>来调用helper。这时<code>Zend_View</code>会加载 <code>Zend_View_Helper_HelperName</code>类,建立一个对象实例,并调用它的<code>helperName()</code>方法。对象的实例会在 <code>Zend_View</code>的实例内一直存在,并可以被<code>$this->helperName()</code>重复调用。
  23. </para>
  24. <sect2 id="zend.view.helpers.initial">
  25. <title>基本的助手</title>
  26. <para>
  27. <code>Zend_View</code>自带了几个helper类,大部分是用来生成组件的和有自动转义变量的功能。另外,有些助手用来创建基于路由的URL和HTML列表以及声明变量。当前的助手包括:
  28. </para>
  29. <itemizedlist>
  30. <listitem><para>
  31. <code>declareVars():</code> 当使用 <code>strictVars()</code> 时很有用,这个助手可用来声明已经或还没有在View对象里设置的模板变量,并设置缺省值。当作参数传递改方法的数组将用来设置缺省值;否则,如果变量不存在,就设置一个空的字符串。
  32. </para></listitem>
  33. <listitem><para>
  34. <code>fieldset($name, $content, $attribs):</code> 生成一个 XHTML fieldset. 如果 <code>$attribs</code> 包含一个 'legend' 键,它的值将用于 fieldset legend。 Fieldset 将环绕在 <code>$content</code> 周围提供给助手。
  35. </para></listitem>
  36. <listitem><para>
  37. <code>form($name, $attribs, $content):</code> 生成一个 XHTML 表单。所有 <code>$attribs</code> 转义和解析成表单标签的 XHTML 属性。如果 <code>$content</code> 不以布尔 false 出现,那么内容就是在表单标签内被解析,如果 <code>$content</code> 是布尔 false (缺省),只有开头的表单标签被生成。
  38. </para></listitem>
  39. <listitem><para>
  40. <code>formButton($name, $value, $attribs):</code> 生成 &lt;button /&gt; 元素;
  41. </para></listitem>
  42. <listitem><para>
  43. <code>formCheckbox($name, $value, $attribs,$options):</code> 生成 &lt;input type="checkbox" /&gt; 元素。
  44. </para>
  45. <para>
  46. 缺省地,当没有提供 $value 并且没有 $options,'0' 被假定为未选的值,'1'为选中的值。
  47. 如果传递 $value,但没有 $options,选中的值就被假定为传递的值。
  48. </para>
  49. <para>
  50. $options 应当是数组。如果数组被索引,第一个值就是选中的值,第二个是未选的值,
  51. 所有其它值被忽略。 你也可传递一个带有键为 'checked' 和 'unChecked' 的联合数组。
  52. </para>
  53. <para>
  54. 如果传递了 $options,如果 $value 匹配选中的值,元素将标记为选中。你也通过传递
  55. 一个布尔值给属性 'checked' 来标记元素为选中或未选。
  56. </para>
  57. <para>
  58. 上述内容可能最好汇总成一些例子:
  59. </para>
  60. <programlisting role="php"><![CDATA[<?php
  61. // '1' and '0' as checked/unchecked options; not checked
  62. echo $this->formCheckbox('foo');
  63. // '1' and '0' as checked/unchecked options; checked
  64. echo $this->formCheckbox('foo', null, array('checked' => true));
  65. // 'bar' and '0' as checked/unchecked options; not checked
  66. echo $this->formCheckbox('foo', 'bar');
  67. // 'bar' and '0' as checked/unchecked options; checked
  68. echo $this->formCheckbox('foo', 'bar', array('checked' => true));
  69. // 'bar' and 'baz' as checked/unchecked options; unchecked
  70. echo $this->formCheckbox('foo', null, null, array('bar', 'baz');
  71. // 'bar' and 'baz' as checked/unchecked options; unchecked
  72. echo $this->formCheckbox('foo', null, null, array(
  73. 'checked' => 'bar',
  74. 'unChecked' => 'baz'
  75. ));
  76. // 'bar' and 'baz' as checked/unchecked options; checked
  77. echo $this->formCheckbox('foo', 'bar', null, array('bar', 'baz');
  78. echo $this->formCheckbox('foo', null, array('checked' => true), array('bar', 'baz');
  79. // 'bar' and 'baz' as checked/unchecked options; unchecked
  80. echo $this->formCheckbox('foo', 'baz', null, array('bar', 'baz');
  81. echo $this->formCheckbox('foo', null, array('checked' => false), array('bar', 'baz');
  82. ]]></programlisting>
  83. <para>
  84. 对所有情况,标记预先准备一个带有未选的值的隐藏元素。
  85. 这样,如果值是未选的,你将仍获得有效的返回到表单的值。
  86. </para>
  87. </listitem>
  88. <listitem>
  89. <para>
  90. <code>formErrors($errors, $options):</code> 生成一个无顺序的 XHTML 列表来显示错误。 <code>$errors</code> 是个字符串或字符串数组;<code>$options</code> 是你想放入开头列表标签的任何属性。
  91. </para>
  92. <para>
  93. 当通过调用助手中的方法时,你可以指定替代的开头,结尾和分隔符:
  94. </para>
  95. <itemizedlist>
  96. <listitem><para>
  97. <code>setElementStart($string)</code>; 缺省为 '&lt;ul class="errors"%s"&gt;&lt;li&gt;', 其中 %s 是在 <code>$options</code> 中被替换的属性。
  98. </para></listitem>
  99. <listitem><para>
  100. <code>setElementSeparator($string)</code>; 缺省为 '&lt;/li&gt;&lt;li&gt;'。
  101. </para></listitem>
  102. <listitem><para>
  103. <code>setElementEnd($string)</code>; 缺省为 '&lt;/li&gt;&lt;/ul&gt;'。
  104. </para></listitem>
  105. </itemizedlist>
  106. </listitem>
  107. <listitem><para>
  108. <code>formFile($name, $value, $attribs):</code> 生成&lt;input
  109. type="file" /&gt;
  110. </para></listitem>
  111. <listitem><para>
  112. <code>formHidden($name, $value, $attribs):</code> 生成&lt;input
  113. type="hidden" /&gt;
  114. </para></listitem>
  115. <listitem><para>
  116. <code>formLabel($name, $value, $attribs):</code> 生成
  117. &lt;label&gt;设置 <code>for</code> 属性给
  118. <code>$name</code>,实际的标签字符给 <code>$value</code>。
  119. 如果 <code>disable</code> 传递给
  120. <code>attribs</code>,什么都不返回。
  121. </para></listitem>
  122. <listitem><para>
  123. <code>formMultiCheckbox($name, $value, $attribs, $options, $listsep):</code> 生成一个 checkboxes 列表。<code>$options</code> 是个联合数组,可以有任意的深度。<code>$value</code> 可以是单个的值或者是可选的匹配在 <code>$options</code> 数组中的键的一个数组。<code>$listsep</code> 缺省为一个 HTML break ("&lt;br /&gt;")。缺省地,这个元素被当作数组,所有 checkboxes 共享同一个名称,并以数组的形式提交。
  124. </para></listitem>
  125. <listitem><para>
  126. <code>formPassword($name, $value, $attribs):</code> Creates an
  127. &lt;input type="password" /&gt; element.
  128. </para></listitem>
  129. <listitem><para>
  130. <code>formRadio($name, $value, $attribs, $options):</code> 生成一系列&lt;input type="button" /&gt;,每个$options数组元素一个,key为radio的值,并且元素的值是radio的标签。
  131. </para></listitem>
  132. <listitem><para>
  133. <code>formReset($name, $value, $attribs):</code> 生成&lt;input
  134. type="reset" /&gt;
  135. </para></listitem>
  136. <listitem><para>
  137. <code>formSelect($name, $value, $attribs, $options):</code> 生成&lt;select&gt;...&lt;/select&gt;其中的每个&lt;option&gt;对应于一个$option数组元素。元素的key是option的值,元素的值是option的标签。$value这个值的option默认为选中。
  138. </para></listitem>
  139. <listitem><para>
  140. <code>formSubmit($name, $value, $attribs):</code> 生成&lt;input
  141. type="submit" /&gt;
  142. </para></listitem>
  143. <listitem><para>
  144. <code>formText($name, $value, $attribs):</code> 生成&lt;input
  145. type="text" /&gt;
  146. </para></listitem>
  147. <listitem><para>
  148. <code>formTextarea($name, $value, $attribs):</code> 生成&lt;textarea&gt;...&lt;/textarea&gt;
  149. </para></listitem>
  150. <listitem><para>
  151. <code>url($urlOptions, $name, $reset):</code> 基于已命名的路由生成URL字符串。<code>$urlOptions</code> 必须是一个键/值对应的关联数组,用于特定的路由。
  152. </para></listitem>
  153. <listitem><para>
  154. <code>htmlList($items, $ordered, $attribs):</code> 基于传递给它的 <code>$items</code> 生成无序的和有序的列表。如果 <code>$items</code> 是多维数组,将创建嵌套的列表。
  155. </para></listitem>
  156. </itemizedlist>
  157. <para>
  158. 以上helper的使用非常简单,下面是个例子。注意你只需要调用即可,它们会根据需要自己加载并实例化。
  159. </para>
  160. <programlisting role="php"><![CDATA[<?php
  161. // 在你的view脚本内部, $this 指向 Zend_View 实例.
  162. //
  163. // 假设你已经为select对应的变量$countries指定一系列option值,
  164. // array('us' => 'United States', 'il' =>
  165. // 'Israel', 'de' => 'Germany').
  166. ?>
  167. <form action="action.php" method="post">
  168. <p><label>Your Email:
  169. <?php echo $this->formText('email', 'you@example.com', array('size' => 32)) ?>
  170. </label></p>
  171. <p><label>Your Country:
  172. <?php echo $this->formSelect('country', 'us', null, $this->countries) ?>
  173. </label></p>
  174. <p><label>Would you like to opt in?
  175. <?php echo $this->formCheckbox('opt_in', 'yes', null, array('yes', 'no')) ?>
  176. </label></p>
  177. </form>]]>
  178. </programlisting>
  179. <para>
  180. 以上视图脚本会输出这样的结果:
  181. </para>
  182. <programlisting role="php"><![CDATA[<form action="action.php" method="post">
  183. <p><label>Your Email:
  184. <input type="text" name="email" value="you@example.com" size="32" />
  185. </label></p>
  186. <p><label>Your Country:
  187. <select name="country">
  188. <option value="us" selected="selected">United States</option>
  189. <option value="il">Israel</option>
  190. <option value="de">Germany</option>
  191. </select>
  192. </label></p>
  193. <p><label>Would you like to opt in?
  194. <input type="hidden" name="opt_in" value="no" />
  195. <input type="checkbox" name="opt_in" value="yes" checked="checked" />
  196. </label></p>
  197. </form>]]>
  198. </programlisting>
  199. <xi:include href="Zend_View-Helpers-Action.xml" />
  200. <xi:include href="Zend_View-Helpers-Partial.xml" />
  201. <xi:include href="Zend_View-Helpers-Placeholder.xml" />
  202. <xi:include href="Zend_View-Helpers-Doctype.xml" />
  203. <xi:include href="Zend_View-Helpers-HeadLink.xml" />
  204. <xi:include href="Zend_View-Helpers-HeadMeta.xml" />
  205. <xi:include href="Zend_View-Helpers-HeadScript.xml" />
  206. <xi:include href="Zend_View-Helpers-HeadStyle.xml" />
  207. <xi:include href="Zend_View-Helpers-HeadTitle.xml" />
  208. <xi:include href="Zend_View-Helpers-HtmlObject.xml" />
  209. <xi:include href="Zend_View-Helpers-InlineScript.xml" />
  210. <xi:include href="Zend_View-Helpers-Json.xml" />
  211. <xi:include href="Zend_View-Helpers-Translate.xml" />
  212. </sect2>
  213. <sect2 id="zend.view.helpers.paths">
  214. <title>助手的路径</title>
  215. <para>
  216. 就像可以指定视图脚本的路径,控制器也可以为<code>Zend_View</code>设定助手类的路径。默认地,<code>Zend_View</code>会到 “Zend/View/Helper/”下查找助手类。可以用 <code>setHelperPath()</code> 和 <code>addHelperPath()</code> 方法来告诉 <code>Zend_View</code> 从其它地方来找路径。另外,你也可以指定类名的前缀,用于指定助手类所在的路径,允许给助手类命名空间。默认情况下,如果没有给出前缀,会假设使用“Zend_View_Helper_”。
  217. </para>
  218. <programlisting role="php"><![CDATA[<?php
  219. $view = new Zend_View();
  220. // 设置路径为:/path/to/more/helpers, 通过使用前缀 'My_View_Helper'
  221. $view->setHelperPath('/path/to/more/helpers', 'My_View_Helper');]]>
  222. </programlisting>
  223. <para>
  224. 你可以用<code>addHelperPath()</code>来增加helper的路径, <code>Zend_View</code>将使用最近增加的路径。这样你可以使用自己的helper。
  225. </para>
  226. <programlisting role="php"><![CDATA[<?php
  227. $view = new Zend_View();
  228. // Add /path/to/some/helpers with class prefix 'My_View_Helper'
  229. $view->addHelperPath('/path/to/some/helpers', 'My_View_Helper');
  230. // Add /other/path/to/helpers with class prefix 'Your_View_Helper'
  231. $view->addHelperPath('/other/path/to/helpers', 'Your_View_Helper');
  232. // now when you call $this->helperName(), Zend_View will look first for
  233. // "/path/to/some/helpers/HelperName" using class name "Your_View_Helper_HelperName",
  234. // then for "/other/path/to/helpers/HelperName.php" using class name "My_View_Helper_HelperName",
  235. // and finally for "Zend/View/Helper/HelperName.php" using class name "Zend_View_Helper_HelperName".]]>
  236. </programlisting>
  237. </sect2>
  238. <sect2 id="zend.view.helpers.custom">
  239. <title>编写自定义的助手类</title>
  240. <para>
  241. 编写自定义的助手类很容易,只要遵循以下几个原则即可:
  242. </para>
  243. <itemizedlist>
  244. <listitem><para>
  245. helper的类名最后部分必须是helper的名称,并使用混合大小写字格式。例如,你在写一个名为“specialPurpose”的类,类名将至少是"SpecialPurpose",另外你还应该给类名加上前缀,建议将“View_Helper”作为前缀的一部份:“My_View_Helper_SpecialPurpose”。(注意大小写)你将需要将前缀(包含或不包含下划线)传递给<code>addHelperPath()</code> 或 <code>setHelperPath()</code>。
  246. </para></listitem>
  247. <listitem><para>
  248. 类中必须有一个public的方法,该方法名与helper类名相同。该方法将在你的模板调用"$this->specialPurpose()"时执行。在我们的“specialPurpose”例子中,相应的方法声明可以是“public function specialPurpose()”。
  249. </para></listitem>
  250. <listitem><para>
  251. 一般来说,助手类不应该echo或print或有其它形式的输出。它只需要返回值就可以了。返回的数据应当被转义。
  252. </para></listitem>
  253. <listitem><para>
  254. 类文件的命名应该是助手类的名称,比如在"specialPurpose"例子中,文件要存为“SpecialPurpose.php”。
  255. </para></listitem>
  256. </itemizedlist>
  257. <para>
  258. 把助手类的文件放在你的助手路径下, <code>Zend_View</code>就会自动加载,实例化,持久化,并执行。
  259. </para>
  260. <para>
  261. 下面是一个<code>SpecialPurpose</code> 助手代码的例子:
  262. </para>
  263. <programlisting role="php"><![CDATA[<?php
  264. class My_View_Helper_SpecialPurpose
  265. {
  266. protected $_count = 0;
  267. public function specialPurpose()
  268. {
  269. $this->_count++;
  270. $output = "I have seen 'The Jerk' {$this->_count} time(s).";
  271. return htmlspecialchars($output);
  272. }
  273. }]]>
  274. </programlisting>
  275. <para>
  276. 在视图代码中,可以调用 <code>SpecialPurpose</code> 助手任意次。它将被实例化一次,并且会在<code>Zend_View</code>实例的生命周期内持久存在。
  277. </para>
  278. <programlisting role="php"><![CDATA[<?php
  279. // remember, in a view script, $this refers to the Zend_View instance.
  280. echo $this->specialPurpose();
  281. echo $this->specialPurpose();
  282. echo $this->specialPurpose();]]>
  283. </programlisting>
  284. <para>
  285. 输出结果如下所示:
  286. </para>
  287. <programlisting role="php"><![CDATA[I have seen 'The Jerk' 1 time(s).
  288. I have seen 'The Jerk' 2 time(s).
  289. I have seen 'The Jerk' 3 time(s).]]>
  290. </programlisting>
  291. <para>
  292. 有时候需要访问调用<code>Zend_View</code> 对象-例如,如果需要使用已指定的编码字符集,或想解析其它视图脚本作为助手的一部分。为了访问视图对象,助手类应该有一个 <code>setView($view)</code> 方法,如下:
  293. </para>
  294. <programlisting role="php"><![CDATA[<?php
  295. class My_View_Helper_ScriptPath
  296. {
  297. public $view;
  298. public function setView(Zend_View_Interface $view)
  299. {
  300. $this->view = $view;
  301. }
  302. public function scriptPath($script)
  303. {
  304. return $this->view->getScriptPath($script);
  305. }
  306. }]]>
  307. </programlisting>
  308. <para>
  309. 如果助手类有一个 <code>setView()</code> 方法,它将在助手类第一次实例化时被调用,并接受当前视图对象作为参数。是否让它在类里持久和如何访问,都完全取决于你。
  310. </para>
  311. </sect2>
  312. </sect1>
  313. <!--
  314. vim:se ts=4 sw=4 et:
  315. -->