Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationLatte
      • ApplicationTracy
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsLatte
      • Framework
      • HttpTracy
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
    • Reflection
    • Security
    • Templating
    • Utils
  • NetteModule
  • none
  • Tracy

Classes

  • Compiler
  • Engine
  • Helpers
  • HtmlNode
  • MacroNode
  • MacroTokens
  • Object
  • Parser
  • PhpWriter
  • Token

Interfaces

  • ILoader
  • IMacro

Exceptions

  • CompileException
  • RegexpException
  • RuntimeException
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (http://nette.org)
  5:  * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
  6:  */
  7: 
  8: namespace Latte;
  9: 
 10: 
 11: /**
 12:  * Templating engine Latte.
 13:  *
 14:  * @author     David Grudl
 15:  */
 16: class Engine extends Object
 17: {
 18:     /** Content types */
 19:     const CONTENT_HTML = Compiler::CONTENT_HTML,
 20:         CONTENT_XHTML = Compiler::CONTENT_XHTML,
 21:         CONTENT_XML = Compiler::CONTENT_XML,
 22:         CONTENT_JS = Compiler::CONTENT_JS,
 23:         CONTENT_CSS = Compiler::CONTENT_CSS,
 24:         CONTENT_ICAL = Compiler::CONTENT_ICAL,
 25:         CONTENT_TEXT = Compiler::CONTENT_TEXT;
 26: 
 27:     /** @var array */
 28:     public $onCompile = array();
 29: 
 30:     /** @var Parser */
 31:     private $parser;
 32: 
 33:     /** @var Compiler */
 34:     private $compiler;
 35: 
 36:     /** @var ILoader */
 37:     private $loader;
 38: 
 39:     /** @var string */
 40:     private $contentType = self::CONTENT_HTML;
 41: 
 42:     /** @var string */
 43:     private $tempDirectory;
 44: 
 45:     /** @var bool */
 46:     private $autoRefresh = TRUE;
 47: 
 48:     /** @var array run-time filters */
 49:     private $filters = array(
 50:         NULL => array(), // dynamic
 51:         'bytes' => 'Latte\Runtime\Filters::bytes',
 52:         'capitalize' => 'Latte\Runtime\Filters::capitalize',
 53:         'datastream' => 'Latte\Runtime\Filters::dataStream',
 54:         'date' => 'Latte\Runtime\Filters::date',
 55:         'escapecss' => 'Latte\Runtime\Filters::escapeCss',
 56:         'escapehtml' => 'Latte\Runtime\Filters::escapeHtml',
 57:         'escapehtmlcomment' => 'Latte\Runtime\Filters::escapeHtmlComment',
 58:         'escapeical' => 'Latte\Runtime\Filters::escapeICal',
 59:         'escapejs' => 'Latte\Runtime\Filters::escapeJs',
 60:         'escapeurl' => 'rawurlencode',
 61:         'escapexml' => 'Latte\Runtime\Filters::escapeXML',
 62:         'firstupper' => 'Latte\Runtime\Filters::firstUpper',
 63:         'implode' => 'implode',
 64:         'indent' => 'Latte\Runtime\Filters::indent',
 65:         'lower' => 'Latte\Runtime\Filters::lower',
 66:         'nl2br' => 'Latte\Runtime\Filters::nl2br',
 67:         'number' => 'number_format',
 68:         'repeat' => 'str_repeat',
 69:         'replace' => 'Latte\Runtime\Filters::replace',
 70:         'replacere' => 'Latte\Runtime\Filters::replaceRe',
 71:         'safeurl' => 'Latte\Runtime\Filters::safeUrl',
 72:         'strip' => 'Latte\Runtime\Filters::strip',
 73:         'striptags' => 'strip_tags',
 74:         'substr' => 'Latte\Runtime\Filters::substring',
 75:         'trim' => 'Latte\Runtime\Filters::trim',
 76:         'truncate' => 'Latte\Runtime\Filters::truncate',
 77:         'upper' => 'Latte\Runtime\Filters::upper',
 78:     );
 79: 
 80:     /** @var string */
 81:     private $baseTemplateClass = 'Latte\Template';
 82: 
 83: 
 84:     /**
 85:      * Renders template to output.
 86:      * @return void
 87:      */
 88:     public function render($name, array $params = array())
 89:     {
 90:         $template = new $this->baseTemplateClass($params, $this->filters, $this, $name);
 91:         $this->loadCacheFile($name, $template->getParameters());
 92:     }
 93: 
 94: 
 95:     /**
 96:      * Renders template to string.
 97:      * @return string
 98:      */
 99:     public function renderToString($name, array $params = array())
100:     {
101:         ob_start();
102:         try {
103:             $this->render($name, $params);
104:         } catch (\Exception $e) {
105:             ob_end_clean();
106:             throw $e;
107:         }
108:         return ob_get_clean();
109:     }
110: 
111: 
112:     /**
113:      * Compiles template to PHP code.
114:      * @return string
115:      */
116:     public function compile($name)
117:     {
118:         foreach ($this->onCompile ?: array() as $cb) {
119:             call_user_func(Helpers::checkCallback($cb), $this);
120:         }
121:         $this->onCompile = array();
122: 
123:         $source = $this->getLoader()->getContent($name);
124:         try {
125:             $tokens = $this->getParser()->setContentType($this->contentType)
126:                 ->parse($source);
127:             $code = $this->getCompiler()->setContentType($this->contentType)
128:                 ->compile($tokens);
129: 
130:             if (preg_match('#^\S{5,100}\z#', $name)) {
131:                 $code = "<?php\n// source: $name\n?>" . $code;
132:             }
133: 
134:         } catch (\Exception $e) {
135:             $e = $e instanceof CompileException ? $e : new CompileException("Thrown exception '{$e->getMessage()}'", NULL, $e);
136:             throw $e->setSource($source, $this->getCompiler()->getLine(), $name);
137:         }
138:         $code = Helpers::optimizePhp($code);
139:         return $code;
140:     }
141: 
142: 
143:     /**
144:      * @return void
145:      */
146:     private function loadCacheFile($name, $params)
147:     {
148:         if (!$this->tempDirectory) {
149:             return call_user_func(function() {
150:                 foreach (func_get_arg(1) as $__k => $__v) {
151:                     $$__k = $__v;
152:                 }
153:                 unset($__k, $__v);
154:                 eval('?>' . func_get_arg(0));
155:             }, $this->compile($name), $params);
156:         }
157: 
158:         $file = $this->getCacheFile($name);
159:         $handle = fopen($file, 'c+');
160:         if (!$handle) {
161:             throw new \RuntimeException("Unable to open or create file '$file'.");
162:         }
163:         flock($handle, LOCK_SH);
164:         $stat = fstat($handle);
165:         if (!$stat['size'] || ($this->autoRefresh && $this->getLoader()->isExpired($name, $stat['mtime']))) {
166:             ftruncate($handle, 0);
167:             flock($handle, LOCK_EX);
168:             $stat = fstat($handle);
169:             if (!$stat['size']) {
170:                 $code = $this->compile($name);
171:                 if (fwrite($handle, $code, strlen($code)) !== strlen($code)) {
172:                     ftruncate($handle, 0);
173:                     throw new \RuntimeException("Unable to write file '$file'.");
174:                 }
175:             }
176:             flock($handle, LOCK_SH); // holds the lock
177:         }
178: 
179:         call_user_func(function() {
180:             foreach (func_get_arg(1) as $__k => $__v) {
181:                 $$__k = $__v;
182:             }
183:             unset($__k, $__v);
184:             include func_get_arg(0);
185:         }, $file, $params);
186:     }
187: 
188: 
189:     /**
190:      * @return string
191:      */
192:     public function getCacheFile($name)
193:     {
194:         if (!$this->tempDirectory) {
195:             throw new \RuntimeException('Set path to temporary directory using setTempDirectory().');
196:         } elseif (!is_dir($this->tempDirectory)) {
197:             mkdir($this->tempDirectory);
198:         }
199:         $file = md5($name);
200:         if (preg_match('#\b\w.{10,50}$#', $name, $m)) {
201:             $file = trim(preg_replace('#\W+#', '-', $m[0]), '-') . '-' . $file;
202:         }
203:         return $this->tempDirectory . '/' . $file . '.php';
204:     }
205: 
206: 
207:     /**
208:      * Registers run-time filter.
209:      * @param  string|NULL
210:      * @param  callable
211:      * @return self
212:      */
213:     public function addFilter($name, $callback)
214:     {
215:         if ($name == NULL) { // intentionally ==
216:             array_unshift($this->filters[NULL], $callback);
217:         } else {
218:             $this->filters[strtolower($name)] = $callback;
219:         }
220:         return $this;
221:     }
222: 
223: 
224:     /**
225:      * Returns all run-time filters.
226:      * @return callable[]
227:      */
228:     public function getFilters()
229:     {
230:         return $this->filters;
231:     }
232: 
233: 
234:     /**
235:      * Adds new macro.
236:      * @return self
237:      */
238:     public function addMacro($name, IMacro $macro)
239:     {
240:         $this->getCompiler()->addMacro($name, $macro);
241:         return $this;
242:     }
243: 
244: 
245:     /**
246:      * @return self
247:      */
248:     public function setContentType($type)
249:     {
250:         $this->contentType = $type;
251:         return $this;
252:     }
253: 
254: 
255:     /**
256:      * Sets path to temporary directory.
257:      * @return self
258:      */
259:     public function setTempDirectory($path)
260:     {
261:         $this->tempDirectory = $path;
262:         return $this;
263:     }
264: 
265: 
266:     /**
267:      * Sets auto-refresh mode.
268:      * @return self
269:      */
270:     public function setAutoRefresh($on = TRUE)
271:     {
272:         $this->autoRefresh = (bool) $on;
273:         return $this;
274:     }
275: 
276: 
277:     /**
278:      * @return Parser
279:      */
280:     public function getParser()
281:     {
282:         if (!$this->parser) {
283:             $this->parser = new Parser;
284:         }
285:         return $this->parser;
286:     }
287: 
288: 
289:     /**
290:      * @return Compiler
291:      */
292:     public function getCompiler()
293:     {
294:         if (!$this->compiler) {
295:             $this->compiler = new Compiler;
296:             Macros\CoreMacros::install($this->compiler);
297:             Macros\BlockMacros::install($this->compiler);
298:         }
299:         return $this->compiler;
300:     }
301: 
302: 
303:     /**
304:      * @return self
305:      */
306:     public function setLoader(ILoader $loader)
307:     {
308:         $this->loader = $loader;
309:         return $this;
310:     }
311: 
312: 
313:     /**
314:      * @return ILoader
315:      */
316:     public function getLoader()
317:     {
318:         if (!$this->loader) {
319:             $this->loader = new Loaders\FileLoader;
320:         }
321:         return $this->loader;
322:     }
323: 
324: }
325: 
Nette 2.2.2 API API documentation generated by ApiGen 2.8.0