1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
<?php
/**
* TTemplateManager and TTemplate class file
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @link http://www.pradosoft.com/
* @copyright Copyright © 2005-2014 PradoSoft
* @license http://www.pradosoft.com/license/
* @package Prado\Web\UI
*/
namespace Prado\Web\UI;
use Prado\Prado;
/**
* TTemplateManager class
*
* TTemplateManager manages the loading and parsing of control templates.
*
* There are two ways of loading a template, either by the associated template
* control class name, or the template file name.
* The former is via calling {@link getTemplateByClassName}, which tries to
* locate the corresponding template file under the directory containing
* the class file. The name of the template file is the class name with
* the extension '.tpl'. To load a template from a template file path,
* call {@link getTemplateByFileName}.
*
* By default, TTemplateManager is registered with {@link TPageService} as the
* template manager module that can be accessed via {@link TPageService::getTemplateManager()}.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @package Prado\Web\UI
* @since 3.0
*/
class TTemplateManager extends \Prado\TModule
{
/**
* Template file extension
*/
const TEMPLATE_FILE_EXT='.tpl';
/**
* Prefix of the cache variable name for storing parsed templates
*/
const TEMPLATE_CACHE_PREFIX='prado:template:';
/**
* Initializes the module.
* This method is required by IModule and is invoked by application.
* It starts output buffer if it is enabled.
* @param TXmlElement module configuration
*/
public function init($config)
{
$this->getService()->setTemplateManager($this);
}
/**
* Loads the template corresponding to the specified class name.
* @return ITemplate template for the class name, null if template doesn't exist.
*/
public function getTemplateByClassName($className)
{
$class=new \ReflectionClass($className);
$tplFile=dirname($class->getFileName()).DIRECTORY_SEPARATOR.$className.self::TEMPLATE_FILE_EXT;
return $this->getTemplateByFileName($tplFile);
}
/**
* 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",'System.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;
}
/**
* Finds a localized template file.
* @param string template file.
* @return string|null a localized template file if found, null otherwise.
*/
protected function getLocalizedTemplate($filename)
{
if(($app=$this->getApplication()->getGlobalization(false))===null)
return is_file($filename)?$filename:null;
foreach($app->getLocalizedResource($filename) as $file)
{
if(($file=realpath($file))!==false && is_file($file))
return $file;
}
return null;
}
}
|