A TTemplate object represents a parsed PRADO control template.
It can instantiate the template as child controls of a specified control.
The template format is like HTML, with the following special tags introduced,
- component tags: a component tag represents the configuration of a component.
The tag name is in the format of com:ComponentType, where ComponentType is the component
class name. Component tags must be well-formed. Attributes of the component tag
are treated as either property initial values, event handler attachment, or regular
tag attributes.
- property tags: property tags are used to set large block of attribute values.
The property tag name is in the format of where AttributeName
can be a property name, an event name or a regular tag attribute name.
- group subproperty tags: subproperties of a common property can be configured using
- directive: directive specifies the property values for the template owner.
It is in the format of <%@ property name-value pairs %>;
- expressions: They are in the format of <%= PHP expression %> and <%% PHP statements %>
- comments: There are two kinds of comments, regular HTML comments and special template comments.
The former is in the format of , which will be treated as text strings.
The latter is in the format of , which will be stripped out.
Tags other than the above are not required to be well-formed.
A TTemplate object represents a parsed PRADO template. To instantiate the template
for a particular control, call {@link instantiateIn($control)}, which
will create and intialize all components specified in the template and
set their parent as $control.
/** * Constructor. * @param string theme path * @param string theme URL * @throws TConfigurationException if theme path does not exist or any parsing error of the skin files */ public function __construct($themePath, $themeUrl) { $this->_themeUrl = $themeUrl; $this->_themePath = realpath($themePath); $this->_name = basename($themePath); $cacheValid = false; // TODO: the following needs to be cleaned up (Qiang) if (($cache = $this->getApplication()->getCache()) !== null) { $array = $cache->get(self::THEME_CACHE_PREFIX . $themePath); if (is_array($array)) { list($skins, $cssFiles, $jsFiles, $timestamp) = $array; if ($this->getApplication()->getMode() !== TApplicationMode::Performance) { if (($dir = opendir($themePath)) === false) { throw new TIOException('theme_path_inexistent', $themePath); } $cacheValid = true; while (($file = readdir($dir)) !== false) { if ($file === '.' || $file === '..') { continue; } else { if (basename($file, '.css') !== $file) { $this->_cssFiles[] = $themeUrl . '/' . $file; } else { if (basename($file, '.js') !== $file) { $this->_jsFiles[] = $themeUrl . '/' . $file; } else { if (basename($file, self::SKIN_FILE_EXT) !== $file && filemtime($themePath . DIRECTORY_SEPARATOR . $file) > $timestamp) { $cacheValid = false; break; } } } } } closedir($dir); if ($cacheValid) { $this->_skins = $skins; } } else { $cacheValid = true; $this->_cssFiles = $cssFiles; $this->_jsFiles = $jsFiles; $this->_skins = $skins; } } } if (!$cacheValid) { $this->_cssFiles = array(); $this->_jsFiles = array(); $this->_skins = array(); if (($dir = opendir($themePath)) === false) { throw new TIOException('theme_path_inexistent', $themePath); } while (($file = readdir($dir)) !== false) { if ($file === '.' || $file === '..') { continue; } else { if (basename($file, '.css') !== $file) { $this->_cssFiles[] = $themeUrl . '/' . $file; } else { if (basename($file, '.js') !== $file) { $this->_jsFiles[] = $themeUrl . '/' . $file; } else { if (basename($file, self::SKIN_FILE_EXT) !== $file) { $template = new TTemplate(file_get_contents($themePath . '/' . $file), $themePath, $themePath . '/' . $file); foreach ($template->getItems() as $skin) { if (!isset($skin[2])) { // a text string, ignored continue; } else { if ($skin[0] !== -1) { throw new TConfigurationException('theme_control_nested', $skin[1], dirname($themePath)); } } $type = $skin[1]; $id = isset($skin[2]['skinid']) ? $skin[2]['skinid'] : 0; unset($skin[2]['skinid']); if (isset($this->_skins[$type][$id])) { throw new TConfigurationException('theme_skinid_duplicated', $type, $id, dirname($themePath)); } /* foreach($skin[2] as $name=>$value) { if(is_array($value) && ($value[0]===TTemplate::CONFIG_DATABIND || $value[0]===TTemplate::CONFIG_PARAMETER)) throw new TConfigurationException('theme_databind_forbidden',dirname($themePath),$type,$id); } */ $this->_skins[$type][$id] = $skin[2]; } } } } } } closedir($dir); sort($this->_cssFiles); sort($this->_jsFiles); if ($cache !== null) { $cache->set(self::THEME_CACHE_PREFIX . $themePath, array($this->_skins, $this->_cssFiles, $this->_jsFiles, time())); } } }
/** * Loads the template from the specified file. * @return ITemplate template parsed from the specified file, null if the file doesn't exist. */ public function getTemplateByFileName($fileName) { if (($fileName = $this->getLocalizedTemplate($fileName)) !== null) { Prado::trace("Loading template {$fileName}", '\\Prado\\Web\\UI\\TTemplateManager'); if (($cache = $this->getApplication()->getCache()) === null) { return new TTemplate(file_get_contents($fileName), dirname($fileName), $fileName); } else { $array = $cache->get(self::TEMPLATE_CACHE_PREFIX . $fileName); if (is_array($array)) { list($template, $timestamps) = $array; if ($this->getApplication()->getMode() === TApplicationMode::Performance) { return $template; } $cacheValid = true; foreach ($timestamps as $tplFile => $timestamp) { if (!is_file($tplFile) || filemtime($tplFile) > $timestamp) { $cacheValid = false; break; } } if ($cacheValid) { return $template; } } $template = new TTemplate(file_get_contents($fileName), dirname($fileName), $fileName); $includedFiles = $template->getIncludedFiles(); $timestamps = array(); $timestamps[$fileName] = filemtime($fileName); foreach ($includedFiles as $includedFile) { $timestamps[$includedFile] = filemtime($includedFile); } $cache->set(self::TEMPLATE_CACHE_PREFIX . $fileName, array($template, $timestamps)); return $template; } } else { return null; } }