function SmallTAL_Compiler(&$returnValue, $template, $page, $variables = null, $directories = null)
 {
     $compilerData = array('metal' => array(), 'keywords' => array('define', 'condition', 'repeat', 'replace', 'content', 'omit-tag', 'attributes'), 'regexp' => array('tag' => '/<((?:\\w+:)?\\w+)(\\s+[^<>]+?)?\\s*(\\/)?>/i', 'tagWithTal' => '/<((?:\\w+:)?\\w+)(\\s+[^<>]+?)??\\s+tal:(?:define|condition|repeat|replace|content|attributes|omit-tag)=([\'"])(.*?)\\3(\\s+[^<>]+?)??\\s*(\\/)?>/i', 'tagWithAttribute' => '/<((?:\\w+:)?\\w+)(\\s+[^<>]+?)??\\s+%s=([\'"])(.*?)\\3(\\s+[^<>]+?)??\\s*(\\/)?>/i', 'xmlns' => '/<html(\\s+[^<>]+?)??\\s+xmlns:%s=([\'"])(.*?)\\2(\\s+[^<>]+?)??\\s*(\\/)?>/i', 'xmlDeclaration' => '/^(?:\\s*<(\\?xml.*?\\?>))/', 'tagAttributes' => '/(?<=\\s)((?:[\\w-]+\\:)?[\\w-]+)=(?:([\'"])(.*?)\\2|([^>\\s\'"]+))/'));
     if (file_exists($directories['templates']) && is_dir($directories['templates']) && file_exists($directories['templates'] . '/' . $template) && is_dir($directories['templates'] . '/' . $template) && (file_exists($directories['temp']) || mkdir($directories['temp'], 0700)) && is_dir($directories['temp'])) {
         if (file_exists($directories['templates'] . '/' . $template . '.metal.html') && false !== ($metalContent = file_get_contents($directories['templates'] . '/' . $template . '.metal.html'))) {
             SmallTAL_Compiler_ParseMETAL($returnValue, $compilerData, $metalContent, false);
         }
         if (file_exists($directories['templates'] . '/' . $template . '/' . $page . '.html') && false !== ($content = file_get_contents($directories['templates'] . '/' . $template . '/' . $page . '.html'))) {
             SmallTAL_Compiler_ParseMETAL($returnValue, $compilerData, $content, true);
             $results = array();
             // Searching for the metal:use-macro attribute
             if (preg_match_all(sprintf($compilerData['regexp']['tagWithAttribute'], 'metal:use-macro'), $content, $results, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {
                 for ($i = count($results) - 1; $i > -1; $i--) {
                     if (array_key_exists($results[$i][4][0], $compilerData['metal'])) {
                         $position = $results[$i][0][1] + strlen($results[$i][0][0]);
                         if (!array_key_exists(6, $results[$i])) {
                             $position = SmallTAL_Compiler_FindEndTag($content, $results[$i][1][0], $position);
                         }
                         $tmpVariable = substr($content, $results[$i][0][1], $position - $results[$i][0][1]);
                         $macro = $compilerData['metal'][$results[$i][4][0]];
                         // Searching for slots
                         if (!array_key_exists(6, $results[$i])) {
                             $resultsSlots = array();
                             $slots = array();
                             if (preg_match_all(sprintf($compilerData['regexp']['tagWithAttribute'], 'metal:fill-slot'), $tmpVariable, $resultsSlots, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {
                                 for ($j = count($resultsSlots) - 1; $j > -1; $j--) {
                                     if (array_key_exists($resultsSlots[$j][4][0], $slots)) {
                                         SmallTAL_AddError($returnValue, constant('SmallTAL_Error_DuplicatedSlot'), $slotName);
                                     }
                                     $slots[$resultsSlots[$j][4][0]] = preg_replace(sprintf($compilerData['regexp']['tagWithAttribute'], 'metal:fill-slot'), '<${1}${2}${5}${6}>', substr($tmpVariable, $resultsSlots[$j][0][1], SmallTAL_Compiler_FindEndTag($tmpVariable, $resultsSlots[$j][1][0], $resultsSlots[$j][0][1] + strlen($resultsSlots[$j][0][0])) - $resultsSlots[$j][0][1]), -1, $count);
                                 }
                             }
                             if (0 < count($slots)) {
                                 if (preg_match_all(sprintf($compilerData['regexp']['tagWithAttribute'], 'metal:define-slot'), $macro, $resultsSlots, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {
                                     for ($j = count($resultsSlots) - 1; $j > -1; $j--) {
                                         if (array_key_exists($resultsSlots[$j][4][0], $slots)) {
                                             $macro = str_replace(substr($macro, $resultsSlots[$j][0][1], SmallTAL_Compiler_FindEndTag($compilerData['metal'][$macroName], $resultsSlots[$j][1][0], $resultsSlots[$j][0][1] + strlen($resultsSlots[$j][0][0])) - $resultsSlots[$j][0][1]), $resultsSlots[$j][4][0], $macro);
                                         } else {
                                             SmallTAL_AddError($returnValue, constant('SmallTAL_Error_UnknownSlot'), $results[$j][4][0]);
                                         }
                                     }
                                 }
                             }
                         }
                         $content = str_replace($tmpVariable, $macro, $content);
                     } else {
                         SmallTAL_AddError($returnValue, constant('SmallTAL_Error_UnknownMacro'), $results[$i][4][0]);
                     }
                 }
             }
             $output = '<?php if(defined(\'SmallTAL\')){$localVariables=array(\'defined\'=>array(),\'repeat\'=>array(),\'stack\'=>array(\'defined\'=>array(),\'repeat\'=>array()),\'template\'=>array());?>';
             $localVariablesIndex = 0;
             $count = 0;
             //TODO: Variables optimization round
             if (null != $content) {
                 if ($tagsCount = preg_match_all($compilerData['regexp']['tagWithTal'], $content, $tags, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {
                     $localVariablesIndex = 0;
                     for ($i = $tagsCount - 1; $i > -1; $i--) {
                         $tagAttributes = array();
                         $attributes = array();
                         if ($attributesCount = preg_match_all($compilerData['regexp']['tagAttributes'], $tags[$i][0][0], $attributes, PREG_SET_ORDER)) {
                             for ($j = 0; $j < $attributesCount; $j++) {
                                 $tagAttributes[$attributes[$j][1]] = empty($attributes[$j][2]) && array_key_exists(4, $attributes[$j]) ? $attributes[$j][4] : $attributes[$j][3];
                             }
                         }
                         unset($attributes);
                         $changes = array('attributes' => array(), 'outside' => array('pre' => null, 'post' => null), 'inside' => array('pre' => null, 'post' => null));
                         foreach ($compilerData['keywords'] as $keyword) {
                             if (array_key_exists('tal:' . $keyword, $tagAttributes)) {
                                 switch ($keyword) {
                                     case 'define':
                                         $tmpVariable = array();
                                         $tmpVariable['count'] = preg_match_all('/[\\s]*(?:(?:(local|world)[\\s]+)?(.+?)[\\s]+(.+?)[\\s]*(?:(?<!;);(?!;)|$))+?/', $tagAttributes['tal:define'], $tmpVariable['elements'], PREG_SET_ORDER);
                                         for ($j = 0; $j < $tmpVariable['count']; $j++) {
                                             $tmpVariable['name'] = str_replace('\'', '&#039', $tmpVariable['elements'][$j][2]);
                                             $changes['outside']['pre'] .= '$localVariables[\'template\'][' . $localVariablesIndex . ']=(' . SmallTAL_Compiler_ParseTALES($tmpVariable['elements'][$j][3], $tagAttributes, '$tmpVariable') . '&&!$tmpVariable[1]);if($localVariables[\'template\'][' . $localVariablesIndex++ . ']){SmallTAL_LocalVariablesPush($localVariables,\'defined\',\'' . $tmpVariable['name'] . '\',$tmpVariable[0]);}unset($tmpVariable);';
                                             if ('world' != $tmpVariable['elements'][$j][1]) {
                                                 $changes['outside']['post'] = 'if($localVariables[\'template\'][' . ($localVariablesIndex - 1) . ']){SmallTAL_LocalVariablesPop($localVariables,\'defined\',\'' . $tmpVariable['name'] . '\');unset($localVariables[\'template\'][' . ($localVariablesIndex - 1) . ']);}' . $changes['outside']['post'];
                                             }
                                         }
                                         unset($tmpVariable);
                                         break;
                                     case 'condition':
                                         $changes['outside']['pre'] .= 'if(' . SmallTAL_Compiler_ParseTALES($tagAttributes['tal:condition'], $tagAttributes, '$localVariables[\'template\'][' . $localVariablesIndex . ']', true, true) . '){';
                                         $changes['outside']['post'] = '}unset($localVariables[\'template\'][' . $localVariablesIndex++ . ']);' . $changes['outside']['post'];
                                         break;
                                     case 'repeat':
                                         $tmpVariable['elements'] = explode(" ", $tagAttributes['tal:repeat'], 2);
                                         $tmpVariable['name'] = str_replace('\'', '&#039', $tmpVariable['elements'][0]);
                                         $changes['outside']['pre'] .= sprintf('if((%1$s)&&($localVariables[\'template\'][%2$d][1]||is_array($localVariables[\'template\'][%2$d][0]))){$localVariables[\'template\'][%3$d]=array(false,false);if(!$localVariables[\'template\'][%2$d][1]){($localVariables[\'template\'][%3$d][0]=true)&&SmallTAL_LocalVariablesPush($localVariables,\'repeat\',\'%4$s\',null);($localVariables[\'template\'][%3$d][1]=true)&&SmallTAL_LocalVariablesPush($localVariables,\'defined\',\'%4$s\',null);$localVariables[\'repeat\'][\'%4$s\'][\'index\']=-1;$localVariables[\'repeat\'][\'%4$s\'][\'length\']=count($localVariables[\'template\'][%2$d][0]);}do{if(!$localVariables[\'template\'][%2$d][1]){$localVariables[\'defined\'][\'%4$s\']=array_shift($localVariables[\'template\'][%2$d][0]);$localVariables[\'repeat\'][\'%4$s\'][\'index\']++;$localVariables[\'repeat\'][\'%4$s\'][\'number\']=$localVariables[\'repeat\'][\'%4$s\'][\'index\']+1;$localVariables[\'repeat\'][\'%4$s\'][\'even\']=($localVariables[\'repeat\'][\'%4$s\'][\'number\']%%2?true:false);$localVariables[\'repeat\'][\'%4$s\'][\'odd\']=!$localVariables[\'repeat\'][\'%4$s\'][\'even\'];$localVariables[\'repeat\'][\'%4$s\'][\'start\']=($localVariables[\'repeat\'][\'%4$s\'][\'index\']?false:true);$localVariables[\'repeat\'][\'%4$s\'][\'end\']=(($localVariables[\'repeat\'][\'%4$s\'][\'number\']==$localVariables[\'repeat\'][\'%4$s\'][\'length\'])?true:false);$localVariables[\'repeat\'][\'%4$s\'][\'letter\']=SmallTAL_NumberToLetter($localVariables[\'repeat\'][\'%4$s\'][\'index\']);$localVariables[\'repeat\'][\'%4$s\'][\'Letter\']=strtoupper($localVariables[\'repeat\'][\'%4$s\'][\'letter\']);}', SmallTAL_Compiler_ParseTALES($tmpVariable['elements'][1], $tagAttributes, '$localVariables[\'template\'][' . $localVariablesIndex . ']'), $localVariablesIndex++, $localVariablesIndex, $tmpVariable['name']);
                                         $changes['outside']['post'] = sprintf('}while(!$localVariables[\'template\'][%1$d][1]&&!empty($localVariables[\'template\'][%1$d][0]));$localVariables[\'template\'][%2$d][0]&&SmallTAL_LocalVariablesPop($localVariables,\'repeat\',\'%3$s\');$localVariables[\'template\'][%2$d][1]&&SmallTAL_LocalVariablesPop($localVariables,\'defined\',\'%3$s\');unset($localVariables[\'template\'][%1$d],$localVariables[\'template\'][%2$d]);}', $localVariablesIndex - 1, $localVariablesIndex++, $tmpVariable['name']) . $changes['outside']['post'];
                                         break;
                                     case 'replace':
                                     case 'content':
                                         if ('content' == $keyword || 'replace' == $keyword && !array_key_exists('tal:content', $tagAttributes)) {
                                             $tmpVariable = array();
                                             if ('structure ' == substr($tagAttributes['tal:' . $keyword], 0, 10) || 'text ' == substr($tagAttributes['tal:' . $keyword], 0, 5)) {
                                                 $tmpVariable['parameters'] = explode(" ", 'content' == $keyword ? $tagAttributes['tal:content'] : $tagAttributes['tal:replace'], 2);
                                             } else {
                                                 $tmpVariable['parameters'] = array("text", $tagAttributes['tal:' . $keyword]);
                                             }
                                             $tmpVariable['pre'] = 'if(' . SmallTAL_Compiler_ParseTALES($tmpVariable['parameters'][1], $tagAttributes, '$localVariables[\'template\'][' . $localVariablesIndex . ']') . '&&!$localVariables[\'template\'][' . $localVariablesIndex . '][1]&&!is_null($localVariables[\'template\'][' . $localVariablesIndex . '][0])){echo(' . ('text' == $tmpVariable['parameters'][0] ? 'str_replace(array(\'&\',\'<\',\'>\'),array(\'&amp\',\'&lt\',\'&gt\'),' : null) . '(is_bool($localVariables[\'template\'][' . $localVariablesIndex . '][0])?($localVariables[\'template\'][' . $localVariablesIndex . '][0]?1:0):$localVariables[\'template\'][' . $localVariablesIndex . '][0])' . ('text' == $tmpVariable['parameters'][0] ? ')' : null) . ');}elseif($localVariables[\'template\'][' . $localVariablesIndex . '][1]){';
                                             $tmpVariable['post'] = '}unset($localVariables[\'template\'][' . $localVariablesIndex++ . ']);';
                                             if ('content' == $keyword) {
                                                 $changes['inside']['pre'] = $tmpVariable['pre'] . $changes['inside']['pre'];
                                                 $changes['inside']['post'] .= $tmpVariable['post'];
                                             } else {
                                                 $changes['outside']['pre'] .= $tmpVariable['pre'];
                                                 $changes['outside']['post'] = $tmpVariable['post'] . $changes['outside']['post'];
                                             }
                                             unset($tmpVariable);
                                         }
                                         break;
                                     case 'attributes':
                                         if (!array_key_exists('tal:content', $tagAttributes)) {
                                             $tmpVariable = array();
                                             $tmpVariable['count'] = preg_match_all('/(?:[\\s]*(.+?)[\\s]+(.+?)[\\s]*(?:(?<!;);(?!;)|$))+?/', $tagAttributes['tal:attributes'], $tmpVariable['elements'], PREG_SET_ORDER);
                                             for ($j = 0; $j < $tmpVariable['count']; $j++) {
                                                 $changes['attributes'][$tmpVariable['elements'][$j][1]] = $tmpVariable['elements'][$j][2];
                                             }
                                         }
                                         break;
                                     case 'omit-tag':
                                         $changes['outside']['pre'] .= '$localVariables[\'template\'][' . $localVariablesIndex . ']=!(' . SmallTAL_Compiler_ParseTALES($tagAttributes['tal:omit-tag'], $tagAttributes, '$tmpVariable', true) . ');unset($tmpVariable);if($localVariables[\'template\'][' . $localVariablesIndex . ']){';
                                         // If isn't selfclosed OR if I already need to put some code between starting and closing tag, I put some data "inside"
                                         // TODO: a regexp to remove ? >< ?php and {}
                                         if (!array_key_exists(6, $tags[$i]) || isset($changes['inside']['pre']) || isset($changes['inside']['post']) || 0 < count($changes['attributes'])) {
                                             $changes['inside']['pre'] = '}' . $changes['inside']['pre'];
                                             $changes['inside']['post'] .= 'if($localVariables[\'template\'][' . $localVariablesIndex . ']){';
                                         }
                                         $changes['outside']['post'] = '}unset($localVariables[\'template\'][' . $localVariablesIndex++ . ']);' . $changes['outside']['post'];
                                         break;
                                 }
                             }
                         }
                         if (0 < count($changes['attributes']) || isset($changes['outside']['pre']) || isset($changes['outside']['post']) || isset($changes['inside']['pre']) || isset($changes['inside']['post'])) {
                             $tmpVariable = array();
                             $tmpVariable['startTag'] = $tags[$i][0][0];
                             $tmpVariable['attributes'] = null;
                             foreach ($changes['attributes'] as $name => $value) {
                                 $tmpVariable['attributes'] .= '<?php if(' . SmallTAL_Compiler_ParseTALES($value, $tagAttributes, '$tmpVariable') . (!array_key_exists($name, $tagAttributes) ? '&&!$tmpVariable[1]' : null) . '){?> ' . $name . '="<?php echo(' . (array_key_exists($name, $tagAttributes) ? '$tmpVariable[1]?\'' . str_replace('\'', '&#039', $tagAttributes[$name]) . '\':' : null) . '(is_bool($tmpVariable[0])?($tmpVariable[0]?1:0):$tmpVariable[0]));?>"<?php }unset($tmpVariable);?>';
                             }
                             foreach ($tagAttributes as $name => $value) {
                                 if (array_key_exists($name, $changes['attributes']) || 'xmlns:tal' == $name || 'tal:' == substr($name, 0, 4)) {
                                     $tmpVariable['startTag'] = preg_replace(sprintf($compilerData['regexp']['tagWithAttribute'], $name), '<${1}${2}${5}${6}>', $tmpVariable['startTag']);
                                 }
                             }
                             if ($tags[$i][0][0] != $tmpVariable['startTag']) {
                                 $content = substr_replace($content, $tmpVariable['startTag'], $tags[$i][0][1], strlen($tags[$i][0][0]));
                             }
                             $tmpVariable['startLength'] = strlen($tmpVariable['startTag']);
                             $tmpVariable['endPosition'] = $tags[$i][0][1] + $tmpVariable['startLength'];
                             $tmpVariable['endLength'] = 0;
                             $tmpVariable['startTagSelfClosed'] = array_key_exists(6, $tags[$i]);
                             $tmpVariable['startTag'] = substr($tmpVariable['startTag'], 0, -($tmpVariable['startTagSelfClosed'] ? 2 : 1));
                             if ($tmpVariable['startTagSelfClosed'] && (isset($changes['inside']['pre']) || isset($changes['inside']['post']))) {
                                 $content = substr_replace($content, $tmpVariable['startTag'] . '></' . $tags[$i][1][0] . '>', $tags[$i][0][1], $tmpVariable['startLength']);
                                 $tmpVariable['startTagSelfClosed'] = false;
                                 $tmpVariable['endPosition'] += strlen($tags[$i][1][0]) + 2;
                                 $tmpVariable['endLength'] = strlen($tags[$i][1][0]) + 3;
                                 $tmpVariable['startLength'] -= 1;
                             } elseif (!$tmpVariable['startTagSelfClosed']) {
                                 $tmpVariable['endPosition'] = SmallTAL_Compiler_FindEndTag($content, $tags[$i][1][0], $tmpVariable['endPosition'], $tmpVariable['endLength']);
                             }
                             // If is an empty node and we need to write inside it, we need an optimization round
                             if ($tmpVariable['endPosition'] - $tmpVariable['endLength'] == $tags[$i][0][1] + strlen($tmpVariable['startTag']) + ($tmpVariable['startTagSelfClosed'] ? 2 : 1) && isset($changes['inside']['pre']) && isset($changes['inside']['post'])) {
                                 $changes['inside']['pre'] .= $changes['inside']['post'];
                                 $changes['inside']['post'] = null;
                                 $changes['inside']['pre'] = str_replace('else{}', '', $changes['inside']['pre']);
                             }
                             if (!$tmpVariable['startTagSelfClosed'] || isset($changes['inside']['post']) || isset($changes['outside']['post'])) {
                                 $content = substr_replace($content, (isset($changes['inside']['post']) ? '<?php ' . $changes['inside']['post'] . '?>' : null) . substr($content, $tmpVariable['endPosition'] - $tmpVariable['endLength'], $tmpVariable['endLength']) . (isset($changes['outside']['post']) ? '<?php ' . $changes['outside']['post'] . '?>' : null), $tmpVariable['endPosition'] - $tmpVariable['endLength'], $tmpVariable['endLength']);
                             }
                             if (isset($tmpVariable['attributes']) || isset($changes['outside']['pre']) || isset($changes['inside']['pre'])) {
                                 $content = substr_replace($content, (isset($changes['outside']['pre']) ? '<?php ' . $changes['outside']['pre'] . '?>' : null) . $tmpVariable['startTag'] . $tmpVariable['attributes'] . ($tmpVariable['startTagSelfClosed'] ? ' /' : null) . '>' . (isset($changes['inside']['pre']) ? '<?php ' . $changes['inside']['pre'] . '?>' : null), $tags[$i][0][1], $tmpVariable['startLength']);
                             }
                             unset($tmpVariable);
                         }
                     }
                 }
             }
             $content = preg_replace(array(sprintf($compilerData['regexp']['xmlns'], 'tal'), sprintf($compilerData['regexp']['xmlns'], 'metal')), '<html${1}${4}${5}>', $content);
             $output .= str_replace("?>\n", "?>\n\n", str_replace("\r", '', $content)) . '<?php }?>';
             $file = null;
             if (false !== ($temporaryFilename = tempnam($directories['temp'], 'TAL')) && false !== ($file = fopen($temporaryFilename, 'wb'))) {
                 fwrite($file, $output);
                 fclose($file);
                 if ((file_exists($directories['cache']) || mkdir($directories['cache'], 0700)) && is_dir($directories['cache']) && (file_exists($directories['cache'] . '/' . $template) || mkdir($directories['cache'] . '/' . $template, 0700)) && is_dir($directories['cache'] . '/' . $template)) {
                     if (!rename($temporaryFilename, $directories['cache'] . '/' . $template . '/' . $page . '.php')) {
                         SmallTAL_AddError($returnValue, constant('SmallTAL_Error_Rename'), $temporaryFilename);
                     }
                 } else {
                     SmallTAL_AddError($returnValue, constant('SmallTAL_Error_Cache'), null);
                 }
             } else {
                 SmallTAL_AddError($returnValue, constant('SmallTAL_Error_TemporaryFile'), null);
             }
         } else {
             SmallTAL_AddError($returnValue, constant('SmallTAL_Error_Template'), null);
         }
     } else {
         SmallTAL_AddError($returnValue, constant('SmallTAL_Error_Path'), null);
     }
 }
Esempio n. 2
0
 function SmallTAL($template, $page, $variables = null, $directories = null)
 {
     $returnValue = array('errorCode' => constant('SmallTAL_Error_None'));
     if (is_null($variables) || !is_array($variables)) {
         $variables = array();
     }
     if (array_key_exists('CONTEXT', $variables)) {
         unset($variables['CONTEXT']);
     }
     if (is_null($directories) || !is_array($directories)) {
         $directories = array();
     }
     $elements = array('templates', 'cache', 'temp');
     foreach ($elements as $element) {
         if (!array_key_exists($element, $directories)) {
             $directories[$element] = $element;
         }
         if (DIRECTORY_SEPARATOR == $directories[$element][strlen($directories[$element]) - 1]) {
             $directories[$element] = substr($directories[$element], 0, -1);
         }
     }
     if (file_exists($directories['templates'] . DIRECTORY_SEPARATOR . $template . DIRECTORY_SEPARATOR . $page . '.html')) {
         if ((file_exists($directories['cache']) || mkdir($directories['cache'], 0700)) && is_dir($directories['cache']) && ((file_exists($directories['cache'] . DIRECTORY_SEPARATOR . $template) || mkdir($directories['cache'] . DIRECTORY_SEPARATOR . $template, 0700)) && is_dir($directories['cache'] . DIRECTORY_SEPARATOR . $template))) {
             if (file_exists($directories['cache'] . DIRECTORY_SEPARATOR . $template . DIRECTORY_SEPARATOR . $page . '.php')) {
                 $filesMTime = array('templateFile' => filemtime($directories['templates'] . DIRECTORY_SEPARATOR . $template . DIRECTORY_SEPARATOR . $page . '.html'), 'metalFile' => file_exists($tmpVariable = $directories['templates'] . DIRECTORY_SEPARATOR . $template . '.metal.html') ? filemtime($tmpVariable) : time(), 'smallTAL' => filemtime(__FILE__), 'smallTALCompiler' => filemtime('SmallTAL.Compiler.php'));
                 $tmpVariable = filemtime($directories['cache'] . DIRECTORY_SEPARATOR . $template . DIRECTORY_SEPARATOR . $page . '.php');
                 $delete = false;
                 while (!$delete && ($fileMTime = array_pop($filesMTime))) {
                     if ($tmpVariable < $fileMTime) {
                         $delete = true;
                     }
                 }
                 if ($delete) {
                     unlink($directories['cache'] . DIRECTORY_SEPARATOR . $template . DIRECTORY_SEPARATOR . $page . '.php');
                 }
             }
             if (!file_exists($directories['cache'] . DIRECTORY_SEPARATOR . $template . DIRECTORY_SEPARATOR . $page . '.php')) {
                 require_once 'SmallTAL.Compiler.php';
                 SmallTAL_Compiler($returnValue, $template, $page, $variables, $directories);
             }
             if (file_exists($directories['cache'] . DIRECTORY_SEPARATOR . $template . DIRECTORY_SEPARATOR . $page . '.php')) {
                 include $directories['cache'] . DIRECTORY_SEPARATOR . $template . DIRECTORY_SEPARATOR . $page . '.php';
             } else {
                 SmallTAL_AddError($returnValue, constant('SmallTAL_Error_Cache'), $directories['cache'] . DIRECTORY_SEPARATOR . $template . DIRECTORY_SEPARATOR . $page . '.php');
             }
         } else {
             SmallTAL_AddError($returnValue, constant('SmallTAL_Error_Path'), null);
         }
     } else {
         SmallTAL_AddError($returnValue, constant('SmallTAL_Error_Template'), $directories['templates'] . DIRECTORY_SEPARATOR . $template . DIRECTORY_SEPARATOR . $page . '.html');
     }
     return $returnValue;
 }