Mercurial > hg > Members > shoshi > webvirt
comparison cake/libs/view/helpers/html.php @ 0:261e66bd5a0c
hg init
author | Shoshi TAMAKI <shoshi@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 24 Jul 2011 21:08:31 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:261e66bd5a0c |
---|---|
1 <?php | |
2 /** | |
3 * Html Helper class file. | |
4 * | |
5 * Simplifies the construction of HTML elements. | |
6 * | |
7 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) | |
8 * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) | |
9 * | |
10 * Licensed under The MIT License | |
11 * Redistributions of files must retain the above copyright notice. | |
12 * | |
13 * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) | |
14 * @link http://cakephp.org CakePHP(tm) Project | |
15 * @package cake | |
16 * @subpackage cake.cake.libs.view.helpers | |
17 * @since CakePHP(tm) v 0.9.1 | |
18 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) | |
19 */ | |
20 /** | |
21 * Html Helper class for easy use of HTML widgets. | |
22 * | |
23 * HtmlHelper encloses all methods needed while working with HTML pages. | |
24 * | |
25 * @package cake | |
26 * @subpackage cake.cake.libs.view.helpers | |
27 * @link http://book.cakephp.org/view/1434/HTML | |
28 */ | |
29 class HtmlHelper extends AppHelper { | |
30 /** | |
31 * html tags used by this helper. | |
32 * | |
33 * @var array | |
34 * @access public | |
35 */ | |
36 var $tags = array( | |
37 'meta' => '<meta%s/>', | |
38 'metalink' => '<link href="%s"%s/>', | |
39 'link' => '<a href="%s"%s>%s</a>', | |
40 'mailto' => '<a href="mailto:%s" %s>%s</a>', | |
41 'form' => '<form %s>', | |
42 'formend' => '</form>', | |
43 'input' => '<input name="%s" %s/>', | |
44 'textarea' => '<textarea name="%s" %s>%s</textarea>', | |
45 'hidden' => '<input type="hidden" name="%s" %s/>', | |
46 'checkbox' => '<input type="checkbox" name="%s" %s/>', | |
47 'checkboxmultiple' => '<input type="checkbox" name="%s[]"%s />', | |
48 'radio' => '<input type="radio" name="%s" id="%s" %s />%s', | |
49 'selectstart' => '<select name="%s"%s>', | |
50 'selectmultiplestart' => '<select name="%s[]"%s>', | |
51 'selectempty' => '<option value=""%s> </option>', | |
52 'selectoption' => '<option value="%s"%s>%s</option>', | |
53 'selectend' => '</select>', | |
54 'optiongroup' => '<optgroup label="%s"%s>', | |
55 'optiongroupend' => '</optgroup>', | |
56 'checkboxmultiplestart' => '', | |
57 'checkboxmultipleend' => '', | |
58 'password' => '<input type="password" name="%s" %s/>', | |
59 'file' => '<input type="file" name="%s" %s/>', | |
60 'file_no_model' => '<input type="file" name="%s" %s/>', | |
61 'submit' => '<input %s/>', | |
62 'submitimage' => '<input type="image" src="%s" %s/>', | |
63 'button' => '<button type="%s"%s>%s</button>', | |
64 'image' => '<img src="%s" %s/>', | |
65 'tableheader' => '<th%s>%s</th>', | |
66 'tableheaderrow' => '<tr%s>%s</tr>', | |
67 'tablecell' => '<td%s>%s</td>', | |
68 'tablerow' => '<tr%s>%s</tr>', | |
69 'block' => '<div%s>%s</div>', | |
70 'blockstart' => '<div%s>', | |
71 'blockend' => '</div>', | |
72 'tag' => '<%s%s>%s</%s>', | |
73 'tagstart' => '<%s%s>', | |
74 'tagend' => '</%s>', | |
75 'para' => '<p%s>%s</p>', | |
76 'parastart' => '<p%s>', | |
77 'label' => '<label for="%s"%s>%s</label>', | |
78 'fieldset' => '<fieldset%s>%s</fieldset>', | |
79 'fieldsetstart' => '<fieldset><legend>%s</legend>', | |
80 'fieldsetend' => '</fieldset>', | |
81 'legend' => '<legend>%s</legend>', | |
82 'css' => '<link rel="%s" type="text/css" href="%s" %s/>', | |
83 'style' => '<style type="text/css"%s>%s</style>', | |
84 'charset' => '<meta http-equiv="Content-Type" content="text/html; charset=%s" />', | |
85 'ul' => '<ul%s>%s</ul>', | |
86 'ol' => '<ol%s>%s</ol>', | |
87 'li' => '<li%s>%s</li>', | |
88 'error' => '<div%s>%s</div>', | |
89 'javascriptblock' => '<script type="text/javascript"%s>%s</script>', | |
90 'javascriptstart' => '<script type="text/javascript">', | |
91 'javascriptlink' => '<script type="text/javascript" src="%s"%s></script>', | |
92 'javascriptend' => '</script>' | |
93 ); | |
94 | |
95 /** | |
96 * Breadcrumbs. | |
97 * | |
98 * @var array | |
99 * @access protected | |
100 */ | |
101 var $_crumbs = array(); | |
102 | |
103 /** | |
104 * Names of script files that have been included once | |
105 * | |
106 * @var array | |
107 * @access private | |
108 */ | |
109 var $__includedScripts = array(); | |
110 /** | |
111 * Options for the currently opened script block buffer if any. | |
112 * | |
113 * @var array | |
114 * @access protected | |
115 */ | |
116 var $_scriptBlockOptions = array(); | |
117 /** | |
118 * Document type definitions | |
119 * | |
120 * @var array | |
121 * @access private | |
122 */ | |
123 var $__docTypes = array( | |
124 'html4-strict' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">', | |
125 'html4-trans' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">', | |
126 'html4-frame' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">', | |
127 'xhtml-strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">', | |
128 'xhtml-trans' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">', | |
129 'xhtml-frame' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">', | |
130 'xhtml11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">' | |
131 ); | |
132 | |
133 /** | |
134 * Adds a link to the breadcrumbs array. | |
135 * | |
136 * @param string $name Text for link | |
137 * @param string $link URL for link (if empty it won't be a link) | |
138 * @param mixed $options Link attributes e.g. array('id'=>'selected') | |
139 * @return void | |
140 * @see HtmlHelper::link() for details on $options that can be used. | |
141 * @access public | |
142 */ | |
143 function addCrumb($name, $link = null, $options = null) { | |
144 $this->_crumbs[] = array($name, $link, $options); | |
145 } | |
146 | |
147 /** | |
148 * Returns a doctype string. | |
149 * | |
150 * Possible doctypes: | |
151 * | |
152 * - html4-strict: HTML4 Strict. | |
153 * - html4-trans: HTML4 Transitional. | |
154 * - html4-frame: HTML4 Frameset. | |
155 * - xhtml-strict: XHTML1 Strict. | |
156 * - xhtml-trans: XHTML1 Transitional. | |
157 * - xhtml-frame: XHTML1 Frameset. | |
158 * - xhtml11: XHTML1.1. | |
159 * | |
160 * @param string $type Doctype to use. | |
161 * @return string Doctype string | |
162 * @access public | |
163 * @link http://book.cakephp.org/view/1439/docType | |
164 */ | |
165 function docType($type = 'xhtml-strict') { | |
166 if (isset($this->__docTypes[$type])) { | |
167 return $this->__docTypes[$type]; | |
168 } | |
169 return null; | |
170 } | |
171 | |
172 /** | |
173 * Creates a link to an external resource and handles basic meta tags | |
174 * | |
175 * ### Options | |
176 * | |
177 * - `inline` Whether or not the link element should be output inline, or in scripts_for_layout. | |
178 * | |
179 * @param string $type The title of the external resource | |
180 * @param mixed $url The address of the external resource or string for content attribute | |
181 * @param array $options Other attributes for the generated tag. If the type attribute is html, | |
182 * rss, atom, or icon, the mime-type is returned. | |
183 * @return string A completed `<link />` element. | |
184 * @access public | |
185 * @link http://book.cakephp.org/view/1438/meta | |
186 */ | |
187 function meta($type, $url = null, $options = array()) { | |
188 $inline = isset($options['inline']) ? $options['inline'] : true; | |
189 unset($options['inline']); | |
190 | |
191 if (!is_array($type)) { | |
192 $types = array( | |
193 'rss' => array('type' => 'application/rss+xml', 'rel' => 'alternate', 'title' => $type, 'link' => $url), | |
194 'atom' => array('type' => 'application/atom+xml', 'title' => $type, 'link' => $url), | |
195 'icon' => array('type' => 'image/x-icon', 'rel' => 'icon', 'link' => $url), | |
196 'keywords' => array('name' => 'keywords', 'content' => $url), | |
197 'description' => array('name' => 'description', 'content' => $url), | |
198 ); | |
199 | |
200 if ($type === 'icon' && $url === null) { | |
201 $types['icon']['link'] = $this->webroot('favicon.ico'); | |
202 } | |
203 | |
204 if (isset($types[$type])) { | |
205 $type = $types[$type]; | |
206 } elseif (!isset($options['type']) && $url !== null) { | |
207 if (is_array($url) && isset($url['ext'])) { | |
208 $type = $types[$url['ext']]; | |
209 } else { | |
210 $type = $types['rss']; | |
211 } | |
212 } elseif (isset($options['type']) && isset($types[$options['type']])) { | |
213 $type = $types[$options['type']]; | |
214 unset($options['type']); | |
215 } else { | |
216 $type = array(); | |
217 } | |
218 } elseif ($url !== null) { | |
219 $inline = $url; | |
220 } | |
221 $options = array_merge($type, $options); | |
222 $out = null; | |
223 | |
224 if (isset($options['link'])) { | |
225 if (isset($options['rel']) && $options['rel'] === 'icon') { | |
226 $out = sprintf($this->tags['metalink'], $options['link'], $this->_parseAttributes($options, array('link'), ' ', ' ')); | |
227 $options['rel'] = 'shortcut icon'; | |
228 } else { | |
229 $options['link'] = $this->url($options['link'], true); | |
230 } | |
231 $out .= sprintf($this->tags['metalink'], $options['link'], $this->_parseAttributes($options, array('link'), ' ', ' ')); | |
232 } else { | |
233 $out = sprintf($this->tags['meta'], $this->_parseAttributes($options, array('type'), ' ', ' ')); | |
234 } | |
235 | |
236 if ($inline) { | |
237 return $out; | |
238 } else { | |
239 $view =& ClassRegistry::getObject('view'); | |
240 $view->addScript($out); | |
241 } | |
242 } | |
243 | |
244 /** | |
245 * Returns a charset META-tag. | |
246 * | |
247 * @param string $charset The character set to be used in the meta tag. If empty, | |
248 * The App.encoding value will be used. Example: "utf-8". | |
249 * @return string A meta tag containing the specified character set. | |
250 * @access public | |
251 * @link http://book.cakephp.org/view/1436/charset | |
252 */ | |
253 function charset($charset = null) { | |
254 if (empty($charset)) { | |
255 $charset = strtolower(Configure::read('App.encoding')); | |
256 } | |
257 return sprintf($this->tags['charset'], (!empty($charset) ? $charset : 'utf-8')); | |
258 } | |
259 | |
260 /** | |
261 * Creates an HTML link. | |
262 * | |
263 * If $url starts with "http://" this is treated as an external link. Else, | |
264 * it is treated as a path to controller/action and parsed with the | |
265 * HtmlHelper::url() method. | |
266 * | |
267 * If the $url is empty, $title is used instead. | |
268 * | |
269 * ### Options | |
270 * | |
271 * - `escape` Set to false to disable escaping of title and attributes. | |
272 * | |
273 * @param string $title The content to be wrapped by <a> tags. | |
274 * @param mixed $url Cake-relative URL or array of URL parameters, or external URL (starts with http://) | |
275 * @param array $options Array of HTML attributes. | |
276 * @param string $confirmMessage JavaScript confirmation message. | |
277 * @return string An `<a />` element. | |
278 * @access public | |
279 * @link http://book.cakephp.org/view/1442/link | |
280 */ | |
281 function link($title, $url = null, $options = array(), $confirmMessage = false) { | |
282 $escapeTitle = true; | |
283 if ($url !== null) { | |
284 $url = $this->url($url); | |
285 } else { | |
286 $url = $this->url($title); | |
287 $title = $url; | |
288 $escapeTitle = false; | |
289 } | |
290 | |
291 if (isset($options['escape'])) { | |
292 $escapeTitle = $options['escape']; | |
293 } | |
294 | |
295 if ($escapeTitle === true) { | |
296 $title = h($title); | |
297 } elseif (is_string($escapeTitle)) { | |
298 $title = htmlentities($title, ENT_QUOTES, $escapeTitle); | |
299 } | |
300 | |
301 if (!empty($options['confirm'])) { | |
302 $confirmMessage = $options['confirm']; | |
303 unset($options['confirm']); | |
304 } | |
305 if ($confirmMessage) { | |
306 $confirmMessage = str_replace("'", "\'", $confirmMessage); | |
307 $confirmMessage = str_replace('"', '\"', $confirmMessage); | |
308 $options['onclick'] = "return confirm('{$confirmMessage}');"; | |
309 } elseif (isset($options['default']) && $options['default'] == false) { | |
310 if (isset($options['onclick'])) { | |
311 $options['onclick'] .= ' event.returnValue = false; return false;'; | |
312 } else { | |
313 $options['onclick'] = 'event.returnValue = false; return false;'; | |
314 } | |
315 unset($options['default']); | |
316 } | |
317 return sprintf($this->tags['link'], $url, $this->_parseAttributes($options), $title); | |
318 } | |
319 | |
320 /** | |
321 * Creates a link element for CSS stylesheets. | |
322 * | |
323 * ### Options | |
324 * | |
325 * - `inline` If set to false, the generated tag appears in the head tag of the layout. Defaults to true | |
326 * | |
327 * @param mixed $path The name of a CSS style sheet or an array containing names of | |
328 * CSS stylesheets. If `$path` is prefixed with '/', the path will be relative to the webroot | |
329 * of your application. Otherwise, the path will be relative to your CSS path, usually webroot/css. | |
330 * @param string $rel Rel attribute. Defaults to "stylesheet". If equal to 'import' the stylesheet will be imported. | |
331 * @param array $options Array of HTML attributes. | |
332 * @return string CSS <link /> or <style /> tag, depending on the type of link. | |
333 * @access public | |
334 * @link http://book.cakephp.org/view/1437/css | |
335 */ | |
336 function css($path, $rel = null, $options = array()) { | |
337 $options += array('inline' => true); | |
338 if (is_array($path)) { | |
339 $out = ''; | |
340 foreach ($path as $i) { | |
341 $out .= "\n\t" . $this->css($i, $rel, $options); | |
342 } | |
343 if ($options['inline']) { | |
344 return $out . "\n"; | |
345 } | |
346 return; | |
347 } | |
348 | |
349 if (strpos($path, '://') !== false) { | |
350 $url = $path; | |
351 } else { | |
352 if ($path[0] !== '/') { | |
353 $path = CSS_URL . $path; | |
354 } | |
355 | |
356 if (strpos($path, '?') === false) { | |
357 if (substr($path, -4) !== '.css') { | |
358 $path .= '.css'; | |
359 } | |
360 } | |
361 $url = $this->assetTimestamp($this->webroot($path)); | |
362 | |
363 if (Configure::read('Asset.filter.css')) { | |
364 $pos = strpos($url, CSS_URL); | |
365 if ($pos !== false) { | |
366 $url = substr($url, 0, $pos) . 'ccss/' . substr($url, $pos + strlen(CSS_URL)); | |
367 } | |
368 } | |
369 } | |
370 | |
371 if ($rel == 'import') { | |
372 $out = sprintf($this->tags['style'], $this->_parseAttributes($options, array('inline'), '', ' '), '@import url(' . $url . ');'); | |
373 } else { | |
374 if ($rel == null) { | |
375 $rel = 'stylesheet'; | |
376 } | |
377 $out = sprintf($this->tags['css'], $rel, $url, $this->_parseAttributes($options, array('inline'), '', ' ')); | |
378 } | |
379 | |
380 if ($options['inline']) { | |
381 return $out; | |
382 } else { | |
383 $view =& ClassRegistry::getObject('view'); | |
384 $view->addScript($out); | |
385 } | |
386 } | |
387 | |
388 /** | |
389 * Returns one or many `<script>` tags depending on the number of scripts given. | |
390 * | |
391 * If the filename is prefixed with "/", the path will be relative to the base path of your | |
392 * application. Otherwise, the path will be relative to your JavaScript path, usually webroot/js. | |
393 * | |
394 * Can include one or many Javascript files. | |
395 * | |
396 * ### Options | |
397 * | |
398 * - `inline` - Whether script should be output inline or into scripts_for_layout. | |
399 * - `once` - Whether or not the script should be checked for uniqueness. If true scripts will only be | |
400 * included once, use false to allow the same script to be included more than once per request. | |
401 * | |
402 * @param mixed $url String or array of javascript files to include | |
403 * @param mixed $options Array of options, and html attributes see above. If boolean sets $options['inline'] = value | |
404 * @return mixed String of `<script />` tags or null if $inline is false or if $once is true and the file has been | |
405 * included before. | |
406 * @access public | |
407 * @link http://book.cakephp.org/view/1589/script | |
408 */ | |
409 function script($url, $options = array()) { | |
410 if (is_bool($options)) { | |
411 list($inline, $options) = array($options, array()); | |
412 $options['inline'] = $inline; | |
413 } | |
414 $options = array_merge(array('inline' => true, 'once' => true), $options); | |
415 if (is_array($url)) { | |
416 $out = ''; | |
417 foreach ($url as $i) { | |
418 $out .= "\n\t" . $this->script($i, $options); | |
419 } | |
420 if ($options['inline']) { | |
421 return $out . "\n"; | |
422 } | |
423 return null; | |
424 } | |
425 if ($options['once'] && isset($this->__includedScripts[$url])) { | |
426 return null; | |
427 } | |
428 $this->__includedScripts[$url] = true; | |
429 | |
430 if (strpos($url, '://') === false) { | |
431 if ($url[0] !== '/') { | |
432 $url = JS_URL . $url; | |
433 } | |
434 if (strpos($url, '?') === false && substr($url, -3) !== '.js') { | |
435 $url .= '.js'; | |
436 } | |
437 $url = $this->assetTimestamp($this->webroot($url)); | |
438 | |
439 if (Configure::read('Asset.filter.js')) { | |
440 $url = str_replace(JS_URL, 'cjs/', $url); | |
441 } | |
442 } | |
443 $attributes = $this->_parseAttributes($options, array('inline', 'once'), ' '); | |
444 $out = sprintf($this->tags['javascriptlink'], $url, $attributes); | |
445 | |
446 if ($options['inline']) { | |
447 return $out; | |
448 } else { | |
449 $view =& ClassRegistry::getObject('view'); | |
450 $view->addScript($out); | |
451 } | |
452 } | |
453 | |
454 /** | |
455 * Wrap $script in a script tag. | |
456 * | |
457 * ### Options | |
458 * | |
459 * - `safe` (boolean) Whether or not the $script should be wrapped in <![CDATA[ ]]> | |
460 * - `inline` (boolean) Whether or not the $script should be added to $scripts_for_layout or output inline | |
461 * | |
462 * @param string $script The script to wrap | |
463 * @param array $options The options to use. | |
464 * @return mixed string or null depending on the value of `$options['inline']` | |
465 * @access public | |
466 * @link http://book.cakephp.org/view/1604/scriptBlock | |
467 */ | |
468 function scriptBlock($script, $options = array()) { | |
469 $options += array('safe' => true, 'inline' => true); | |
470 if ($options['safe']) { | |
471 $script = "\n" . '//<![CDATA[' . "\n" . $script . "\n" . '//]]>' . "\n"; | |
472 } | |
473 $inline = $options['inline']; | |
474 unset($options['inline'], $options['safe']); | |
475 $attributes = $this->_parseAttributes($options, ' ', ' '); | |
476 if ($inline) { | |
477 return sprintf($this->tags['javascriptblock'], $attributes, $script); | |
478 } else { | |
479 $view =& ClassRegistry::getObject('view'); | |
480 $view->addScript(sprintf($this->tags['javascriptblock'], $attributes, $script)); | |
481 return null; | |
482 } | |
483 } | |
484 | |
485 /** | |
486 * Begin a script block that captures output until HtmlHelper::scriptEnd() | |
487 * is called. This capturing block will capture all output between the methods | |
488 * and create a scriptBlock from it. | |
489 * | |
490 * ### Options | |
491 * | |
492 * - `safe` Whether the code block should contain a CDATA | |
493 * - `inline` Should the generated script tag be output inline or in `$scripts_for_layout` | |
494 * | |
495 * @param array $options Options for the code block. | |
496 * @return void | |
497 * @access public | |
498 * @link http://book.cakephp.org/view/1605/scriptStart | |
499 */ | |
500 function scriptStart($options = array()) { | |
501 $options += array('safe' => true, 'inline' => true); | |
502 $this->_scriptBlockOptions = $options; | |
503 ob_start(); | |
504 return null; | |
505 } | |
506 | |
507 /** | |
508 * End a Buffered section of Javascript capturing. | |
509 * Generates a script tag inline or in `$scripts_for_layout` depending on the settings | |
510 * used when the scriptBlock was started | |
511 * | |
512 * @return mixed depending on the settings of scriptStart() either a script tag or null | |
513 * @access public | |
514 * @link http://book.cakephp.org/view/1606/scriptEnd | |
515 */ | |
516 function scriptEnd() { | |
517 $buffer = ob_get_clean(); | |
518 $options = $this->_scriptBlockOptions; | |
519 $this->_scriptBlockOptions = array(); | |
520 return $this->scriptBlock($buffer, $options); | |
521 } | |
522 | |
523 /** | |
524 * Builds CSS style data from an array of CSS properties | |
525 * | |
526 * ### Usage: | |
527 * | |
528 * {{{ | |
529 * echo $html->style(array('margin' => '10px', 'padding' => '10px'), true); | |
530 * | |
531 * // creates | |
532 * 'margin:10px;padding:10px;' | |
533 * }}} | |
534 * | |
535 * @param array $data Style data array, keys will be used as property names, values as property values. | |
536 * @param boolean $oneline Whether or not the style block should be displayed on one line. | |
537 * @return string CSS styling data | |
538 * @access public | |
539 * @link http://book.cakephp.org/view/1440/style | |
540 */ | |
541 function style($data, $oneline = true) { | |
542 if (!is_array($data)) { | |
543 return $data; | |
544 } | |
545 $out = array(); | |
546 foreach ($data as $key=> $value) { | |
547 $out[] = $key.':'.$value.';'; | |
548 } | |
549 if ($oneline) { | |
550 return join(' ', $out); | |
551 } | |
552 return implode("\n", $out); | |
553 } | |
554 | |
555 /** | |
556 * Returns the breadcrumb trail as a sequence of »-separated links. | |
557 * | |
558 * @param string $separator Text to separate crumbs. | |
559 * @param string $startText This will be the first crumb, if false it defaults to first crumb in array | |
560 * @return string Composed bread crumbs | |
561 * @access public | |
562 */ | |
563 function getCrumbs($separator = '»', $startText = false) { | |
564 if (!empty($this->_crumbs)) { | |
565 $out = array(); | |
566 if ($startText) { | |
567 $out[] = $this->link($startText, '/'); | |
568 } | |
569 | |
570 foreach ($this->_crumbs as $crumb) { | |
571 if (!empty($crumb[1])) { | |
572 $out[] = $this->link($crumb[0], $crumb[1], $crumb[2]); | |
573 } else { | |
574 $out[] = $crumb[0]; | |
575 } | |
576 } | |
577 return join($separator, $out); | |
578 } else { | |
579 return null; | |
580 } | |
581 } | |
582 | |
583 /** | |
584 * Creates a formatted IMG element. If `$options['url']` is provided, an image link will be | |
585 * generated with the link pointed at `$options['url']`. This method will set an empty | |
586 * alt attribute if one is not supplied. | |
587 * | |
588 * ### Usage | |
589 * | |
590 * Create a regular image: | |
591 * | |
592 * `echo $html->image('cake_icon.png', array('alt' => 'CakePHP'));` | |
593 * | |
594 * Create an image link: | |
595 * | |
596 * `echo $html->image('cake_icon.png', array('alt' => 'CakePHP', 'url' => 'http://cakephp.org'));` | |
597 * | |
598 * @param string $path Path to the image file, relative to the app/webroot/img/ directory. | |
599 * @param array $options Array of HTML attributes. | |
600 * @return string completed img tag | |
601 * @access public | |
602 * @link http://book.cakephp.org/view/1441/image | |
603 */ | |
604 function image($path, $options = array()) { | |
605 if (is_array($path)) { | |
606 $path = $this->url($path); | |
607 } elseif (strpos($path, '://') === false) { | |
608 if ($path[0] !== '/') { | |
609 $path = IMAGES_URL . $path; | |
610 } | |
611 $path = $this->assetTimestamp($this->webroot($path)); | |
612 } | |
613 | |
614 if (!isset($options['alt'])) { | |
615 $options['alt'] = ''; | |
616 } | |
617 | |
618 $url = false; | |
619 if (!empty($options['url'])) { | |
620 $url = $options['url']; | |
621 unset($options['url']); | |
622 } | |
623 | |
624 $image = sprintf($this->tags['image'], $path, $this->_parseAttributes($options, null, '', ' ')); | |
625 | |
626 if ($url) { | |
627 return sprintf($this->tags['link'], $this->url($url), null, $image); | |
628 } | |
629 return $image; | |
630 } | |
631 | |
632 /** | |
633 * Returns a row of formatted and named TABLE headers. | |
634 * | |
635 * @param array $names Array of tablenames. | |
636 * @param array $trOptions HTML options for TR elements. | |
637 * @param array $thOptions HTML options for TH elements. | |
638 * @return string Completed table headers | |
639 * @access public | |
640 * @link http://book.cakephp.org/view/1446/tableHeaders | |
641 */ | |
642 function tableHeaders($names, $trOptions = null, $thOptions = null) { | |
643 $out = array(); | |
644 foreach ($names as $arg) { | |
645 $out[] = sprintf($this->tags['tableheader'], $this->_parseAttributes($thOptions), $arg); | |
646 } | |
647 return sprintf($this->tags['tablerow'], $this->_parseAttributes($trOptions), join(' ', $out)); | |
648 } | |
649 | |
650 /** | |
651 * Returns a formatted string of table rows (TR's with TD's in them). | |
652 * | |
653 * @param array $data Array of table data | |
654 * @param array $oddTrOptions HTML options for odd TR elements if true useCount is used | |
655 * @param array $evenTrOptions HTML options for even TR elements | |
656 * @param bool $useCount adds class "column-$i" | |
657 * @param bool $continueOddEven If false, will use a non-static $count variable, | |
658 * so that the odd/even count is reset to zero just for that call. | |
659 * @return string Formatted HTML | |
660 * @access public | |
661 * @link http://book.cakephp.org/view/1447/tableCells | |
662 */ | |
663 function tableCells($data, $oddTrOptions = null, $evenTrOptions = null, $useCount = false, $continueOddEven = true) { | |
664 if (empty($data[0]) || !is_array($data[0])) { | |
665 $data = array($data); | |
666 } | |
667 | |
668 if ($oddTrOptions === true) { | |
669 $useCount = true; | |
670 $oddTrOptions = null; | |
671 } | |
672 | |
673 if ($evenTrOptions === false) { | |
674 $continueOddEven = false; | |
675 $evenTrOptions = null; | |
676 } | |
677 | |
678 if ($continueOddEven) { | |
679 static $count = 0; | |
680 } else { | |
681 $count = 0; | |
682 } | |
683 | |
684 foreach ($data as $line) { | |
685 $count++; | |
686 $cellsOut = array(); | |
687 $i = 0; | |
688 foreach ($line as $cell) { | |
689 $cellOptions = array(); | |
690 | |
691 if (is_array($cell)) { | |
692 $cellOptions = $cell[1]; | |
693 $cell = $cell[0]; | |
694 } elseif ($useCount) { | |
695 $cellOptions['class'] = 'column-' . ++$i; | |
696 } | |
697 $cellsOut[] = sprintf($this->tags['tablecell'], $this->_parseAttributes($cellOptions), $cell); | |
698 } | |
699 $options = $this->_parseAttributes($count % 2 ? $oddTrOptions : $evenTrOptions); | |
700 $out[] = sprintf($this->tags['tablerow'], $options, implode(' ', $cellsOut)); | |
701 } | |
702 return implode("\n", $out); | |
703 } | |
704 | |
705 /** | |
706 * Returns a formatted block tag, i.e DIV, SPAN, P. | |
707 * | |
708 * ### Options | |
709 * | |
710 * - `escape` Whether or not the contents should be html_entity escaped. | |
711 * | |
712 * @param string $name Tag name. | |
713 * @param string $text String content that will appear inside the div element. | |
714 * If null, only a start tag will be printed | |
715 * @param array $options Additional HTML attributes of the DIV tag, see above. | |
716 * @return string The formatted tag element | |
717 * @access public | |
718 * @link http://book.cakephp.org/view/1443/tag | |
719 */ | |
720 function tag($name, $text = null, $options = array()) { | |
721 if (is_array($options) && isset($options['escape']) && $options['escape']) { | |
722 $text = h($text); | |
723 unset($options['escape']); | |
724 } | |
725 if (!is_array($options)) { | |
726 $options = array('class' => $options); | |
727 } | |
728 if ($text === null) { | |
729 $tag = 'tagstart'; | |
730 } else { | |
731 $tag = 'tag'; | |
732 } | |
733 return sprintf($this->tags[$tag], $name, $this->_parseAttributes($options, null, ' ', ''), $text, $name); | |
734 } | |
735 | |
736 /** | |
737 * Returns a formatted DIV tag for HTML FORMs. | |
738 * | |
739 * ### Options | |
740 * | |
741 * - `escape` Whether or not the contents should be html_entity escaped. | |
742 * | |
743 * @param string $class CSS class name of the div element. | |
744 * @param string $text String content that will appear inside the div element. | |
745 * If null, only a start tag will be printed | |
746 * @param array $options Additional HTML attributes of the DIV tag | |
747 * @return string The formatted DIV element | |
748 * @access public | |
749 * @link http://book.cakephp.org/view/1444/div | |
750 */ | |
751 function div($class = null, $text = null, $options = array()) { | |
752 if (!empty($class)) { | |
753 $options['class'] = $class; | |
754 } | |
755 return $this->tag('div', $text, $options); | |
756 } | |
757 | |
758 /** | |
759 * Returns a formatted P tag. | |
760 * | |
761 * ### Options | |
762 * | |
763 * - `escape` Whether or not the contents should be html_entity escaped. | |
764 * | |
765 * @param string $class CSS class name of the p element. | |
766 * @param string $text String content that will appear inside the p element. | |
767 * @param array $options Additional HTML attributes of the P tag | |
768 * @return string The formatted P element | |
769 * @access public | |
770 * @link http://book.cakephp.org/view/1445/para | |
771 */ | |
772 function para($class, $text, $options = array()) { | |
773 if (isset($options['escape'])) { | |
774 $text = h($text); | |
775 } | |
776 if ($class != null && !empty($class)) { | |
777 $options['class'] = $class; | |
778 } | |
779 if ($text === null) { | |
780 $tag = 'parastart'; | |
781 } else { | |
782 $tag = 'para'; | |
783 } | |
784 return sprintf($this->tags[$tag], $this->_parseAttributes($options, null, ' ', ''), $text); | |
785 } | |
786 | |
787 /** | |
788 * Build a nested list (UL/OL) out of an associative array. | |
789 * | |
790 * @param array $list Set of elements to list | |
791 * @param array $options Additional HTML attributes of the list (ol/ul) tag or if ul/ol use that as tag | |
792 * @param array $itemOptions Additional HTML attributes of the list item (LI) tag | |
793 * @param string $tag Type of list tag to use (ol/ul) | |
794 * @return string The nested list | |
795 * @access public | |
796 */ | |
797 function nestedList($list, $options = array(), $itemOptions = array(), $tag = 'ul') { | |
798 if (is_string($options)) { | |
799 $tag = $options; | |
800 $options = array(); | |
801 } | |
802 $items = $this->__nestedListItem($list, $options, $itemOptions, $tag); | |
803 return sprintf($this->tags[$tag], $this->_parseAttributes($options, null, ' ', ''), $items); | |
804 } | |
805 | |
806 /** | |
807 * Internal function to build a nested list (UL/OL) out of an associative array. | |
808 * | |
809 * @param array $items Set of elements to list | |
810 * @param array $options Additional HTML attributes of the list (ol/ul) tag | |
811 * @param array $itemOptions Additional HTML attributes of the list item (LI) tag | |
812 * @param string $tag Type of list tag to use (ol/ul) | |
813 * @return string The nested list element | |
814 * @access private | |
815 * @see HtmlHelper::nestedList() | |
816 */ | |
817 function __nestedListItem($items, $options, $itemOptions, $tag) { | |
818 $out = ''; | |
819 | |
820 $index = 1; | |
821 foreach ($items as $key => $item) { | |
822 if (is_array($item)) { | |
823 $item = $key . $this->nestedList($item, $options, $itemOptions, $tag); | |
824 } | |
825 if (isset($itemOptions['even']) && $index % 2 == 0) { | |
826 $itemOptions['class'] = $itemOptions['even']; | |
827 } else if (isset($itemOptions['odd']) && $index % 2 != 0) { | |
828 $itemOptions['class'] = $itemOptions['odd']; | |
829 } | |
830 $out .= sprintf($this->tags['li'], $this->_parseAttributes($itemOptions, array('even', 'odd'), ' ', ''), $item); | |
831 $index++; | |
832 } | |
833 return $out; | |
834 } | |
835 } |