PageRenderTime 57ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://github.com/gmarrot/jelix
PHP | 459 lines | 227 code | 41 blank | 191 comment | 38 complexity | bcbc66eab05ac7e01e542fd2ab4b9077 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, BSD-3-Clause
  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 ($callMeta) {
  295. if (in_array($tpl, $this->processedMeta)) {
  296. $callMeta = false;
  297. }
  298. else
  299. $this->processedMeta[] = $tpl;
  300. }
  301. $this->recursiveTpl[] = $tpl;
  302. #ifnot JTPL_STANDALONE
  303. $md = $this->getTemplate ($sel, $outputtype, $trusted);
  304. #else
  305. $md = $this->getTemplate ($tpl, $outputtype, $trusted);
  306. #endif
  307. if ($callMeta) {
  308. $fct = 'template_meta_'.$md;
  309. $fct($this);
  310. }
  311. $fct = 'template_'.$md;
  312. $fct($this);
  313. array_pop($this->recursiveTpl);
  314. $this->_templateName = $previousTpl;
  315. $content = ob_get_clean();
  316. } catch(Exception $e) {
  317. ob_end_clean();
  318. throw $e;
  319. }
  320. return $content;
  321. }
  322. /**
  323. * Return the generated content from the given string template (virtual)
  324. * @param string $tpl template content
  325. * @param string $outputtype the type of output (html, text etc..)
  326. * @param boolean $trusted says if the template file is trusted or not
  327. * @param boolean $callMeta false if meta should not be called
  328. * @return string the generated content
  329. */
  330. public function fetchFromString ($tpl, $outputtype='', $trusted = true, $callMeta=true){
  331. $content = '';
  332. ob_start ();
  333. try{
  334. #ifnot JTPL_STANDALONE
  335. $cachePath = jApp::tempPath('compiled/templates/virtuals/');
  336. require_once(JELIX_LIB_PATH.'tpl/jTplCompiler.class.php');
  337. #else
  338. $cachePath = jTplConfig::$cachePath . '/virtuals/';
  339. require_once(JTPL_PATH . 'jTplCompiler.class.php');
  340. #endif
  341. $previousTpl = $this->_templateName;
  342. $md = 'virtual_'.md5($tpl).($trusted?'_t':'');
  343. $this->_templateName = $md;
  344. if ($outputtype == '')
  345. $outputtype = 'html';
  346. $cachePath .= $outputtype.'_'.$this->_templateName.'.php';
  347. #ifnot JTPL_STANDALONE
  348. $mustCompile = jApp::config()->compilation['force'] || !file_exists($cachePath);
  349. #else
  350. $mustCompile = jTplConfig::$compilationForce || !file_exists($cachePath);
  351. #endif
  352. if ($mustCompile && !function_exists('template_'.$md)) {
  353. $compiler = new jTplCompiler();
  354. $compiler->outputType = $outputtype;
  355. $compiler->trusted = $trusted;
  356. $compiler->compileString($tpl, $cachePath, $this->userModifiers, $this->userFunctions, $md);
  357. }
  358. require_once($cachePath);
  359. if ($callMeta) {
  360. $fct = 'template_meta_'.$md;
  361. $fct($this);
  362. }
  363. $fct = 'template_'.$md;
  364. $fct($this);
  365. $content = ob_get_clean();
  366. $this->_templateName = $previousTpl;
  367. }catch(exception $e){
  368. ob_end_clean();
  369. throw $e;
  370. }
  371. return $content;
  372. }
  373. protected $userModifiers = array();
  374. /**
  375. * register a user modifier. The function should accept at least a
  376. * string as first parameter, and should return this string
  377. * which can be modified.
  378. * @param string $name the name of the modifier in a template
  379. * @param string $functionName the corresponding PHP function
  380. * @since jelix 1.1
  381. */
  382. public function registerModifier ($name, $functionName) {
  383. $this->userModifiers[$name] = $functionName;
  384. }
  385. protected $userFunctions = array();
  386. /**
  387. * register a user function. The function should accept a jTpl object
  388. * as first parameter.
  389. * @param string $name the name of the modifier in a template
  390. * @param string $functionName the corresponding PHP function
  391. * @since jelix 1.1
  392. */
  393. public function registerFunction ($name, $functionName) {
  394. $this->userFunctions[$name] = $functionName;
  395. }
  396. /**
  397. * return the current encoding
  398. * @return string the charset string
  399. * @since 1.0b2
  400. */
  401. public static function getEncoding () {
  402. #if JTPL_STANDALONE
  403. return jTplConfig::$charset;
  404. #else
  405. return jApp::config()->charset;
  406. #endif
  407. }
  408. #if JTPL_STANDALONE
  409. public function getLocaleString($locale) {
  410. $getter = jTplConfig::$localesGetter;
  411. if ($getter)
  412. $res = call_user_func($getter, $locale);
  413. else
  414. $res = $locale;
  415. return $res;
  416. }
  417. #endif
  418. }