Index: trunk/core/kernel/parser/construct_tags.php =================================================================== diff -u -N -r6583 -r8605 --- trunk/core/kernel/parser/construct_tags.php (.../construct_tags.php) (revision 6583) +++ trunk/core/kernel/parser/construct_tags.php (.../construct_tags.php) (revision 8605) @@ -1,5 +1,8 @@ Tag != 'block' && $tag->Tag != 'DefineElement') { + // && ($tag->Tag != 'RenderElement' && isset($tag->NP['_short_closing_'])) + if ($tag->Tag != 'block' && $tag->Tag != 'DefineElement' && $tag->Tag != 'Capture' && !($tag->Tag == 'RenderElement' && isset($tag->NP['_short_closing_']))) { $this->Parser->AppendCode($tag->GetCode()); } // $this->Parser->AppendCompiledCode( $tag->GetCode() ); @@ -170,12 +174,18 @@ switch ($this->Tag) { case 'block': case 'DefineElement': + case 'RenderElement': if ($this->Tag == 'DefineElement') { $this->SetStopTag('end_define'); //This recursion level should end when 'blockend' is found } else { $this->SetStopTag('blockend'); //This recursion level should end when 'blockend' is found } + if ($this->Tag == 'RenderElement') { + $this->NP['name'] = '__lambda_element_'.$this->Application->LambdaElements++; + $RenderTag =& new Tag($this->TagData.' name="'.$this->NP['name'].'"', $this->Parser); + $this->Parser->AppendCode($RenderTag->GetCode()); + } $this->Parser->Recurve($this); //Saving current tag in parser recursion array $this->Parser->SetBuffer(''); $this->BlockName = $this->NP['name']; //Stroing BlockName @@ -246,12 +256,23 @@ //caching func body $this->Application->PreParsedCache[$this->BlockName] = $f_body; - $func = create_function('$params', $f_body); + $compile_body = preg_replace('/\/\*COMPILE-ONLY\*\/.*/m', '', $f_body); + + $func = create_function('$params', $compile_body); $this->Application->PreParsedBlocks[$this->BlockName] = $func; $this->Parser->Args = null; $this->Parser->ResetCode(); - $this->Parser->AppendCompiledFunction($this->BlockName, $f_body); + $real_name = $this->Parser->AppendCompiledFunction($this->BlockName, $f_body); + + if ($this->Tag == 'RenderElement') { + $RenderTag =& new Tag($this->TagData.' name="'.$this->BlockName.'"', $this->Parser); +// $this->Parser->AppendCompiledCode($RenderTag->GetCode()); + + // for compilation run + $RenderTag->Process(); + } + } return true; } @@ -274,4 +295,84 @@ } } +class CaptureTag extends ConstructTag { + var $VarName = null; + var $Mode = CM_LATE_PARSE; + + function Process() + { + switch ($this->Tag) { + case 'Capture': + $this->Parser->Recurve($this); //Saving current tag in parser recursion array + $this->Parser->SetBuffer(''); + $this->VarName = $this->NP['to_var']; //Stroing BlockName + $this->StoreSkipMode(); + + if (isset($this->NP['mode']) && $this->NP['mode'] == 'parse_now') { + $this->Mode = CM_PARSE; + } + $this->SuggestSkipMode(skip_tags); + break; + } + } + + function RunCapture($f, $func, $cur_lambda) + { + $code = array(); + $code[] = '/*COMPILE-ONLY*/ '.$f[2]; + $code[] = '/*LAMBDA-ONLY*/ $application->PreParsedBlocks[\'capture_'.$this->VarName.'\'] = $application->PreParsedBlocks[\'capture_'.$this->VarName.$cur_lambda.'\'];'; + $code[] = '$__f = $application->PreParsedBlocks[\'capture_'.$this->VarName.'\'];'; + $code[] = '$application->Parser->SetParam(\''.$this->VarName.'\', $__f(array())'.');'; + $code[] = '$'.$this->VarName.' = $application->Parser->GetParam(\''.$this->VarName.'\');'; + $code[] = '$params[\''.$this->VarName.'\'] = $'.$this->VarName.';'; + if ($this->Parser->RecursionIndex > 1) { + $this->Parser->AppendCode($code, -1); + } + else { + $this->Application->Parser->SetParam($this->VarName, $func(array())); + $this->Parser->AppendCompiledCode($code); + } + } + + function CheckRecursion(&$tag) + { + if (parent::CheckRecursion($tag)) { //if endtag matches (SkipMode would be restored then) + $f_code = $this->Parser->GetCode(); + array_unshift($f_code, '$o = \'\';'); + array_unshift($f_code, '$application =& kApplication::Instance();'); + $f_code[] = 'return $o;'; + + $f = $this->Parser->PrepareCompiledFunction('capture_'.$this->VarName, $f_code, false); + $f_code = trim(join("\n\t", $f_code)); + $func = create_function('$params', $f_code); + $this->Application->PreParsedBlocks['capture_'.$this->VarName] = $func; + $cur_lambda = $this->Application->LambdaElements++; + $this->Application->PreParsedBlocks['capture_'.$this->VarName.$cur_lambda] = $func; + + $this->Parser->AppendCompiledCode($f[1]); + + if ($this->Mode == CM_PARSE) { + $this->RunCapture($f, $func, $cur_lambda); + } + elseif ($this->Mode == CM_LATE_PARSE) { + $code = array(); + $code[] = '/*COMPILE-ONLY*/ '.$f[2]; + $code[] = '/*LAMBDA-ONLY*/ $application->PreParsedBlocks[\'capture_'.$this->VarName.'\'] = $application->PreParsedBlocks[\'capture_'.$this->VarName.$cur_lambda.'\'];'; + $code[] = '$application->LateParsed[\''.$this->VarName.'\'] = '.$cur_lambda.';'; + if ($this->Parser->RecursionIndex > 1) { + $this->Parser->AppendCode($code, -1); + } + else { + $this->Parser->AppendCompiledCode($code); + } + $this->Application->LateParsed[$this->VarName] = $cur_lambda; + } + $this->Parser->ResetCode(); + return true; + } + return ($tag->Tag == $this->StopTag); //Tag matches StopTag we are waiting for to close current recursion + } + +} + ?> \ No newline at end of file