PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/jelix/tpl/jTpl.class.php

http://github.com/jelix/jelix
PHP | 457 lines | 225 code | 41 blank | 191 comment | 37 complexity | 8584f969582ebaa53c6fce447eab2144 MD5 | raw file
Possible License(s): BSD-3-Clause, JSON, GPL-3.0, LGPL-3.0, LGPL-2.1, GPL-2.0
  1. <?php
  2. /**
  3. * @package jelix
  4. * @subpackage jtpl
  5. * @author Laurent Jouanneau
  6. * @contributor Dominique Papin
  7. * @copyright 2005-2012 Laurent Jouanneau, 2007 Dominique Papin
  8. * @link http://www.jelix.org
  9. * @licence GNU Lesser General Public Licence see LICENCE file or http://www.gnu.org/licenses/lgpl.html
  10. */
  11. /**
  12. * template engine
  13. * @package jelix
  14. * @subpackage jtpl
  15. */
  16. class jTpl {
  17. #if JTPL_STANDALONE
  18. #expand const VERSION = '__JTPL_VERSION__';
  19. #endif
  20. /**
  21. * all assigned template variables.
  22. * It have a public access only for plugins. So you musn't use directly this property
  23. * except from tpl plugins.
  24. * See methods of jTpl to manage template variables
  25. * @var array
  26. */
  27. public $_vars = array ();
  28. /**
  29. * temporary template variables for plugins.
  30. * It have a public access only for plugins. So you musn't use directly this property
  31. * except from tpl plugins.
  32. * @var array
  33. */
  34. public $_privateVars = array ();
  35. /**
  36. * internal use
  37. * It have a public access only for plugins. So you musn't use directly this property
  38. * except from tpl plugins.
  39. * @var array
  40. */
  41. public $_meta = array();
  42. public function __construct () {
  43. #ifnot JTPL_STANDALONE
  44. $config = jApp::config();
  45. $this->_vars['j_basepath'] = $config->urlengine['basePath'];
  46. $this->_vars['j_jelixwww'] = $config->urlengine['jelixWWWPath'];
  47. $this->_vars['j_jquerypath'] = $config->urlengine['jqueryPath'];
  48. $this->_vars['j_themepath'] = $config->urlengine['basePath'].'themes/'.$config->theme.'/';
  49. $this->_vars['j_locale'] = $config->locale;
  50. #endif
  51. $this->_vars['j_datenow'] = date('Y-m-d');
  52. $this->_vars['j_timenow'] = date('H:i:s');
  53. }
  54. /**
  55. * assign a value in a template variable
  56. * @param string|array $name the variable name, or an associative array 'name'=>'value'
  57. * @param mixed $value the value (or null if $name is an array)
  58. */
  59. public function assign ($name, $value = null) {
  60. if (is_array($name)) {
  61. $this->_vars = array_merge($this->_vars, $name);
  62. } else {
  63. $this->_vars[$name] = $value;
  64. }
  65. }
  66. /**
  67. * assign a value by reference in a template variable
  68. * @param string $name the variable name
  69. * @param mixed $value the value
  70. * @since jelix 1.1
  71. */
  72. public function assignByRef ($name, & $value) {
  73. $this->_vars[$name] = &$value;
  74. }
  75. /**
  76. * concat a value in with a value of an existing template variable
  77. * @param string|array $name the variable name, or an associative array 'name'=>'value'
  78. * @param mixed $value the value (or null if $name is an array)
  79. */
  80. public function append ($name, $value = null) {
  81. if (is_array($name)) {
  82. foreach ($name as $key => $val) {
  83. if (isset($this->_vars[$key]))
  84. $this->_vars[$key] .= $val;
  85. else
  86. $this->_vars[$key] = $val;
  87. }
  88. } else {
  89. if (isset($this->_vars[$name]))
  90. $this->_vars[$name] .= $value;
  91. else
  92. $this->_vars[$name] = $value;
  93. }
  94. }
  95. /**
  96. * assign a value in a template variable, only if the template variable doesn't exist
  97. * @param string|array $name the variable name, or an associative array 'name'=>'value'
  98. * @param mixed $value the value (or null if $name is an array)
  99. */
  100. public function assignIfNone ($name, $value = null) {
  101. if (is_array($name)) {
  102. foreach ($name as $key => $val) {
  103. if (!isset($this->_vars[$key]))
  104. $this->_vars[$key] = $val;
  105. }
  106. } else {
  107. if (!isset($this->_vars[$name]))
  108. $this->_vars[$name] = $value;
  109. }
  110. }
  111. #ifnot JTPL_STANDALONE
  112. /**
  113. * assign a zone content to a template variable
  114. * @param string $name the variable name
  115. * @param string $zoneName a zone selector
  116. * @param array $params parameters for the zone
  117. * @see jZone
  118. */
  119. function assignZone ($name, $zoneName, $params = array()) {
  120. $this->_vars[$name] = jZone::get ($zoneName, $params);
  121. }
  122. /**
  123. * append a zone content to a template variable
  124. * @param string $name the variable name
  125. * @param string $zoneName a zone selector
  126. * @param array $params parameters for the zone
  127. * @see jZone
  128. * @since 1.0
  129. */
  130. function appendZone ($name, $zoneName, $params = array()) {
  131. if (isset($this->_vars[$name]))
  132. $this->_vars[$name] .= jZone::get ($zoneName, $params);
  133. else
  134. $this->_vars[$name] = jZone::get ($zoneName, $params);
  135. }
  136. /**
  137. * assign a zone content to a template variable only if this variable doesn't exist
  138. * @param string $name the variable name
  139. * @param string $zoneName a zone selector
  140. * @param array $params parameters for the zone
  141. * @see jZone
  142. */
  143. function assignZoneIfNone ($name, $zoneName, $params = array()) {
  144. if (!isset($this->_vars[$name]))
  145. $this->_vars[$name] = jZone::get ($zoneName, $params);
  146. }
  147. #endif
  148. /**
  149. * says if a template variable exists
  150. * @param string $name the variable template name
  151. * @return boolean true if the variable exists
  152. */
  153. public function isAssigned ($name) {
  154. return isset($this->_vars[$name]);
  155. }
  156. /**
  157. * return the value of a template variable
  158. * @param string $name the variable template name
  159. * @return mixed the value (or null if it isn't exist)
  160. */
  161. public function get ($name) {
  162. if (isset ($this->_vars[$name])) {
  163. return $this->_vars[$name];
  164. } else {
  165. $return = null;
  166. return $return;
  167. }
  168. }
  169. /**
  170. * Return all template variables
  171. * @return array
  172. */
  173. public function getTemplateVars () {
  174. return $this->_vars;
  175. }
  176. /**
  177. * process all meta instruction of a template
  178. * @param string $tpl template selector
  179. * @param string $outputtype the type of output (html, text etc..)
  180. * @param boolean $trusted says if the template file is trusted or not
  181. */
  182. public function meta ($tpl, $outputtype = '', $trusted = true) {
  183. #ifnot JTPL_STANDALONE
  184. $sel = new jSelectorTpl($tpl,$outputtype,$trusted);
  185. $tpl = $sel->toString();
  186. #endif
  187. if (in_array($tpl, $this->processedMeta)) {
  188. // we want to process meta only one time, when a template is included
  189. // several time in an other template, or, more important, when a template
  190. // is included in a recursive manner (in this case, it did cause infinite loop, see #1396).
  191. return $this->_meta;
  192. }
  193. $this->processedMeta[] = $tpl;
  194. #ifnot JTPL_STANDALONE
  195. $md = $this->getTemplate ($sel, $outputtype, $trusted);
  196. #else
  197. $md = $this->getTemplate ($tpl, $outputtype, $trusted);
  198. #endif
  199. $fct = 'template_meta_'.$md;
  200. $fct($this);
  201. return $this->_meta;
  202. }
  203. /**
  204. * display the generated content from the given template
  205. * @param string $tpl template selector
  206. * @param string $outputtype the type of output (html, text etc..)
  207. * @param boolean $trusted says if the template file is trusted or not
  208. */
  209. public function display ($tpl, $outputtype = '', $trusted = true) {
  210. #ifnot JTPL_STANDALONE
  211. $sel = new jSelectorTpl($tpl,$outputtype,$trusted);
  212. $tpl = $sel->toString();
  213. #endif
  214. $previousTpl = $this->_templateName;
  215. $this->_templateName = $tpl;
  216. $this->recursiveTpl[] = $tpl;
  217. #ifnot JTPL_STANDALONE
  218. $md = $this->getTemplate ($sel, $outputtype, $trusted);
  219. #else
  220. $md = $this->getTemplate ($tpl, $outputtype, $trusted);
  221. #endif
  222. $fct = 'template_'.$md;
  223. $fct($this);
  224. array_pop($this->recursiveTpl);
  225. $this->_templateName = $previousTpl;
  226. }
  227. /**
  228. * contains the name of the template file
  229. * It have a public access only for plugins. So you musn't use directly this property
  230. * except from tpl plugins.
  231. * @var string
  232. * @since 1.1
  233. */
  234. public $_templateName;
  235. protected $recursiveTpl = array();
  236. protected $processedMeta = array();
  237. /**
  238. * include the compiled template file and call one of the generated function
  239. * @param string|jSelectorTpl $tpl template selector
  240. * @param string $outputtype the type of output (html, text etc..)
  241. * @param boolean $trusted says if the template file is trusted or not
  242. * @return string the suffix name of the function to call
  243. */
  244. protected function getTemplate ($tpl, $outputtype = '', $trusted = true) {
  245. #ifnot JTPL_STANDALONE
  246. $tpl->userModifiers = $this->userModifiers;
  247. $tpl->userFunctions = $this->userFunctions;
  248. jIncluder::inc($tpl);
  249. return md5($tpl->module.'_'.$tpl->resource.'_'.$tpl->outputType.($trusted?'_t':''));
  250. #else
  251. $tpl = jTplConfig::$templatePath . $tpl;
  252. if ($outputtype == '')
  253. $outputtype = 'html';
  254. $cachefile = dirname($this->_templateName).'/';
  255. if ($cachefile == './')
  256. $cachefile = '';
  257. if (jTplConfig::$cachePath == '/' || jTplConfig::$cachePath == '')
  258. throw new Exception('cache path is invalid ! its value is: "'.jTplConfig::$cachePath.'".');
  259. $cachefile = jTplConfig::$cachePath.$cachefile.$outputtype.($trusted?'_t':'').'_'.basename($tpl);
  260. $mustCompile = jTplConfig::$compilationForce || !file_exists($cachefile);
  261. if (!$mustCompile) {
  262. if (filemtime($tpl) > filemtime($cachefile)) {
  263. $mustCompile = true;
  264. }
  265. }
  266. if ($mustCompile) {
  267. include_once(JTPL_PATH . 'jTplCompiler.class.php');
  268. $compiler = new jTplCompiler();
  269. $compiler->compile($this->_templateName, $tpl, $outputtype, $trusted,
  270. $this->userModifiers, $this->userFunctions);
  271. }
  272. require_once($cachefile);
  273. return md5($tpl.'_'.$outputtype.($trusted?'_t':''));
  274. #endif
  275. }
  276. /**
  277. * return the generated content from the given template
  278. * @param string $tpl template selector
  279. * @param string $outputtype the type of output (html, text etc..)
  280. * @param boolean $trusted says if the template file is trusted or not
  281. * @param boolean $callMeta false if meta should not be called
  282. * @return string the generated content
  283. */
  284. public function fetch ($tpl, $outputtype='', $trusted = true, $callMeta=true) {
  285. $content = '';
  286. ob_start ();
  287. try{
  288. #ifnot JTPL_STANDALONE
  289. $sel = new jSelectorTpl($tpl, $outputtype, $trusted);
  290. $tpl = $sel->toString();
  291. #endif
  292. $previousTpl = $this->_templateName;
  293. $this->_templateName = $tpl;
  294. if (in_array($tpl, $this->processedMeta)) {
  295. $callMeta = false;
  296. }
  297. else
  298. $this->processedMeta[] = $tpl;
  299. $this->recursiveTpl[] = $tpl;
  300. #ifnot JTPL_STANDALONE
  301. $md = $this->getTemplate ($sel, $outputtype, $trusted);
  302. #else
  303. $md = $this->getTemplate ($tpl, $outputtype, $trusted);
  304. #endif
  305. if ($callMeta) {
  306. $fct = 'template_meta_'.$md;
  307. $fct($this);
  308. }
  309. $fct = 'template_'.$md;
  310. $fct($this);
  311. array_pop($this->recursiveTpl);
  312. $this->_templateName = $previousTpl;
  313. $content = ob_get_clean();
  314. } catch(Exception $e) {
  315. ob_end_clean();
  316. throw $e;
  317. }
  318. return $content;
  319. }
  320. /**
  321. * Return the generated content from the given string template (virtual)
  322. * @param string $tpl template content
  323. * @param string $outputtype the type of output (html, text etc..)
  324. * @param boolean $trusted says if the template file is trusted or not
  325. * @param boolean $callMeta false if meta should not be called
  326. * @return string the generated content
  327. */
  328. public function fetchFromString ($tpl, $outputtype='', $trusted = true, $callMeta=true){
  329. $content = '';
  330. ob_start ();
  331. try{
  332. #ifnot JTPL_STANDALONE
  333. $cachePath = jApp::tempPath('compiled/templates/virtuals/');
  334. require_once(JELIX_LIB_PATH.'tpl/jTplCompiler.class.php');
  335. #else
  336. $cachePath = jTplConfig::$cachePath . '/virtuals/';
  337. require_once(JTPL_PATH . 'jTplCompiler.class.php');
  338. #endif
  339. $previousTpl = $this->_templateName;
  340. $md = 'virtual_'.md5($tpl).($trusted?'_t':'');
  341. $this->_templateName = $md;
  342. if ($outputtype == '')
  343. $outputtype = 'html';
  344. $cachePath .= $outputtype.'_'.$this->_templateName.'.php';
  345. #ifnot JTPL_STANDALONE
  346. $mustCompile = $GLOBALS['gJConfig']->compilation['force'] || !file_exists($cachePath);
  347. #else
  348. $mustCompile = jTplConfig::$compilationForce || !file_exists($cachePath);
  349. #endif
  350. if ($mustCompile && !function_exists('template_'.$md)) {
  351. $compiler = new jTplCompiler();
  352. $compiler->outputType = $outputtype;
  353. $compiler->trusted = $trusted;
  354. $compiler->compileString($tpl, $cachePath, $this->userModifiers, $this->userFunctions, $md);
  355. }
  356. require_once($cachePath);
  357. if ($callMeta) {
  358. $fct = 'template_meta_'.$md;
  359. $fct($this);
  360. }
  361. $fct = 'template_'.$md;
  362. $fct($this);
  363. $content = ob_get_clean();
  364. $this->_templateName = $previousTpl;
  365. }catch(exception $e){
  366. ob_end_clean();
  367. throw $e;
  368. }
  369. return $content;
  370. }
  371. protected $userModifiers = array();
  372. /**
  373. * register a user modifier. The function should accept at least a
  374. * string as first parameter, and should return this string
  375. * which can be modified.
  376. * @param string $name the name of the modifier in a template
  377. * @param string $functionName the corresponding PHP function
  378. * @since jelix 1.1
  379. */
  380. public function registerModifier ($name, $functionName) {
  381. $this->userModifiers[$name] = $functionName;
  382. }
  383. protected $userFunctions = array();
  384. /**
  385. * register a user function. The function should accept a jTpl object
  386. * as first parameter.
  387. * @param string $name the name of the modifier in a template
  388. * @param string $functionName the corresponding PHP function
  389. * @since jelix 1.1
  390. */
  391. public function registerFunction ($name, $functionName) {
  392. $this->userFunctions[$name] = $functionName;
  393. }
  394. /**
  395. * return the current encoding
  396. * @return string the charset string
  397. * @since 1.0b2
  398. */
  399. public static function getEncoding () {
  400. #if JTPL_STANDALONE
  401. return jTplConfig::$charset;
  402. #else
  403. return jApp::config()->charset;
  404. #endif
  405. }
  406. #if JTPL_STANDALONE
  407. public function getLocaleString($locale) {
  408. $getter = jTplConfig::$localesGetter;
  409. if ($getter)
  410. $res = call_user_func($getter, $locale);
  411. else
  412. $res = $locale;
  413. return $res;
  414. }
  415. #endif
  416. }