PageRenderTime 39ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/lithium-0.6/libraries/lithium/template/helper/Html.php

https://github.com/gwoo/framework-benchs
PHP | 361 lines | 196 code | 29 blank | 136 comment | 14 complexity | 1b6087adc37d231221ea6b1d0e085219 MD5 | raw file
  1. <?php
  2. /**
  3. * Lithium: the most rad php framework
  4. *
  5. * @copyright Copyright 2010, Union of RAD (http://union-of-rad.org)
  6. * @license http://opensource.org/licenses/bsd-license.php The BSD License
  7. */
  8. namespace lithium\template\helper;
  9. /**
  10. * A template helper that assists in generating HTML content. Accessible in templates via
  11. * `$this->html`, which will auto-load this helper into the rendering context. For examples of how
  12. * to use this helper, see the documentation for a specific method. For a list of the
  13. * template strings this helper uses, see the `$_strings` property.
  14. */
  15. class Html extends \lithium\template\Helper {
  16. /**
  17. * String templates used by this helper.
  18. *
  19. * @var array
  20. */
  21. protected $_strings = array(
  22. 'block' => '<div{:options}>{:content}</div>',
  23. 'block-end' => '</div>',
  24. 'block-start' => '<div{:options}>',
  25. 'charset' => '<meta http-equiv="Content-Type" content="{:type}; charset={:charset}" />',
  26. 'doctype' => '<!DOCTYPE {:version} PUBLIC "{:dtd}" "{:url}">',
  27. 'image' => '<img src="{:path}"{:options} />',
  28. 'js-block' => '<script type="text/javascript"{:options}>{:content}</script>',
  29. 'js-end' => '</script>',
  30. 'js-start' => '<script type="text/javascript"{:options}>',
  31. 'link' => '<a href="{:url}"{:options}>{:title}</a>',
  32. 'list' => '<ul{:options}>{:content}</ul>',
  33. 'list-item' => '<li{:options}>{:content}</li>',
  34. 'meta' => '<meta{:options}/>',
  35. 'meta-link' => '<link href="{:url}"{:options} />',
  36. 'para' => '<p{:options}>{:content}</p>',
  37. 'para-start' => '<p{:options}>',
  38. 'script' => '<script type="text/javascript" src="{:path}"{:options}></script>',
  39. 'style' => '<style type="text/css"{:options}>{:content}</style>',
  40. 'style-import' => '<style type="text/css"{:options}>@import url({:url});</style>',
  41. 'style-link' => '<link rel="{:type}" type="text/css" href="{:path}"{:options} />',
  42. 'table-header' => '<th{:options}>{:content}</th>',
  43. 'table-header-row' => '<tr{:options}>{:content}</tr>',
  44. 'table-cell' => '<td{:options}>{:content}</td>',
  45. 'table-row' => '<tr{:options}>{:content}</tr>',
  46. 'tag' => '<{:name}{:options}>{:content}</{:name}>',
  47. 'tag-end' => '</{:name}>',
  48. 'tag-start' => '<{:name}{:options}>'
  49. );
  50. /**
  51. * Document type definitions
  52. *
  53. * @var array
  54. */
  55. protected $_docTypes = array(
  56. 'html4-strict' => array(
  57. 'version' => 'HTML',
  58. 'dtd' => '-//W3C//DTD HTML 4.01//EN',
  59. 'url' => 'http://www.w3.org/TR/html4/strict.dtd'
  60. ),
  61. 'html4-trans' => array(
  62. 'version' => 'HTML',
  63. 'dtd' => '-//W3C//DTD HTML 4.01 Transitional//EN',
  64. 'url' => 'http://www.w3.org/TR/html4/loose.dtd'
  65. ),
  66. 'html4-frame' => array(
  67. 'version' => 'HTML',
  68. 'dtd' => '-//W3C//DTD HTML 4.01 Frameset//EN',
  69. 'url' => 'http://www.w3.org/TR/html4/frameset.dtd'
  70. ),
  71. 'xhtml-strict' => array(
  72. 'version' => 'html',
  73. 'dtd' => '-//W3C//DTD XHTML 1.0 Strict//EN',
  74. 'url' => 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'
  75. ),
  76. 'xhtml-trans' => array(
  77. 'version' => 'html',
  78. 'dtd' => '-//W3C//DTD XHTML 1.0 Transitional//EN',
  79. 'url' => 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'
  80. ),
  81. 'xhtml-frame' => array(
  82. 'version' => 'html',
  83. 'dtd' => '-//W3C//DTD XHTML 1.0 Frameset//EN',
  84. 'url' => 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd'
  85. ),
  86. 'xhtml11' => array(
  87. 'version' => 'html',
  88. 'dtd' => '-//W3C//DTD XHTML 1.1//EN',
  89. 'url' => 'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd'
  90. )
  91. );
  92. /**
  93. * Data used for custom <meta /> links.
  94. *
  95. * @var array
  96. */
  97. protected $_metaLinks = array(
  98. 'atom' => array('type' => 'application/atom+xml', 'rel' => 'alternate'),
  99. 'rss' => array('type' => 'application/rss+xml', 'rel' => 'alternate'),
  100. 'icon' => array('type' => 'image/x-icon', 'rel' => 'icon')
  101. );
  102. /**
  103. * Used by output handlers to calculate asset paths in conjunction with the `Media` class.
  104. *
  105. * @var array
  106. * @see lithium\net\http\Media
  107. */
  108. public $contentMap = array(
  109. 'script' => 'js',
  110. 'style' => 'css',
  111. 'image' => 'image',
  112. '_metaLink' => 'generic'
  113. );
  114. /**
  115. * Returns a doctype string.
  116. *
  117. * Possible doctypes:
  118. *
  119. * - `html4-strict`: HTML4 Strict.
  120. * - `html4-trans`: HTML4 Transitional.
  121. * - `html4-frame`: HTML4 Frameset.
  122. * - `xhtml-strict`: XHTML1 Strict.
  123. * - `xhtml-trans`: XHTML1 Transitional.
  124. * - `xhtml-frame`: XHTML1 Frameset.
  125. * - `xhtml11`: XHTML1.1
  126. *
  127. * Note that the HTML5 doctype has been omitted, because the doctype tag is simply
  128. * `<!doctype html>`.
  129. *
  130. * @param string $type Doctype to use.
  131. * @return string An HTML doctype tag.
  132. */
  133. public function docType($type = 'xhtml-trans') {
  134. if (isset($this->_docTypes[$type])) {
  135. return $this->_render(__METHOD__, 'doctype', $this->_docTypes[$type]);
  136. }
  137. }
  138. /**
  139. * Returns a charset meta-tag.
  140. *
  141. * @param string $charset The character set to be used in the meta tag. Example: `"utf-8"`.
  142. * @return string A meta tag containing the specified character set.
  143. */
  144. public function charset($charset = null) {
  145. $options = array('type' => 'text/html');
  146. $options['charset'] = $charset ?: 'utf-8';
  147. return $this->_render(__METHOD__, 'charset', $options);
  148. }
  149. /**
  150. * Creates an HTML link (`<a />`) or a document meta-link (`<link />`).
  151. *
  152. * If `$url` starts with `"http://"` or `"https://"`, this is treated as an external link.
  153. * Otherwise, it is treated as a path to controller/action and parsed using
  154. * the `Router::match()` method (where `Router` is the routing class dependency specified by
  155. * the rendering context, i.e. `lithium\template\view\Renderer::$_classes`).
  156. *
  157. * If `$url` is empty, `$title` is used in its place.
  158. *
  159. * @param string $title The content to be wrapped by an `<a />` tag.
  160. * @param mixed $url Can be a string representing a URL relative to the base of your Lithium
  161. * applcation, an external URL (starts with `'http://'` or `'https://'`), an anchor
  162. * name starting with `'#'` (i.e. `'#top'`), or an array defining a set of request
  163. * parameters that should be matched against a route in `Router`.
  164. * @param array $options Array of HTML attributes.
  165. * @return string Returns an `<a />` or `<link />` element.
  166. */
  167. public function link($title, $url = null, $options = array()) {
  168. $defaults = array('escape' => true);
  169. $options += $defaults;
  170. if (isset($options['type']) && $type = $options['type']) {
  171. unset($options['type']);
  172. $options = array_diff_key($options, $defaults) + compact('title');
  173. return $this->_metaLink($type, $url, $options);
  174. }
  175. $url = is_null($url) ? $title : $url;
  176. $params = $options;
  177. $options = array_diff_key($options, $defaults);
  178. return $this->_render(__METHOD__, 'link', compact('title', 'url', 'options'), $params);
  179. }
  180. /**
  181. * Returns a JavaScript include tag (`<script />` element). If the filename is prefixed with
  182. * `"/"`, the path will be relative to the base path of your application. Otherwise, the path
  183. * will be relative to your JavaScript path, usually `webroot/js`.
  184. *
  185. * @param mixed $path String path to JavaScript file, or an array of paths.
  186. * @param array $options
  187. * @return string
  188. */
  189. public function script($path, $options = array()) {
  190. $defaults = array('inline' => true);
  191. $options += $defaults;
  192. $m = __METHOD__;
  193. if (is_array($path)) {
  194. $result = join("\n\t", array_map(array(&$this, __FUNCTION__), $path));
  195. return ($options['inline']) ? $result . "\n" : null;
  196. }
  197. $params = compact('path') + array('options' => array_diff_key($options, $defaults));
  198. $script = $this->_filter(__METHOD__, $params, function($self, $params, $chain) use ($m) {
  199. return $self->invokeMethod('_render', array($m, 'script', $params));
  200. });
  201. if ($options['inline']) {
  202. return $script;
  203. }
  204. if ($this->_context) {
  205. $this->_context->scripts($script);
  206. }
  207. }
  208. /**
  209. * Creates a link element for CSS stylesheets.
  210. *
  211. * @param mixed $path The name of a CSS style sheet in `/app/webroot/css`, or an array
  212. * containing names of CSS stylesheets in that directory.
  213. * @param array $options Array of HTML attributes.
  214. * @return string CSS <link /> or <style /> tag, depending on the type of link.
  215. * @filter This method can be filtered.
  216. */
  217. public function style($path, $options = array()) {
  218. $defaults = array('type' => 'stylesheet', 'inline' => true);
  219. $options += $defaults;
  220. if (is_array($path)) {
  221. $result = join("\n\t", array_map(array(&$this, __FUNCTION__), $path));
  222. return ($options['inline']) ? $result . "\n" : null;
  223. }
  224. $params = compact('path', 'options');
  225. $method = __METHOD__;
  226. $filter = function($self, $params, $chain) use ($defaults, $method) {
  227. extract($params);
  228. $type = $options['type'];
  229. $options = array_diff_key($options, $defaults);
  230. $template = ($type == 'import') ? 'style-import' : 'style-link';
  231. $params = compact('type', 'path', 'options');
  232. return $self->invokeMethod('_render', array($method, $template, $params));
  233. };
  234. $style = $this->_filter(__METHOD__, $params, $filter);
  235. if ($options['inline']) {
  236. return $style;
  237. }
  238. if ($this->_context) {
  239. $this->_context->styles($style);
  240. }
  241. }
  242. /**
  243. * Creates a formatted <img /> element.
  244. *
  245. * @param string $path Path to the image file, relative to the app/webroot/img/ directory.
  246. * @param array $options Array of HTML attributes.
  247. * @return string
  248. */
  249. public function image($path, $options = array()) {
  250. $defaults = array('alt' => '');
  251. $options += $defaults;
  252. $path = is_array($path) ? $this->_context->url($path) : $path;
  253. $params = compact('path', 'options');
  254. $method = __METHOD__;
  255. return $this->_filter($method, $params, function($self, $params, $chain) use ($method) {
  256. return $self->invokeMethod('_render', array($method, 'image', $params));
  257. });
  258. }
  259. /**
  260. * Returns a formatted block tag, i.e <div />, <span />, <p />.
  261. *
  262. * @param string $name Tag name.
  263. * @param string $content String content that will appear inside the div element.
  264. * If null, only a start tag will be printed
  265. * @param array $options Additional HTML attributes of the DIV tag
  266. * @return string The formatted tag element
  267. */
  268. function tag($name, $content = null, $options = array()) {
  269. $options = is_array($options) ? $options : array('class' => $options);
  270. return $this->_render(__METHOD__, ($content === null) ? 'tag-start' : 'tag', compact(
  271. 'name', 'options', 'content'
  272. ));
  273. }
  274. /**
  275. * Returns a formatted DIV tag for HTML FORMs.
  276. *
  277. * @param string $class CSS class name of the div element.
  278. * @param string $content String content that will appear inside the div element.
  279. * If null, only a start tag will be printed
  280. * @param array $options Additional HTML attributes of the DIV tag
  281. * @return string The formatted DIV element
  282. */
  283. function block($class = null, $content = null, $options = array()) {
  284. if ($class) {
  285. $options['class'] = $class;
  286. }
  287. return $this->_render(__METHOD__, 'block', compact('content', 'options'));
  288. }
  289. /**
  290. * Returns a formatted P tag.
  291. *
  292. * @param string $class CSS class name of the p element.
  293. * @param string $content String content that will appear inside the p element.
  294. * @param array $options Additional HTML attributes of the P tag
  295. * @return string The formatted P element
  296. */
  297. function para($class, $content, $options = array()) {
  298. if ($class) {
  299. $options['class'] = $class;
  300. }
  301. return $this->_render(__METHOD__, ($content === null) ? 'para-start' : 'para', compact(
  302. 'content', 'options'
  303. ));
  304. }
  305. /**
  306. * Creates a link to an external resource.
  307. *
  308. * @param string $type The title of the external resource
  309. * @param mixed $url The address of the external resource or string for content attribute
  310. * @param array $options Other attributes for the generated tag. If the type attribute
  311. * is 'html', 'rss', 'atom', or 'icon', the mime-type is returned.
  312. * @return string
  313. */
  314. protected function _metaLink($type, $url = null, $options = array()) {
  315. $options += isset($this->_metaLinks[$type]) ? $this->_metaLinks[$type] : array();
  316. if ($type == 'icon') {
  317. $url = $url ?: 'favicon.ico';
  318. $standard = $this->_render(__METHOD__, 'meta-link', compact('url', 'options'), array(
  319. 'handlers' => array('url' => 'path')
  320. ));
  321. $options['rel'] = 'shortcut icon';
  322. $ieFix = $this->_render(__METHOD__, 'meta-link', compact('url', 'options'), array(
  323. 'handlers' => array('url' => 'path')
  324. ));
  325. return "{$standard}\n\t{$ieFix}";
  326. }
  327. return $this->_render(__METHOD__, 'meta-link', compact('url', 'options'), array(
  328. 'handlers' => array()
  329. ));
  330. }
  331. }
  332. ?>