error handler improvements
[simplicity.git] / source / lib / simplicity / core / template / template.php
blob8ae788e3322fc22afa4d68b2a076d818bba701d6
1 <?php
3 /**
4 * Template Module
5 *
6 * The Simplicity Template module provides a simple PHP based templating system.
7 *
8 * @author John Le Drew <jp@antz29.com>
9 * @copyright Copyright (c) 2009, John Le Drew
10 * @license http://www.opensource.org/licenses/mit-license.php MIT License
11 * @version 2.0.0-alpha
13 * @smp_children smp_TemplatePlugin
14 * @smp_core
16 class smp_Template extends smp_Pluggable implements smp_ModuleStatic
18 private $_data = array();
19 private $_plugins = array();
21 private $_parent;
23 private $_template;
24 private $_root;
26 /**
27 * Constructor
29 * Create a new smp_Template instance providing the $path to the template file. Do not specify the $parent at this time, it is used for
30 * rendering sub templates defined by a call to render().
32 * @param $path string
33 * @param $parent smp_Template
35 public function __construct($path=null,$parent=null)
37 $this->createExtensionPoint('smp_TemplatePlugin');
38 $this->registerPluginPrefix('smp_');
40 if (!($parent instanceof smp_Template))
42 if (!file_exists($path)) {
43 throw new Exception("{$path} does not exist. Failed to load template.");
45 } else {
46 if (!file_exists($path)) $path = $parent->getRoot().$path;
47 if (!file_exists($path)) {
48 return;
52 $this->_template = $path;
53 $this->_root = ($parent instanceof smp_Template) ? $parent->getRoot() : dirname($this->_template).DS;
55 $this->_parent = $parent;
58 public function setParent(smp_Template $parent)
60 $this->_parent = $parent;
63 private function setRoot($path)
65 $this->_root = $path.DS;
68 /**
69 * getRoot
71 * Get the root path of this template.
73 * @return string
75 public function getRoot()
77 return $this->_root;
80 public function getTemplate()
82 return $this->_template;
85 /**
86 * set
88 * Set a value to be passed to the template. This will be accessible within
89 * the template as a property ($this->name).
91 * @param $name string
92 * @param $value mixed
94 public function set($name,$value)
96 if ($value instanceof smp_Template) {
97 $value->setParent($this);
99 $this->_data[$name] = $value;
103 * get
105 * Get a value assigned to the template.
107 * @param string $name
108 * @return mixed
110 public function get($name)
112 $ret = null;
114 if (!isset($this->_data[$name])) return $ret;
116 return $this->_data[$name];
119 private function &getRef($name)
121 if (($this->_parent instanceof smp_Template) && !$this->has($name)) {
122 return $this->_parent->getRef($name);
124 $ret = null;
126 if (!isset($this->_data[$name])) return $ret;
128 return $this->_data[$name];
131 private function &setRef($name,$value)
133 $this->_data[$name] = $value;
134 return $this->_data[$name];
138 * addItem
140 * Add an items to the specified list, if the list does not exist a new list is created
141 * in the current template. You can also specify a key to make the list associative.
143 * @param $list string
144 * @param $value mixed
145 * @param $key string
146 * @return void
148 public function addItem($list,$value,$key=null)
150 $list_ref =& $this->getRef($list);
152 if (!$list_ref) {
153 $list_ref =& $this->setRef($list,array());
156 if (isset($key)) {
157 $list_ref[$key] = $value;
159 else {
160 $list_ref[] = $value;
165 * loadPlugin
167 * Load a specific plugin and make it available to the template.
169 * You can either provide an instance or class name. By default,
170 * once loaded a plugin will be available as a method of the template
171 * by the same name ($this->MyPlugin()), alternatively you can
172 * specify an identifier as the second param.
174 * @param smp_TemplatePlugin $plugin
175 * @param string $identifier
176 * @return smp_TemplatePlugin
178 public function loadPlugin($plugin,$identifier=null)
180 if ($plugin instanceof smp_TemplatePlugin) {
181 $p = $plugin;
183 else
185 if (!$plugin = $this->getModuleClass($plugin)) throw new Exception("Unknown template plugin {$plugin}");
186 $p = new $plugin($this);
189 if (!isset($identifier)) {
190 $identifier = $this->getClassModule(get_class($p));
193 $this->_plugins[$identifier] = $p;
195 return $this->_plugins[$identifier];
199 * getPlugin
201 * Get an instance of a loaded plugin.
203 * @param string $name
204 * @return smp_TemplatePlugin
206 public function getPlugin($name)
208 if (($this->_parent instanceof smp_Template) && !$this->hasPlugin($name)) {
209 return $this->_parent->getPlugin($name);
212 if (isset($this->_plugins[$name]))
214 return $this->_plugins[$name];
217 return $this->loadPlugin($name);
221 * hasPlugin
223 * Return true of false in the given plugin $name exists.
225 * @param $name string
226 * @return boolean
228 public function hasPlugin($name)
230 return isset($this->_plugins[$name]);
234 * @internal
236 public function __call($name,$args)
238 return $this->getPlugin($name);
242 * Allows access to template data via a overloaded property.
244 * @internal
245 * @see get
247 public function __get($name)
249 return $this->get($name);
253 * Allows you to set template data via a overloaded property.
255 * @internal
256 * @see set
258 public function __set($name,$value)
260 return $this->set($name,$value);
264 * has
266 * Returns boolean true / false if the specified key is available..
268 * @param string $name
269 * @return boolean
271 public function has($name)
273 return isset($this->_data[$name]);
277 * __isset overloaded function.
279 * @internal
280 * @see has
283 public function __isset($name)
285 return $this->has($name);
289 * render
291 * Render the template at the given path and return a string.
293 * @param string $path
294 * @return string
296 public function render($path,$args=array())
298 if (!$path) return false;
300 if (!($path instanceof smp_Template)) {
301 if (substr($path,0,2) == './') {
302 $path = dirname($this->_template).DS.substr($path,2);
304 $tpl = new smp_Template($path,$this);
306 else {
307 $tpl = $path;
308 $tpl->setParent($this);
311 foreach ($args as $k => $v)
313 $tpl->set($k,$v);
316 return $tpl->renderTemplate();
320 * renderTemplate
322 * Render the root template and return the resulting string.
324 * @return string
326 public function renderTemplate()
328 if (!($this->_parent instanceof smp_Template))
330 foreach ($this->_data as $k => $val) {
331 if ($val instanceof smp_Template) {
332 $this->_data[$k] = $this->get($k);
337 ob_start();
338 if (file_exists($this->_template))
340 if (substr($this->_template,0,7) == 'smpa://')
342 include smp_Archive::loadFileFromArchive($this->_template,true);
344 else
346 include $this->_template;
350 return ob_get_clean();
353 public function transferData(smp_Template $target)
355 foreach ($this->_data as $key => $value)
357 $target->set($key,$value);
358 unset($this->_data[$key]);
362 public function e($str)
364 return htmlentities($str);