3 * The own template engine for loading caching and sending out the web pages
6 * @author Roland Haeder <webmaster@mxchange.org>
8 * @copyright Copyright(c) 2007, 2008 Roland Haeder, this is free software
9 * @license GNU GPL 3.0 or any newer version
10 * @link http://www.mxchange.org
12 * This program is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, either version 3 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 class TemplateEngine extends BaseFrameworkSystem implements CompileableTemplate {
27 * The local path name where all templates and sub folders for special
28 * templates are stored. We will internally determine the language plus
29 * "html" for web templates or "emails" for email templates
31 private $basePath = "";
34 * The extension for web and email templates (not compiled templates)
36 private $templateExtension = ".tpl";
39 * The extension for code templates (not compiled templates)
41 private $codeExtension = ".ctp";
44 * Path relative to $basePath and language code for compiled code-templates
46 private $compileOutputPath = "templates/_compiled";
49 * The raw (maybe uncompiled) template
51 private $rawTemplateData = "";
54 * Template data with compiled-in variables
56 private $compiledData = "";
59 * The last loaded template's FQFN for debugging the engine
61 private $lastTemplate = "";
64 * The variable stack for the templates. This must be initialized and
65 * shall become an instance of FrameworkArrayObject.
67 private $varStack = null;
70 * Configuration variables in a simple array
72 private $configVariables = array();
75 * The language instance which should link to an object of LanguageSystem
77 private $langInstance = null;
80 * Loaded templates for recursive protection and detection
82 private $loadedTemplates = array();
85 * Compiled templates for recursive protection and detection
87 private $compiledTemplates = array();
90 * Loaded raw template data
92 private $loadedRawData = null;
95 * Raw templates which are linked in code templates
97 private $rawTemplates = null;
100 * A regular expression for variable=value pairs
102 private $regExpVarValue = '/([\w_]+)(="([^"]*)"|=([\w_]+))?/';
105 * A regular expression for filtering out code tags
107 * E.g.: {?template:variable=value;var2=value2;[...]?}
109 private $regExpCodeTags = '/\{\?([a-z_]+)(:("[^"]+"|[^?}]+)+)?\?\}/';
114 private $helpers = array();
116 // Exception codes for the template engine
117 const EXCEPTION_TEMPLATE_TYPE_IS_UNEXPECTED = 0xa00;
118 const EXCEPTION_TEMPLATE_CONTAINS_INVALID_VAR = 0xa01;
119 const EXCEPTION_INVALID_VIEW_HELPER = 0xa02;
122 * Private constructor
126 private final function __construct () {
127 // Call parent constructor
128 parent::constructor(__CLASS__);
130 // Set part description
131 $this->setPartDescr("Template-Engine");
133 // Create unique ID number
134 $this->createUniqueID();
137 $this->removeNumberFormaters();
138 $this->removeSystemArray();
142 * Creates an instance of the class TemplateEngine and prepares it for usage
144 * @param $basePath The local base path for all templates
145 * @param $langInstance An instance of LanguageSystem (default)
146 * @param $ioInstance An instance of FileIOHandler (default, middleware!)
147 * @return $tplInstance An instance of TemplateEngine
148 * @throws BasePathIsEmptyException If the provided $basePath is empty
149 * @throws InvalidBasePathStringException If $basePath is no string
150 * @throws BasePathIsNoDirectoryException If $basePath is no
151 * directory or not found
152 * @throws BasePathReadProtectedException If $basePath is
155 public final static function createTemplateEngine ($basePath, $langInstance, $ioInstance) {
156 // Get a new instance
157 $tplInstance = new TemplateEngine();
159 // Is the base path valid?
160 if (empty($basePath)) {
161 // Base path is empty
162 throw new BasePathIsEmptyException($tplInstance, self::EXCEPTION_UNEXPECTED_EMPTY_STRING);
163 } elseif (!is_string($basePath)) {
165 throw new InvalidBasePathStringException(array($tplInstance, $basePath), self::EXCEPTION_INVALID_STRING);
166 } elseif (!is_dir($basePath)) {
168 throw new BasePathIsNoDirectoryException(array($tplInstance, $basePath), self::EXCEPTION_INVALID_PATH_NAME);
169 } elseif (!is_readable($basePath)) {
171 throw new BasePathReadProtectedException(array($tplInstance, $basePath), self::EXCEPTION_READ_PROTECED_PATH);
174 // Get configuration instance
175 $cfgInstance = $tplInstance->getConfigInstance();
178 $tplInstance->setBasePath($basePath);
180 // Initialize the variable stack
181 $tplInstance->initVariableStack();
183 // Set the language and IO instances
184 $tplInstance->setLanguageInstance($langInstance);
185 $tplInstance->setIOInstance($ioInstance);
187 // Set template extensions
188 $tplInstance->setRawTemplateExtension($cfgInstance->readConfig("raw_template_extension"));
189 $tplInstance->setCodeTemplateExtension($cfgInstance->readConfig("code_template_extension"));
191 // Absolute output path for compiled templates
192 $tplInstance->setCompileOutputPath(PATH . $cfgInstance->readConfig("compile_output_path"));
194 // Return the prepared instance
199 * Search for a variable in the stack
201 * @param $var The variable we are looking for
202 * @return $idx FALSE means not found, > 0 means found on a specific index
204 private function isVariableAlreadySet ($var) {
205 // First everything is not found
209 for ($idx = $this->varStack->getIterator(); $idx->valid(); $idx->next()) {
211 $currEntry = $idx->current();
213 // Is the entry found?
214 if ($currEntry['name'] == $var) {
216 $found = $idx->key();
221 // Return the current position
226 * Add a variable to the stack
228 * @param $var The variable we are looking for
229 * @param $value The value we want to store in the variable
232 private function addVariable ($var, $value) {
233 // Add it to the stack
234 $this->varStack->append(array(
241 * Modify an entry on the stack
243 * @param $var The variable we are looking for
244 * @param $value The value we want to store in the variable
247 private function modifyVariable ($var, $value) {
248 // It should be there so let's look again...
249 for ($idx = $this->varStack->getIterator(); $idx->valid(); $idx->next()) {
251 $currEntry = $idx->current();
253 // Is this the requested variable?
254 if ($currEntry['name'] == $var) {
255 // Change it to the other value
256 $this->varStack->offsetSet($idx->key(), array(
265 * Initialize the variable stack. This holds all variables for later
270 public final function initVariableStack () {
271 $this->varStack = new FrameworkArrayObject();
275 * Setter for language instance which should be LanguageSystem
277 * @param $langInstance The language instance
280 public final function setLanguageInstance (ManageableLanguage $langInstance) {
281 $this->langInstance = $langInstance;
285 * Setter for file I/O instance which should be FileIOHandler
287 * @param $ioInstance The file I/O instance
290 public final function setIOInstance (FileIOHandler $ioInstance) {
291 $this->ioInstance = $ioInstance;
295 * Getter for file I/O instance which should be FileIOHandler
297 * @return $ioInstance The file I/O instance
299 public final function getIOInstance () {
300 return $this->ioInstance;
304 * Setter for base path
306 * @param $basePath The local base path for all templates
309 public final function setBasePath ($basePath) {
311 $basePath = (string) $basePath;
314 $this->basePath = $basePath;
318 * Getter for base path
320 * @return $basePath The local base path for all templates
322 public final function getBasePath () {
324 return $this->basePath;
328 * Setter for template extension
330 * @param $templateExtension The file extension for all uncompiled
334 public final function setRawTemplateExtension ($templateExtension) {
336 $templateExtension = (string) $templateExtension;
339 $this->templateExtension = $templateExtension;
343 * Setter for code template extension
345 * @param $codeExtension The file extension for all uncompiled
349 public final function setCodeTemplateExtension ($codeExtension) {
351 $codeExtension = (string) $codeExtension;
354 $this->codeExtension = $codeExtension;
358 * Getter for template extension
360 * @return $templateExtension The file extension for all uncompiled
363 public final function getRawTemplateExtension () {
365 return $this->templateExtension;
369 * Getter for code-template extension
371 * @return $codeExtension The file extension for all code-
374 public final function getCodeTemplateExtension () {
376 return $this->codeExtension;
380 * Setter for path of compiled templates
382 * @param $compileOutputPath The local base path for all
386 public final function setCompileOutputPath ($compileOutputPath) {
388 $compileOutputPath = (string) $compileOutputPath;
391 $this->compileOutputPath = $compileOutputPath;
395 * Setter for template type. Only "html", "emails" and "compiled" should
398 * @param $templateType The current template's type
401 private final function setTemplateType ($templateType) {
403 $templateType = (string) $templateType;
405 // And set it (only 2 letters)
406 $this->templateType = $templateType;
410 * Getter for template type
412 * @return $templateType The current template's type
414 public final function getTemplateType () {
415 return $this->templateType;
419 * Setter for the last loaded template's FQFN
421 * @param $template The last loaded template
424 private final function setLastTemplate ($template) {
426 $template = (string) $template;
427 $this->lastTemplate = $template;
431 * Getter for the last loaded template's FQFN
433 * @return $template The last loaded template
435 private final function getLastTemplate () {
436 return $this->lastTemplate;
440 * Assign (add) a given variable with a value
442 * @param $var The variable we are looking for
443 * @param $value The value we want to store in the variable
446 public final function assignVariable ($var, $value) {
447 // First search for the variable if it was already added
448 $idx = $this->isVariableAlreadySet($var);
451 if ($idx === false) {
452 // Add it to the stack
453 $this->addVariable($var, $value);
454 } elseif (!empty($value)) {
455 // Modify the stack entry
456 $this->modifyVariable($var, $value);
461 * Assign a given congfiguration variable with a value
463 * @param $var The configuration variable we are looking for
464 * @param $value The value we want to store in the variable
467 public final function assignConfigVariable ($var, $value) {
468 // Sweet and simple...
469 $this->configVariables[$var] = $value;
473 * Removes a given variable
475 * @param $var The variable we are looking for
478 public final function removeVariable ($var) {
479 // First search for the variable if it was already added
480 $idx = $this->isVariableAlreadySet($var);
483 if ($idx !== false) {
484 // Remove this variable
485 $this->varStack->offsetUnset($idx);
490 * Private setter for raw template data
492 * @param $rawTemplateData The raw data from the template
495 private final function setRawTemplateData ($rawTemplateData) {
497 $rawTemplateData = (string) $rawTemplateData;
499 // And store it in this class
500 $this->rawTemplateData = $rawTemplateData;
504 * Private setter for compiled templates
506 private final function setCompiledData ($compiledData) {
508 $compiledData = (string) $compiledData;
510 // And store it in this class
511 $this->compiledData = $compiledData;
515 * Private loader for all template types
517 * @param $template The template we shall load
520 private final function loadTemplate ($template) {
522 $template = (string) $template;
524 // Get extension for the template
525 $ext = $this->getRawTemplateExtension();
527 // If we shall load a code-template we need to switch the file extension
528 if ($this->getTemplateType() == $this->getConfigInstance()->readConfig("code_template_type")) {
529 // Switch over to the code-template extension
530 $ext = $this->getCodeTemplateExtension();
533 // Construct the FQFN for the template by honoring the current language
534 $fqfn = sprintf("%s%s/%s/%s%s",
535 $this->getBasePath(),
536 $this->langInstance->getLanguageCode(),
537 $this->getTemplateType(),
542 // Load the raw template data
543 $this->loadRawTemplateData($fqfn);
547 * A private loader for raw template names
549 * @param $fqfn The full-qualified file name for a template
551 * @throws NullPointerException If $inputInstance is null
552 * @throws NoObjectException If $inputInstance is not an object
553 * @throws MissingMethodException If $inputInstance is missing a
556 private function loadRawTemplateData ($fqfn) {
558 if ((defined('DEBUG_TEMPLATE')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Template <strong>%s</strong> vom Typ <strong>%s</strong> wird geladen.<br />\n",
561 $this->getTemplateType()
564 // Get a input/output instance from the middleware
565 $ioInstance = $this->getIOInstance();
567 // Validate the instance
568 if (is_null($ioInstance)) {
570 throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
571 } elseif (!is_object($ioInstance)) {
572 // Throw another exception
573 throw new NoObjectException($ioInstance, self::EXCEPTION_IS_NO_OBJECT);
574 } elseif (!method_exists($ioInstance, 'loadFileContents')) {
575 // Throw yet another exception
576 throw new MissingMethodException(array($ioInstance, 'loadFileContents'), self::EXCEPTION_MISSING_METHOD);
579 // Load the raw template
580 $rawTemplateData = $ioInstance->loadFileContents($fqfn);
583 if ((defined('DEBUG_TEMPLATE')) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] <strong>%s</strong> Byte Rohdaten geladen.<br />\n",
585 strlen($rawTemplateData)
588 // Store the template's contents into this class
589 $this->setRawTemplateData($rawTemplateData);
591 // Remember the template's FQFN
592 $this->setLastTemplate($fqfn);
596 * Try to assign an extracted template variable as a "content" or "config"
599 * @param $varName The variable's name (shall be content or
601 * @param $var The variable we want to assign
603 private function assignTemplateVariable ($varName, $var) {
604 // Is it not a config variable?
605 if ($varName != "config") {
606 // Regular template variables
607 $this->assignVariable($var, "");
609 // Configuration variables
610 $this->assignConfigVariable($var, $this->getConfigInstance()->readConfig($var));
615 * Extract variables from a given raw data stream
617 * @param $rawData The raw template data we shall analyze
619 * @throws InvalidTemplateVariableNameException If a variable name
623 private function extractVariablesFromRawData ($rawData) {
625 $rawData = (string) $rawData;
627 // Search for variables
628 @preg_match_all('/\$(\w+)(\[(\w+)\])?/', $rawData, $variableMatches);
630 // Did we find some variables?
631 if ((is_array($variableMatches)) && (count($variableMatches) == 4) && (count($variableMatches[0]) > 0)) {
632 // Initialize all missing variables
633 foreach ($variableMatches[3] as $key=>$var) {
634 // Is the variable name valid?
635 if (($variableMatches[1][$key] != $this->getConfigInstance()->readConfig("tpl_valid_var")) && ($variableMatches[1][$key] != "config")) {
636 // Invalid variable name
637 throw new InvalidTemplateVariableNameException(array($this, $this->getLastTemplate(), $variableMatches[1][$key], $this->getConfigInstance()), self::EXCEPTION_TEMPLATE_CONTAINS_INVALID_VAR);
640 // Try to assign it, empty strings are being ignored
641 $this->assignTemplateVariable($variableMatches[1][$key], $var);
647 * Main analysis of the loaded template
649 * @param $templateMatches Found template place-holders, see below
652 *---------------------------------
653 * Structure of $templateMatches:
654 *---------------------------------
655 * [0] => Array - An array with all full matches
656 * [1] => Array - An array with left part (before the ":") of a match
657 * [2] => Array - An array with right part of a match including ":"
658 * [3] => Array - An array with right part of a match excluding ":"
660 private function analyzeTemplate ($templateMatches) {
661 // Backup raw template data
662 $backup = $this->getRawTemplateData();
664 // Initialize some arrays
665 if (is_null($this->loadedRawData)) { $this->loadedRawData = array(); $this->rawTemplates = array(); }
667 // Load all requested templates
668 foreach ($templateMatches[1] as $template) {
670 // Load and compile only templates which we have not yet loaded
671 // RECURSIVE PROTECTION! BE CAREFUL HERE!
672 if ((!isset($this->loadedRawData[$template])) && (!in_array($template, $this->loadedTemplates))) {
674 // Then try to search for code-templates first
676 // Load the code template and remember it's contents
677 $this->loadCodeTemplate($template);
678 $this->loadedRawData[$template] = $this->getRawTemplateData();
680 // Remember this template for recursion detection
681 // RECURSIVE PROTECTION!
682 $this->loadedTemplates[] = $template;
683 } catch (FilePointerNotOpenedException $e) {
684 // Template not found!
685 $this->rawTemplates[] = $template;
688 } // if ((!isset( ...
690 } // for ($templateMatches ...
692 // Restore the raw template data
693 $this->setRawTemplateData($backup);
697 * Compile a given raw template code and remember it for later usage
699 * @param $code The raw template code
700 * @param $template The template's name
703 private function compileCode ($code, $template) {
704 // Is this template already compiled?
705 if (in_array($template, $this->compiledTemplates)) {
710 // Remember this template being compiled
711 $this->compiledTemplates[] = $template;
713 // Compile the loaded code in five steps:
715 // 1. Backup current template data
716 $backup = $this->getRawTemplateData();
718 // 2. Set the current template's raw data as the new content
719 $this->setRawTemplateData($code);
721 // 3. Compile the template data
722 $this->compileTemplate();
724 // 4. Remember it's contents
725 $this->loadedRawData[$template] = $this->getRawTemplateData();
727 // 5. Restore the previous raw content from backup variable
728 $this->setRawTemplateData($backup);
732 * Insert all given and loaded templates by running through all loaded
733 * codes and searching for their place-holder in the main template
735 * @param $templateMatches See method analyzeTemplate()
738 private function insertAllTemplates ($templateMatches) {
739 // Run through all loaded codes
740 foreach ($this->loadedRawData as $template => $code) {
742 // Search for the template
743 $foundIndex = array_search($template, $templateMatches[1]);
745 // Lookup the matching template replacement
746 if (isset($templateMatches[0][$foundIndex])) {
748 // Get the current raw template
749 $rawData = $this->getRawTemplateData();
751 // Replace the space holder with the template code
752 $rawData = str_replace($templateMatches[0][$foundIndex], $code, $rawData);
754 // Set the new raw data
755 $this->setRawTemplateData($rawData);
761 * Load all extra raw templates
765 private function loadExtraRawTemplates () {
766 // Are there some raw templates we need to load?
767 if (count($this->rawTemplates) > 0) {
768 // Try to load all raw templates
769 foreach ($this->rawTemplates as $key => $template) {
772 $this->loadWebTemplate($template);
774 // Remember it's contents
775 $this->rawTemplates[$template] = $this->getRawTemplateData();
777 // Remove it from the loader list
778 unset($this->rawTemplates[$key]);
780 // Remember this template for recursion detection
781 // RECURSIVE PROTECTION!
782 $this->loadedTemplates[] = $template;
783 } catch (FilePointerNotOpenedException $e) {
784 // This template was never found. We silently ignore it
785 unset($this->rawTemplates[$key]);
792 * Assign all found template variables
794 * @param $varMatches An array full of variable/value pairs.
797 private function assignAllVariables ($varMatches) {
798 // Search for all variables
799 foreach ($varMatches[1] as $key=>$var) {
801 // Detect leading equals
802 if (substr($varMatches[2][$key], 0, 1) == "=") {
803 // Remove and cast it
804 $varMatches[2][$key] = (string) substr($varMatches[2][$key], 1);
807 // Do we have some quotes left and right side? Then it is free text
808 if ((substr($varMatches[2][$key], 0, 1) == "\"") && (substr($varMatches[2][$key], -1, 1) == "\"")) {
809 // Free string detected! Which we can assign directly
810 $this->assignVariable($var, $varMatches[3][$key]);
812 // Non-string found so we need some deeper analysis...
813 die("Deeper analysis not yet implemented!");
816 } // for ($varMatches ...
819 * Compiles all loaded raw templates
821 * @param $templateMatches See method analyzeTemplate() for details
824 private function compileRawTemplateData ($templateMatches) {
825 // Are some code-templates found which we need to compile?
826 if (count($this->loadedRawData) > 0) {
829 foreach ($this->loadedRawData as $template => $code) {
831 // Search for the template
832 $foundIndex = array_search($template, $templateMatches[1]);
834 // Lookup the matching variable data
835 if (isset($templateMatches[3][$foundIndex])) {
837 // Split it up with another reg. exp. into variable=value pairs
838 @preg_match_all($this->regExpVarValue, $templateMatches[3][$foundIndex], $varMatches);
840 // Assign all variables
841 $this->assignAllVariables($varMatches);
843 } // END - if (isset($templateMatches ...
845 // Compile the loaded template
846 $this->compileCode($code, $template);
848 } // END - foreach ($this->loadedRawData ...
850 // Insert all templates
851 $this->insertAllTemplates($templateMatches);
853 } // END - if (count($this->loadedRawData) ...
857 * Getter for raw template data
859 * @return $rawTemplateData The raw data from the template
861 public final function getRawTemplateData () {
862 return $this->rawTemplateData;
866 * Getter for compiled templates
868 public final function getCompiledData () {
869 return $this->compiledData;
873 * Load a specified web template into the engine
875 * @param $template The web template we shall load which is
876 * located in "html" by default
879 public final function loadWebTemplate ($template) {
881 $this->setTemplateType($this->getConfigInstance()->readConfig("web_template_type"));
883 // Load the special template
884 $this->loadTemplate($template);
888 * Load a specified email template into the engine
890 * @param $template The email template we shall load which is
891 * located in "emails" by default
894 public final function loadEmailTemplate ($template) {
896 $this->setTemplateType($this->getConfigInstance()->readConfig("email_template_type"));
898 // Load the special template
899 $this->loadTemplate($template);
903 * Load a specified code template into the engine
905 * @param $template The code template we shall load which is
906 * located in "code" by default
909 public final function loadCodeTemplate ($template) {
911 $this->setTemplateType($this->getConfigInstance()->readConfig("code_template_type"));
913 // Load the special template
914 $this->loadTemplate($template);
918 * Compile all variables by inserting their respective values
922 public final function compileVariables () {
923 // Initialize the $content array
924 $validVar = $this->getConfigInstance()->readConfig("tpl_valid_var");
927 // Iterate through all variables
928 for ($idx = $this->varStack->getIterator(); $idx->valid(); $idx->next()) {
929 // Get current variable from the stack
930 $currVariable = $idx->current();
932 // Transfer it's name/value combination to the $content array
933 $dummy[$currVariable['name']] = $currVariable['value'];
937 // Prepare all configuration variables
938 $config = $this->configVariables;
940 // Remove some variables
942 unset($currVariable);
944 // Prepare the eval() command for comiling the template
945 $eval = sprintf("\$this->setCompiledData(\"%s\");",
946 addslashes($this->getRawTemplateData())
950 if (((defined('DEBUG_EVAL')) || (defined('DEBUG_ALL'))) && (is_object($this->getDebugInstance()))) $this->getDebugInstance()->output(sprintf("[%s:] Konstruierte PHP-Anweisung: <pre><em>%s</em></pre><br />\n",
955 // Run the constructed command. This will "compile" all variables in
960 * Compile all required templates into the current loaded one
963 * @throws UnexpectedTemplateTypeException If the template type is
965 * @throws InvalidArrayCountException If an unexpected array
966 * count has been found
968 public final function compileTemplate () {
969 // We will only work with template type "code" from configuration
970 if ($this->getTemplateType() != $this->getConfigInstance()->readConfig("code_template_type")) {
972 throw new UnexpectedTemplateTypeException(array($this, $this->getTemplateType(), $this->getConfigInstance()->readConfig("code_template_type")), self::EXCEPTION_TEMPLATE_TYPE_IS_UNEXPECTED);
975 // Get the raw data. Thanks to Flobee(R) for given me a hint using the
976 // modifier "m" in regular expressions. I had implemented a regex here
977 // like this: (\n|\r)
978 $rawData = $this->getRawTemplateData();
980 // Remove double spaces and trim leading/trailing spaces
981 $rawData = trim(str_replace(" ", " ", $rawData));
983 // Search for raw variables
984 $this->extractVariablesFromRawData($rawData);
986 // Search for code-tags which are {? ?}
987 @preg_match_all($this->regExpCodeTags, $rawData, $templateMatches);
989 // Analyze the matches array
990 if ((is_array($templateMatches)) && (count($templateMatches) == 4) && (count($templateMatches[0]) > 0)) {
991 // Entries are found:
994 $this->analyzeTemplate($templateMatches);
996 // Compile raw template data
997 $this->compileRawTemplateData($templateMatches);
999 // Are there some raw templates left for loading?
1000 $this->loadExtraRawTemplates();
1002 // Are some raw templates found and loaded?
1003 if (count($this->rawTemplates) > 0) {
1004 die("NOT YET IMPLEMENTED");
1006 } // END - if($templateMatches ...
1010 * Output the compiled page to the outside world. In case of web templates
1011 * this would be vaild (X)HTML code. And in case of email templates this
1012 * would store a prepared email body inside the template engine.
1016 public final function output () {
1017 // Check which type of template we have
1018 switch ($this->getTemplateType()) {
1019 case "html": // Raw HTML templates can be send to the output buffer
1021 $this->getWebOutputInstance()->output($this->getCompiledData());
1024 default: // Unknown type found
1025 if ((is_object($this->getDebugInstance())) && (method_exists($this->getDebugInstance(), 'output'))) {
1026 // Use debug output handler
1027 $this->getDebugInstance()->output(sprintf("[%s:] Unbekannter Template-Typ <strong>%s</strong> erkannt.",
1028 $this->__toString(),
1029 $this->getTemplateType()
1034 // DO NOT REWRITE THIS TO app_die() !!!
1035 die(sprintf("[%s:] Unbekannter Template-Typ <strong>%s</strong> erkannt.",
1036 $this->__toString(),
1037 $this->getTemplateType()
1045 * Loads a given view helper (by name)
1047 * @param $helperName The helper's name
1049 * @throws ViewHelperNotFoundException If the given view helper was not found
1051 protected function loadViewHelper ($helperName) {
1052 // Make first character upper case, rest low
1053 $helperName = ucfirst($helperName);
1055 // Is this view helper loaded?
1056 if (!isset($this->helpers[$helperName])) {
1057 // Create a class name
1058 $className = "{$helperName}ViewHelper";
1060 // Does this class exists?
1061 if (!class_exists($className)) {
1063 throw new ViewHelperNotFoundException(array($this, $helperName), self::EXCEPTION_INVALID_VIEW_HELPER);
1066 // Generate new instance
1067 $eval = sprintf("\$this->helpers[%s] = %s::create%s();",
1077 // Return the requested instance
1078 return $this->helpers[$helperName];