Helper
Helper意为着提供许多函数,这些函数通常用在view中,并以一种有用的方式格式化并展示数据。
HTML Helper是Cake的一种让开发不再那么枯燥,并且变得更加快速的方法。HTML Helper有2个目标:帮助插入HTML代码中经常重复的部分,并致力于快速简单创建Web表单。下面的章节将为你介绍最重要的Helper函数,但是记住使用http://api.cakephp.org作为最终的参考。
HTML Helper的许多函数使用了HTML标签定义文件,此文件为tags.ini.php.Cake核心的配置文件包含了一个tags.ini.php,但是如果你想做出一些修改,拷贝一份/cake/config/tags.ini.php,并将它放在/app/config/ 文件夹下。HTML Helper在文件里使用标签定义来生成你请求的标签。使用HTML Helper来创建某些view代码是有帮助的,因为一个tags.ini.php文件的修改会导致一个站点级的变化。
除此之外,在应用程序的核心配置文件(/app/config/core.php)里,如果AUTO_OUTPUT设置为true,Helper会自动输出标签,而不是返回其值。通过努力,已经实现它来减轻那些厌恶在他们view代码里调用短标签(<?= ?>)或许多echo()的痛楚。包含$return参数的函数允许你强制覆写核心配置的设置。如果你想HTML Helper返回HTML代码而与AUTO_OUTPUT的任何设置无关,将$return设置为true,
HTML Helper函数也包含参数$htmlAttributes,此参数允许你跟踪标签上的额外属性。例如,如果你有一个标签,并且你想为它增加一个class属性,你可以将它作为$htmlAttribute值传入:
|
array('class'=>'someClass')
|
如果你想使用Cake在HTML代码里插入格式化好了的,并且经常重复的元素,HTML Helper最擅长做这件事情了。在helper里有很多函数插入媒体,并帮助处理表。甚至有guiListTree来创建一个无序的基于PHP数组的列表。
charset
- string $charset
- boolean $return
用来生成一个字符集的META标签。
css
- string $path
- string $rel = 'stylesheet'
- array $htmlAttributes
- boolean $return = false
$rel参数允许你为标签提供一个rel=的值。
创建一个CSS样式的链接。
image
- string $path
- array $htmlAttributes
- boolean $return = false
Render一个图像标签。函数返回的代码可以做为一个link()函数的输入框来自动创建链接的图像。
link
- string $title
- string $url
- array $htmlAttributes
- string $confirmMessage = false
- boolean $escapeTitle = true
- boolean $return = false
在view里使用本函数创建链接。当点击链接后,如果你需要显示一个JavaScript确认消息时,使用$confirmMessage吧。例如,在链接启用之前,点击一个删除对象的链接可能会跳出一个"Are you sure?"消息来确认动作。如果你想让HTML
Helper跳出你在$title变量里设置的数据,将$escapeTitle设置为true。
tableHeaders
- array $names
- array $tr_options
- array $th_options
使用一个格式化的表头。
tableCells
- array $data
- array $odd_tr_options
- array $even_tr_options
用来创建一组格式化的表单元格。
guiListTree
- array $data
- array $htmlAttributes
- string $bodyKey = 'body'
- string $childrenKey =
'children'
- boolean $return = false
从数组里生成一个无序嵌套的列表树。
在你的view里,当HTML Helper想加速你的表单代码时,这时它表现的非常耀眼。它会生成所有的表单标记,在错误的环境下会自动填充值,并会指出错误信息。为了帮助表述,让我们过一遍一个快速的实例。假设一会应用程序有一个Note model,并且你想创建controller逻辑和一个view来增加和编辑Note对象。在NotesController,你会有一个edit动作,可能如下:
function edit($id)
{
//First, let's check to see if any form data has been
//submitted to the action.
if (!empty($this->data['Note']))
{
//Here's where we try to validate the form data (see Chap. 12)
//and save it
if ($this->Note->save($this->data['Note']))
{
//If we've successfully saved, take the user
//to the appropriate place
$this->flash('Your information has been saved.', '/notes/edit/' . $id);
exit();
}
else
{
//Generate the error messages for the appropriate fields
//this is not really necessary as save already does this, but it is an example
//call $this->Note->validates($this->data['Note']); if you are not doing a save
//then use the method below to populate the tagErrorMsg() helper method
$this->validateErrors($this->Note);
//And render the edit view code
$this->render();
}
}
// If we haven't received any form data, get the note we want to edit, and hand
// its information to the view
$this->set('note', $this->Note->find("id = $id"));
$this->render();
}
|
一旦我们建立了controller,让我们看看view代码(在app/views/notes/edit.thtml). 在这里,我们的Note Model非常简单,因为它仅仅包含了一个id,一个提交者的id,以及一个body。view代码会显示Note数据,并允许用户输入新的值,然后将数据保存到model里。
缺省的,HTML Helper在所有view都是可用的,我们可以使用$html来访问它。
特别的,让我们看看表,表单的核心就在这里:
编辑View
(edit.thtml)代码实例
<!-- This tag creates our form tag -->
<?php echo $html->formTag('/notes/edit/' . $html->tagValue('Note/id')?>
<table cellpadding="10" cellspacing="0">
<tr>
<td align="right">Body: </td>
<td>
<!-- Here's where we use the HTML helper to render the text
area tag and its possible error message the $note
variable was created by the controller, and contains
the data for the note we're editing. -->
<?php echo
$html->textarea('Note/body', array('cols'=>'60', 'rows'=>'10'));
?>
<?php echo $html->tagErrorMsg('Note/body',
'Please enter in a body for this note.') ?>
</td>
</tr>
<tr>
<td></td>
<td>
<!-- We can also use the HTML helper to include
hidden tags inside our table -->
<?php echo $html->hiddenTag('Note/id')?>
<?php echo $html->hiddenTag('note/submitter_id', $this->controller->Session->read('User.id'))?>
</td>
</tr>
</table>
<!-- And finally, the submit button-->
<?php echo $html->submit()?>
</form>
|
大多数表单标记生成函数(与tagErrorMsg一起)需要提供$fieldName。$fieldName让Cake知道你传递哪些数据,使它能正确保存并验证这些数据。传递给$fieldName参数的字符串以"Model名(modelname)/字段名(fieldname)"的格式来传递。
如果你正想增加一个标题的字段到我们的Note中,你需要增加一些东东到View中,像下面这样:
<?php echo $html->input('Note/title') ?>
<?php echo $html->tagErrorMsg('Note/title', 'Please supply a title for this note.')?>
|
tagErrorMsg()函数显示的错误信息包含在<div class="error_message"></div>,并有简单的CSS样式。
下面是HTML Helper可以生成的表单标签(tag)(他们大多数都是非常明了的):
submit
- string $buttonCaption
- array $htmlAttributes
- boolean $return = false
password
- string $fieldName
- array $htmlAttributes
- boolean $return = false
textarea
- string $fieldName
- array $htmlAttributes
- boolean $return = false
checkbox
- string $fieldName
- array $htmlAttributes
- boolean $return = false
file
- string $fieldName
- array $htmlAttributes
- boolean $return = false
hidden
- string $fieldName
- array $htmlAttributes
- boolean $return = false
input
- string $fieldName
- array $htmlAttributes
- boolean $return = false
radio
- string $fieldName
- array $options
- array $inbetween
- array $htmlAttributes
- boolean $return = false
tagErrorMsg
- string $fieldName
- string $message
HTML Helper同时也包含一组函数,这些函数帮助创建与日期相关的选项标签。$tagName参数应该当成$fieldName参数以同样的方式来处理。仅提供日期选项标签相关的字段名称。一旦数据被处理,你会在你的Controller里看见它。此Controller包含它处理的日期部分,并且在字段名结尾处连接。例如,如果Note有一个日期类型的截止日期(Deadline)字段,那么dayOptionTag $tagName参数应设置为'note/deadline',一旦将表单提交到一个controller动作里,日期数据会在$params参数里显示:
$this->data['Note']['deadline_day']
|
然后你能使用此信息以一种格式连接时间数据,此格式对当前数据库配置来说是友好的。本代码仅在你打算保存数据之前才放入的,将它保存到一个$data数组,此数组用来将信息保存到model中。
在保存model之前链接时间数据(摘录自NotesController)
function edit($id)
{
//First, let's check to see if any form data has been submitted to the action.
if (!empty($this->data['Note']))
{
//Concatenate time data for storage...
$this->data['Note']['deadline'] =
$this->data['Note']['deadline_year'] . "-" .
$this->data['Note']['deadline_month'] . "-" .
$this->data['Note']['deadline_day'];
//Here's where we try to validate the form data (see Chap. 10) and save it
if ($this->Note->save($this->data['Note']))
{
...
|
1.
dayOptionTag
($tagName, $value=null, $selected=null, $optionAttr=null)
2.
yearOptionTag
($tagName, $value=null, $minYear=null, $maxYear=null, $selected=null,
$optionAttr=null)
3.
monthOptionTag
($tagName, $value=null, $selected=null, $optionAttr=null)
4.
hourOptionTag
($tagName, $value=null, $format24Hours=false, $selected=null, $optionAttr=null)
5.
minuteOptionTag
($tagName, $value=null, $selected=null, $optionAttr=null)
6.
meridianOptionTag
($tagName, $value=null, $selected=null, $optionAttr=null)
7.
dateTimeOptionTag
($tagName, $dateFormat= 'DMY', $timeFormat= '12', $selected=null,
$optionAttr=null)
AJAX
为了Ajax操作和客户端效果,Cake的Ajax Helper利用了曾经流行的Prototype和script.aculo.us库。为使用这个Helper,你必须从http://script.aculo.us得到一个当前版本的JavaScript库,并将它放在/app/webroot/js/这个地方。除此之外,任何计划使用Ajax
Helper的View需要包含这些库。
本Helper的大多数函数需要有一个特定的$options数组作为参数。本数组用来指定关于Ajax操作的不同东西。下面是可以制定的不同值:
AjaxHelper $options 键
|
/* 一般选项*/
$options['url'] //你想用来调用的动作(Action)URL
$options['frequency'] //remoteTimer()或observeField()检查的间隔秒 数
$options['update'] // 你希望用来更新Ajax操作结果的元素的DOM ID。
$options['with'] //你希望用来序列化而且随一个Ajax表单提交的表单元素 DOM ID。
$options['type'] // 要么是'asynchronous' (缺省),或是 'synchronous'.
//允许选择一个操作类型
/* 回调 : 在XMLHttpRequest 处理过程中在某次数上执行的JS代码*/
$options['loading'] //当浏览器加载远程数据时执行的JS 代码
$options['loaded'] //当浏览器正完成加载远程文档时执行的JS 代码。
$options['interactive'] // 当用户可以和远程文档交互,甚至没有完成加载时执行的JS编码。
$options['complete'] //完成时调用的JS编码。
$options['confirm'] //在一个XMLHttpRequest动作开始之前在确认对话框显示的文本。
$options['condition'] // XMLHttpRequest启动之前需要符合的JS条件。
$options['before'] //请求启动前调用的JS编码
$options['after'] //在请求启动后,加载前理解调用的JS编码
|
下面的Helper函数使Cake的Ajax变得更加快速而且简单:
link
- string $title
- string $href
- array $options
- boolean $confirm
- boolean $escapeTitle
显示链接文本$title,它获取$options['url']的远程文档,并且更新DOM元素$options['update'].回调可以和本函数一起使用。
remoteFunction
本函数创建一个远程调用需要的JavaScript。为linkToRemote,它主要作为一个Helper。它不会常常使用,除非你需要生成一些自定义的脚本。
remoteTimer
周期性的调用在$options['url']中指定的动作,周期是每$options['frequency']秒(缺省为10)。通常用来更新一个指定的带有远程调用结果的div(由$options['update']指定)。回调可以和本函数一起使用。
form
- string $action
- string $type
- array $options
返回一个表单,本表单提交到$action动作,在后台使用XMLHttpRequest代替常规的重加载POST提交。本表单的数据仅扮演一个正常的表单数据角色,(例如,可以在$this->params['form']获取)。$options['update']指定的DOM元素会更新为受影响的远程文档。回调可以和本函数一起使用。
observeField
- string $field_id
- array $options
观察$field_id指定的DOM ID字段(每$options['frequency']秒),并当他的内容改变时调用$options['url']的动作。你也可以更新ID为D $options['update']的DOM元素,或指定一个也使用$options['with']的表单元素。回调可以和本函数一起使用。
observeForm
- string $form_id
- array $options
和observeField()一样。它仅观察给定表单的所有元素。
autoComplete
- string $field
- string $url
- array $options
自动完成renderID为$field的文本字段。$url的动作应该可以返回autocomplete条件:基本上,你的动作需要取消一个无序列表(<ul></ul>),此列表有一些自动完成的条件。如果你想要一个获取Blog Post主题的autocomplete字段,Controller动作可以如下:
function autocomplete ()
{
$this->set('posts',
$this->Post->findAll(
"subject LIKE '{$this->data['Post']['subject']}'")
);
$this->layout = "ajax";
}
|
上面autocomplete()动作对应的view可以如下:
<ul>
<?php foreach($posts as $post): ?>
<li><?php echo $post['Post']['subject']; ?></li>
<?php endforeach; ?>
</ul>
|
在View里实际看到的自动完成(auto-complete)字段应该如下:
<form action="/users/index" method="POST">
<?php echo $ajax->autoComplete('Post/subject', '/posts/autoComplete')?>
<?php echo $html->submit('View Post')?>
</form>
|
autoComplete()函数使用本信息render一个文本字段,以及一些用来展示动作提供的autocomplete条件的div。你也可能想将view打扮成下面这样:
<style type="text/css">
div.auto_complete {
position :absolute;
width :250px;
background-color :white;
border :1px solid #888;
margin :0px;
padding :0px;
}
li.selected { background-color: #ffb; }
</style>
|
drag
- string $id
- array $options
使ID 为$id 的DOM元素可以拖拽。你需要在$options里指定一些附加的信息:
|
// (版本号参考script.aculo.us版本)
$options['handle'] // (v1.0)设置作为一个嵌入的处理元素是否仅可以拖拽。//本值必须为一个元素的引用或者元素的ID。
$options['handle'] // (V1.5)和上面一样,除了当前值可以是一个引用了一个CSS class值的字符串。第一个child/grandchild/etc可以在有本CSS class值的元素中找到,此CSS作为句柄来使用了。
$options['revert'] // (V1.0)如果设置为true,当拖拽结束时元素返回它的原始位置。
$options['revert'] // (V1.5)撤销也可以为一个任意的函数引用,当拖拽结束时调用。
$options['constraint'] // 如果设置为horizontal(水平)或 vertical(垂直),拖拽会受限,仅仅在水平或垂直上发生。
|
drop
- string $id
- array $options
使ID为$id 的DOM元素可以下拉。你可以在$options里指定一些附加的信息:
|
$options['accept'] //.将 accept设置为一个字符串或者一个描述CSS class的 JavaScript的字符串数组。Droppable仅接受Draggable,此Draggable有这些CSS class的一个或多个。
$options['containment'] //如果它包含在给定元素(或者元素id)中,可下拉的元素仅接受可下拉的元素。可以是单个,也可以是一个元素的JS数组。
$options['overlap'] //如果设置为orizontal(水平)或 vertical(垂直),,如果在给定方向超过50%的重复,可下拉的元素仅对可下拉的元素有反应。
|
dropRemote
- string $id
- array $options
- array $ajaxOptions
用来创建一个下拉目标,当一个拖拽的元素可以在它之上下拉时,它会启动一个XMLHttpRequest请求。$options和drop()一样,而且$ajaxOptions和link()相同。
sortable
- string $id
- array $options
使一组浮动的对象(ID为$id的DOM 元素指定)组或列表变得有序。$options数组可以如下配置你的排序:
|
$options['tag'] // 设置为排序的标签(或者容器里的子元素)。对于OL容易,它是LI,你必须为其他子标签提供标签种类,且省为’li’.
$options['only'] //进一步限制子元素的选择,仅选取那些给定CSS class的元素(或者,如果你提供了一个字符串的数组,选择任何CSS
class的那些元素)。
$options['overlap'] // vertical(缺省)或者 horizontal,对于浮动的有序对象或水平列表,选择horizontal。垂直列表应该是vertical
$options['constraint'] //将可拖拽的元素移动限制为'vertical' 或 'horizontal'
$options['containment'] // 启用Sortable间的拖拽和下拉。使用一组元素或元素id(容器里的)
$options['handle'] //使创建的可拖拽的元素使用句柄,参看drag()的handle选项。
|
editor
- string $id
- string $url
- array $options
将ID为id的DOM元素作第一个参数来创建一个内建的Ajax编辑器。实现之后,mouseOver时元素会突出,当点击时,会变为一个文本输入框。第二个参数是一个编辑的数据发送到此的URL。动作也可以返回一个已更新的元素内容。编辑器的其他附加选项可以在Script.aculo.us的wiki里找到。
JavaScript Helper用来帮助开发人员输出优秀格式的与JavaScript相关的标签和数据。
codeBlock
返回JavaScript <script>标签里的$script。
link
返回一个JavaScript include标签,它指向引用$url的脚本。
linkOut
和link()相同,include标签仅假定引用$url的脚本不再相同的域上。
escapeScript
忽略JavaScript代码的回车,单引号和双引号。
event
- string $object
- string $event
- string $observer
- boolean $useCapture
将一事件加到一个元素上。和Prototype库一起使用。
缓存event()创建的的JavaScript事件。
写入cacheEvents()缓存的事件。
includeScript
数字Helper包含了一些非常优秀的函数来格式化View的数字。
precision
- mixed $number
- int $precision = 3
返回格式化到$precision指定的精确度的$number
toReadableSize
返回一个可读的大小,假定$size以字节提供。
基本上,你传入一字节数,本函数返回一个合适的可读的KB, MB,
GB,或TB值。
toPercentage
- mixed $number
- int $precision = 2
返回格式化为百分数的数字,并精确到$precision。
Text Helper提供一些方法供开发人员将优秀格式化好的文本输出到浏览器。
highlight
- string $text
- string $highlighter =
'<span class="highlight">\1</span>'
返回$text,带有此文本每个出现的地方或$phrase ,它们都在$highlighter指定的标签中。
stripLinks
返回已删除所有HTML链接(<a href=…)的$text。
autoLinkUrls
- string $text
- array $htmlOptions
返回包含对应的<a>标签中的URL的$text。
autoLinkEmails
- string $text
- array $htmlOptions
返回包含在相应<a>标签中的邮件地址的$text
autoLink
- string $text
- array $htmlOptions
返回包含在相应的<a>标签中的URL和email。
truncate
- string $text
- int $length
- string $ending = '...'
返回第一个$text 中的$length数量的字符,并且$text紧跟$ending (缺省'...' )。的
excerpt
- string $text
- string $phrase
- int $radius = 100
- string $ending = '...'
解析一个对$text的引用,在每边的$radius范围内抓取一定数量字符的$phrase。
autoLinkEmails
- string $text
- boolean $allowHtml = false
文本到HTML的解析器,和Textile或RedCloth有点类似,仅仅是语法有一点不同。
时间Helper提供方法让开发人员将Unix时间戳和/或日期时间字符串格式化为更加利于理解的格式并输出到浏览器。
可以将时间以有效PHP时间字符串或Unix时间戳提供给所有函数。
fromString
如果给定一个UNIX时间戳或一个有效的strtotime()日期字符串,返回一个UNIX时间戳。
nice
- string $dateString
- boolean $return = false
返回一个格式化非常好的日期字符串。日期格式为"D, M
jS Y, H:i", 或 'Mon, Jan 1st 2005, 12:00'.
niceShort
- string $dateString
- boolean $return = false
格式话如nice()指定的日期字符串,但是如果字符串是今天,却输出"Today, 12:00",如果字符串是昨天,却输出"Yesterday,
12:00"
isToday
如果给定的日期字符串是今天,则返回true。
daysAsSql
- string $begin
- string $end
- string $fieldName
- boolean $return = false
返回一个局部的SQL字符串来查询所有在这2个日期之间的记录。
dayAsSql
- string $dateString
- string $fieldName
- boolean $return = false
返回一个局部SQL字符串来查询所有发生在同一天而且在这2个时间的记录。
isThisYear
- string $dateString
- boolean $return = false
如果给定的日期是在当年,返回true。
wasYesterday
- string $dateString
- boolean $return = false
如果给定的日期是在昨天,返回true。
isTomorrow
- string $dateString
- boolean $return = false
如果给定的日期是在明天,返回true。
toUnix
- string $dateString
- boolean $return = false
返回一个文本时间描述的UNIX时间戳,一个对PHP函数strtotime()的包装。
toAtom
- string $dateString
- boolean $return = false
为Atom RSS feed返回一个格式化的日期。
toRSS
- string $dateString
- boolean $return = false
为RSS feed格式化日期。
timeAgoInWords
- string $dateString
- boolean $return = false
返回一个相对日期或者一个格式化的日期,此日期取决于当前时间和给定时间的差。$datetime的格式应该是strtotime()可解析的,像MySQL的时间。
relativeTime
- string $dateString
- boolean $return = false
与timeAgoInWords()非常类似,但是它有能力为未来的时间戳创建输出(例如,"Yesterday, 10:33", "Today, 9:42", 以及 "Tomorrow, 4:34").
relativeTime
- string $timeInterval
- string $dateString
- boolean $return = false
如果指定的时间在指定的间隔内,返回true,否则返回false。时间间隔应该以数字的格式指定,单位也是:'6 hours', '2
days'等。
在你的view代码中,是否需要一些帮助?如果你发现你自己不断的需要某些特定的view逻辑,你可创建你自己的view helper。
假设我们想创建一个helper,它可以用来输出一个应用程序中使用的CSS格式的链接。为了让你的逻辑合适Cake已存在的Helper结构,你需要在/app/views/helpers创建一个新类。让我们称我们的helper为LinkHelper吧。实际的PHP类文件如下:
|
class LinkHelper extends Helper
{
function makeEdit($title, $url)
{
// Logic to create
specially formatted link goes here...
}
}
|
你可能需要利用在Cake Helper类里包含的一些函数:
output
- string $string
- boolean $return = false
决定是否输出或返回一个基于AUTO_OUTPUT(参看/app/config/core.php)和$return值的字符串。你应该使用此方法将所有数据返回到view里。
返回应用程序当前核心的配置以及标签定义。
使用output()格式化我们链接标题以及URL,并将它返回给view。
|
class LinkHelper extends Helper
{
function makeEdit($title, $url)
{
// Use the helper's
output function to hand formatted
// data back to the view:
return $this->output("<div
class=\\"editOuter\\"><a href=\\"$url\\"
class=\\"edit\\">$title</a></div>");
}
}
|
你可能想使用在其他helper中已经存在的功能。为了利用他们,你可以在$helper数组里指定你想使用的helper,和你在controller的格式一样.
|
class LinkHelper extends Helper
{
var $helpers = array('Html');
function makeEdit($title, $url)
{
// Use the HTML
helper to output
// formatted data:
$link = $this->Html->link($title, $url, array('class' =>
'edit'));
return $this->output("<div
class=\\"editOuter\\">$link</div>");
}
}
|
一旦你已经创建了一个helper,而且将它放入/app/views/helpers/,你需要通过特殊的$helper变量将它包含在你的controller里,
|
class ThingsController
{
var $helpers = array('Html',
'Link');
}
|
如果你计划在其他地方使用它时,记住包含数组中的HTML
helper。命名过则和model的类似。
1.
LinkHelper
=类名
2.
Helper数组里的link = key
3.
link.php
=/app/views/helpers中的PHP文件名
请考虑一下给Cake的代码-使用Trac系统或邮件列表联系一个开发人员,或创建一个新的CakeForge项目,和其他人共享你的新Helper。
Last Updated:2006-12-03