File.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <?php
  2. /**
  3. * Lithium: the most rad php framework
  4. *
  5. * @copyright Copyright 2013, 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\view\adapter;
  9. use lithium\util\String;
  10. use lithium\core\Libraries;
  11. use lithium\template\TemplateException;
  12. /**
  13. * The File adapter implements both template loading and rendering, and uses the
  14. * `lithium\template\view\Stream` class or `lithium\template\view\Compiler` class to auto-escape
  15. * template output with short tags (i.e. `<?=`).
  16. *
  17. * For more information about implementing your own template loaders or renderers, see the
  18. * `lithium\template\View` class.
  19. *
  20. * @see lithium\template\View
  21. * @see lithium\template\view\Compiler
  22. */
  23. class File extends \lithium\template\view\Renderer implements \ArrayAccess {
  24. /**
  25. * These configuration variables will automatically be assigned to their corresponding protected
  26. * properties when the object is initialized.
  27. *
  28. * @var array
  29. */
  30. protected $_autoConfig = array(
  31. 'classes' => 'merge', 'request', 'response', 'context',
  32. 'strings', 'handlers', 'view', 'compile', 'paths'
  33. );
  34. /**
  35. * Boolean flag indicating whether templates should be pre-compiled before inclusion. For more
  36. * information on template compilation, see `view\Compiler`.
  37. *
  38. * @see lithium\template\view\Compiler
  39. * @var boolean
  40. */
  41. protected $_compile = true;
  42. /**
  43. * An array containing the variables currently in the scope of the template. These values are
  44. * manipulable using array syntax against the template object, i.e. `$this['foo'] = 'bar'`
  45. * inside your template files.
  46. *
  47. * @var array
  48. */
  49. protected $_data = array();
  50. /**
  51. * Variables that have been set from a view/element/layout/etc. that should be available to the
  52. * same rendering context.
  53. *
  54. * @var array Key/value pairs of variables
  55. */
  56. protected $_vars = array();
  57. protected $_paths = array();
  58. /**
  59. * `File`'s dependencies. These classes are used by the output handlers to generate URLs
  60. * for dynamic resources and static assets, as well as compiling the templates.
  61. *
  62. * @see Renderer::$_handlers
  63. * @var array
  64. */
  65. protected $_classes = array(
  66. 'compiler' => 'lithium\template\view\Compiler',
  67. 'router' => 'lithium\net\http\Router',
  68. 'media' => 'lithium\net\http\Media'
  69. );
  70. public function __construct(array $config = array()) {
  71. $defaults = array(
  72. 'classes' => array(),
  73. 'compile' => true,
  74. 'compiler' => array(),
  75. 'extract' => true,
  76. 'paths' => array()
  77. );
  78. parent::__construct($config + $defaults);
  79. }
  80. /**
  81. * Renders content from a template file provided by `template()`.
  82. *
  83. * @param string $template
  84. * @param array|string $data
  85. * @param array $options
  86. * @return string
  87. */
  88. public function render($template, $data = array(), array $options = array()) {
  89. $defaults = array('context' => array());
  90. $options += $defaults;
  91. $this->_context = $options['context'] + $this->_context;
  92. $this->_data = (array) $data + $this->_vars;
  93. $this->_options = $options;
  94. $template__ = $template;
  95. unset($options, $template, $defaults, $data);
  96. if ($this->_config['extract']) {
  97. extract($this->_data, EXTR_OVERWRITE);
  98. } elseif ($this->_view) {
  99. extract((array) $this->_view->outputFilters, EXTR_OVERWRITE);
  100. }
  101. ob_start();
  102. include $template__;
  103. return ob_get_clean();
  104. }
  105. /**
  106. * Returns a template file name
  107. *
  108. * @param string $type
  109. * @param array $params
  110. * @return string
  111. */
  112. public function template($type, array $params) {
  113. $library = Libraries::get(isset($params['library']) ? $params['library'] : true);
  114. $params['library'] = $library['path'];
  115. $path = $this->_paths($type, $params);
  116. if ($this->_compile) {
  117. $compiler = $this->_classes['compiler'];
  118. $path = $compiler::template($path, $this->_config['compiler']);
  119. }
  120. return $path;
  121. }
  122. /**
  123. * Allows checking to see if a value is set in template data, i.e. `$this['foo']` in templates.
  124. *
  125. * @param string $offset The key / variable name to check.
  126. * @return boolean Returns `true` if the value is set, otherwise `false`.
  127. */
  128. public function offsetExists($offset) {
  129. return array_key_exists($offset, $this->_data);
  130. }
  131. public function offsetGet($offset) {
  132. return isset($this->_data[$offset]) ? $this->_data[$offset] : null;
  133. }
  134. public function offsetSet($offset, $value) {
  135. $this->_data[$offset] = $value;
  136. }
  137. public function offsetUnset($offset) {
  138. unset($this->_data[$offset]);
  139. }
  140. /**
  141. * Searches one or more path templates for a matching template file, and returns the file name.
  142. *
  143. * @param string $type
  144. * @param array $params The set of options keys to be interpolated into the path templates
  145. * when searching for the correct file to load.
  146. * @return string Returns the first template file found. Throws an exception if no templates
  147. * are available.
  148. */
  149. protected function _paths($type, array $params) {
  150. if (!isset($this->_paths[$type])) {
  151. throw new TemplateException("Invalid template type '{$type}'.");
  152. }
  153. foreach ((array) $this->_paths[$type] as $path) {
  154. if (!file_exists($path = String::insert($path, $params))) {
  155. continue;
  156. }
  157. return $path;
  158. }
  159. throw new TemplateException("Template not found at path `{$path}`.");
  160. }
  161. }
  162. ?>