- update template inheritance processing

This commit is contained in:
uwetews
2015-09-14 23:46:17 +02:00
parent 71c1b32c51
commit 8d734a9d52
8 changed files with 59 additions and 35 deletions

View File

@@ -2,6 +2,7 @@
14.09.2015 14.09.2015
- optimize autoloader - optimize autoloader
- optimize subtemplate handling - optimize subtemplate handling
- update template inheritance processing
30.08.2015 30.08.2015
- size optimization move some runtime functions into extension - size optimization move some runtime functions into extension

View File

@@ -119,7 +119,7 @@ class Smarty extends Smarty_Internal_TemplateBase
/** /**
* smarty version * smarty version
*/ */
const SMARTY_VERSION = '3.1.28-dev/56'; const SMARTY_VERSION = '3.1.28-dev/57';
/** /**
* define variable scopes * define variable scopes

View File

@@ -65,7 +65,7 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
*/ */
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter) public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
{ {
if ($compiler->blockTagNestingLevel == 0 && $compiler->template->isChild) { if ($compiler->blockTagNestingLevel == 0 && $compiler->inheritanceChild) {
$this->option_flags = array('hide', 'nocache', 'append', 'prepend'); $this->option_flags = array('hide', 'nocache', 'append', 'prepend');
} else { } else {
$this->option_flags = array('hide', 'nocache'); $this->option_flags = array('hide', 'nocache');
@@ -101,7 +101,8 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
static function compileChildBlock(Smarty_Internal_TemplateCompilerBase $compiler, $_name = null) static function compileChildBlock(Smarty_Internal_TemplateCompilerBase $compiler, $_name = null)
{ {
if (!$compiler->blockTagNestingLevel) { if (!$compiler->blockTagNestingLevel) {
$compiler->trigger_template_error(' tag {$smarty.block.child} used outside {block} tags ', $compiler->parser->lex->taglineno); $compiler->trigger_template_error(' tag {$smarty.block.child} used outside {block} tags ',
$compiler->parser->lex->taglineno);
} }
$compiler->has_code = true; $compiler->has_code = true;
$compiler->suppressNocacheProcessing = true; $compiler->suppressNocacheProcessing = true;
@@ -120,11 +121,13 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
*/ */
static function compileParentBlock(Smarty_Internal_TemplateCompilerBase $compiler, $_name = null) static function compileParentBlock(Smarty_Internal_TemplateCompilerBase $compiler, $_name = null)
{ {
if (!$compiler->template->isChild) { if (!$compiler->inheritanceChild) {
$compiler->trigger_template_error(' tag {$smarty.block.parent} used in parent template ', $compiler->parser->lex->taglineno); $compiler->trigger_template_error(' tag {$smarty.block.parent} used in parent template ',
$compiler->parser->lex->taglineno);
} }
if (!$compiler->blockTagNestingLevel) { if (!$compiler->blockTagNestingLevel) {
$compiler->trigger_template_error(' tag {$smarty.block.parent} used outside {block} tags ', $compiler->parser->lex->taglineno); $compiler->trigger_template_error(' tag {$smarty.block.parent} used outside {block} tags ',
$compiler->parser->lex->taglineno);
} }
$compiler->suppressNocacheProcessing = true; $compiler->suppressNocacheProcessing = true;
$compiler->has_code = true; $compiler->has_code = true;
@@ -157,8 +160,8 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase
// setup buffer for template function code // setup buffer for template function code
$compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template(); $compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
$_funcNameCaching = $_funcName = preg_replace('![^\w]+!', '_', "block_function_{$_name}_" . $_funcNameCaching =
uniqid(rand(), true)); $_funcName = preg_replace('![^\w]+!', '_', "block_function_{$_name}_" . uniqid(rand(), true));
if ($compiler->template->compiled->has_nocache_code) { if ($compiler->template->compiled->has_nocache_code) {
// $compiler->parent_compiler->template->tpl_function[$_name]['call_name_caching'] = $_funcNameCaching; // $compiler->parent_compiler->template->tpl_function[$_name]['call_name_caching'] = $_funcNameCaching;
$_funcNameCaching .= '_nocache'; $_funcNameCaching .= '_nocache';
@@ -168,34 +171,47 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase
$output .= "function {$_funcNameCaching} (\$_smarty_tpl, \$block) {\n"; $output .= "function {$_funcNameCaching} (\$_smarty_tpl, \$block) {\n";
$output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n"; $output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n";
$output .= "\$_smarty_tpl->cached->hashes['{$compiler->template->compiled->nocache_hash}'] = true;\n?>\n"; $output .= "\$_smarty_tpl->cached->hashes['{$compiler->template->compiled->nocache_hash}'] = true;\n?>\n";
$compiler->parser->current_buffer->append_subtree($compiler->parser, new Smarty_Internal_ParseTree_Tag($compiler->parser, $output)); $compiler->parser->current_buffer->append_subtree($compiler->parser,
new Smarty_Internal_ParseTree_Tag($compiler->parser,
$output));
$compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode); $compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
$output = "<?php /*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n"; $output = "<?php /*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n";
$output .= "\n}\n}\n"; $output .= "\n}\n}\n";
$output .= "/*/ {$_funcName}_nocache */\n\n"; $output .= "/*/ {$_funcName}_nocache */\n\n";
$output .= "?>\n"; $output .= "?>\n";
$compiler->parser->current_buffer->append_subtree($compiler->parser, new Smarty_Internal_ParseTree_Tag($compiler->parser, $output)); $compiler->parser->current_buffer->append_subtree($compiler->parser,
$compiler->parent_compiler->templateFunctionCode .= $f = $compiler->parser->current_buffer->to_smarty_php($compiler->parser); new Smarty_Internal_ParseTree_Tag($compiler->parser,
$output));
$compiler->parent_compiler->templateFunctionCode .= $f =
$compiler->parser->current_buffer->to_smarty_php($compiler->parser);
$compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template(); $compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
$_functionCode = new Smarty_Internal_ParseTree_Tag($compiler->parser, preg_replace_callback("/((<\?php )?echo '\/\*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%\*\/([\S\s]*?)\/\*\/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%\*\/';(\?>\n)?)/", array($this, $_functionCode = new Smarty_Internal_ParseTree_Tag($compiler->parser,
'removeNocache'), $_functionCode->to_smarty_php($compiler->parser))); preg_replace_callback("/((<\?php )?echo '\/\*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%\*\/([\S\s]*?)\/\*\/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%\*\/';(\?>\n)?)/",
array($this, 'removeNocache'),
$_functionCode->to_smarty_php($compiler->parser)));
} }
$output = "<?php\n"; $output = "<?php\n";
$output .= "/* {$_funcName} {$compiler->template->source->type}:{$compiler->template->source->name} */\n"; $output .= "/* {$_funcName} {$compiler->template->source->type}:{$compiler->template->source->name} */\n";
$output .= "if (!function_exists('{$_funcName}')) {\n"; $output .= "if (!function_exists('{$_funcName}')) {\n";
$output .= "function {$_funcName}(\$_smarty_tpl, \$block) {?>"; $output .= "function {$_funcName}(\$_smarty_tpl, \$block) {?>";
$compiler->parser->current_buffer->append_subtree($compiler->parser, new Smarty_Internal_ParseTree_Tag($compiler->parser, $output)); $compiler->parser->current_buffer->append_subtree($compiler->parser,
new Smarty_Internal_ParseTree_Tag($compiler->parser,
$output));
$compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode); $compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
$output = "<?php\n}\n}\n"; $output = "<?php\n}\n}\n";
$output .= "/*/ {$_funcName} */\n"; $output .= "/*/ {$_funcName} */\n";
$output .= "?>\n"; $output .= "?>\n";
$compiler->parser->current_buffer->append_subtree($compiler->parser, new Smarty_Internal_ParseTree_Tag($compiler->parser, $output)); $compiler->parser->current_buffer->append_subtree($compiler->parser,
$compiler->parent_compiler->templateFunctionCode .= $f = $compiler->parser->current_buffer->to_smarty_php($compiler->parser); new Smarty_Internal_ParseTree_Tag($compiler->parser,
$output));
$compiler->parent_compiler->templateFunctionCode .= $f =
$compiler->parser->current_buffer->to_smarty_php($compiler->parser);
// nocache plugins must be copied // nocache plugins must be copied
if (!empty($compiler->template->compiled->required_plugins['nocache'])) { if (!empty($compiler->template->compiled->required_plugins['nocache'])) {
foreach ($compiler->template->compiled->required_plugins['nocache'] as $plugin => $tmp) { foreach ($compiler->template->compiled->required_plugins['nocache'] as $plugin => $tmp) {
foreach ($tmp as $type => $data) { foreach ($tmp as $type => $data) {
$compiler->parent_compiler->template->compiled->required_plugins['compiled'][$plugin][$type] = $data; $compiler->parent_compiler->template->compiled->required_plugins['compiled'][$plugin][$type] =
$data;
} }
} }
} }
@@ -216,13 +232,15 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase
unset($compiler->callChildBlock[$compiler->blockTagNestingLevel]); unset($compiler->callChildBlock[$compiler->blockTagNestingLevel]);
} }
$compiler->blockTagNestingLevel --; $compiler->blockTagNestingLevel --;
if ($compiler->blockTagNestingLevel == 0 && $compiler->template->isChild) { // inner {block} or child template {block} must register block
if ($compiler->blockTagNestingLevel == 0 && $compiler->inheritanceChild) {
$_function = 'register'; $_function = 'register';
} else { } else {
$_function = 'call'; $_function = 'call';
} }
$cm = $compiler->template->caching ? 'true' : 'false'; $cm = $compiler->template->caching ? 'true' : 'false';
$output = "<?php \n\$_smarty_tpl->_Block->{$_function}Block(\$_smarty_tpl, array('caching' => {$cm}, 'function' => '{$_funcNameCaching}'"; $output =
"<?php \n\$_smarty_tpl->_Block->{$_function}Block(\$_smarty_tpl, array('caching' => {$cm}, 'function' => '{$_funcNameCaching}'";
foreach ($_parameter as $name => $stat) { foreach ($_parameter as $name => $stat) {
if ($stat !== false) { if ($stat !== false) {
$output .= ", '{$name}' => {$stat}"; $output .= ", '{$name}' => {$stat}";
@@ -241,7 +259,9 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase
*/ */
function removeNocache($match) function removeNocache($match)
{ {
$code = preg_replace("/((<\?php )?echo '\/\*%%SmartyNocache:{$this->compiler->template->compiled->nocache_hash}%%\*\/)|(\/\*\/%%SmartyNocache:{$this->compiler->template->compiled->nocache_hash}%%\*\/';(\?>\n)?)/", '', $match[0]); $code =
preg_replace("/((<\?php )?echo '\/\*%%SmartyNocache:{$this->compiler->template->compiled->nocache_hash}%%\*\/)|(\/\*\/%%SmartyNocache:{$this->compiler->template->compiled->nocache_hash}%%\*\/';(\?>\n)?)/",
'', $match[0]);
$code = str_replace(array('\\\'', '\\\\\''), array('\'', '\\\''), $code); $code = str_replace(array('\\\'', '\\\\\''), array('\'', '\\\''), $code);
return $code; return $code;
} }

View File

@@ -53,8 +53,10 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase
if (strpos($_attr['file'], '$_tmp') !== false) { if (strpos($_attr['file'], '$_tmp') !== false) {
$compiler->trigger_template_error('illegal value for file attribute', $compiler->parser->lex->line - 1); $compiler->trigger_template_error('illegal value for file attribute', $compiler->parser->lex->line - 1);
} }
// save template name
$compiler->extendsFileName = $_attr['file']; $compiler->extendsFileName = $_attr['file'];
$compiler->template->isChild = true; // process {block} in child template mode
$compiler->inheritanceChild = true;
$compiler->has_code = false; $compiler->has_code = false;
return ''; return '';
} }

View File

@@ -65,9 +65,6 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
*/ */
public function compile($args, Smarty_Internal_SmartyTemplateCompiler $compiler, $parameter) public function compile($args, Smarty_Internal_SmartyTemplateCompiler $compiler, $parameter)
{ {
if (!isset($parameter['isChild'])) {
$parameter['isChild'] = false;
}
// check and get attributes // check and get attributes
$_attr = $this->getAttributes($compiler, $args); $_attr = $this->getAttributes($compiler, $args);
@@ -101,6 +98,9 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
} else { } else {
$variable_template = true; $variable_template = true;
} }
if ($compiler->inheritanceForceChild) {
$hashResourceName .= '-child';
}
if (isset($_attr['assign'])) { if (isset($_attr['assign'])) {
// output will be stored in a smarty variable instead of being displayed // output will be stored in a smarty variable instead of being displayed
@@ -223,7 +223,9 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
$tpl->compiled = new Smarty_Template_Compiled(); $tpl->compiled = new Smarty_Template_Compiled();
$tpl->compiled->nocache_hash = $compiler->parent_compiler->template->compiled->nocache_hash; $tpl->compiled->nocache_hash = $compiler->parent_compiler->template->compiled->nocache_hash;
$tpl->loadCompiler(); $tpl->loadCompiler();
$tpl->isChild = $parameter['isChild']; $tpl->compiler->inheritanceChild =
$tpl->compiler->inheritanceForceChild = $compiler->inheritanceForceChild;
$tpl->compiler->inheritance = $compiler->inheritance;
// save unique function name // save unique function name
$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['func'] = $compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['func'] =
$tpl->compiled->unifunc = 'content_' . str_replace(array('.', ','), '_', uniqid('', true)); $tpl->compiled->unifunc = 'content_' . str_replace(array('.', ','), '_', uniqid('', true));
@@ -237,6 +239,8 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
$tpl->compiler->compileTemplate($tpl, $tpl->compiler->compileTemplate($tpl,
null, null,
$compiler->parent_compiler)); $compiler->parent_compiler));
$compiler->inheritanceParentIsChild = $tpl->compiler->inheritanceChild;
$compiler->inheritance = $tpl->compiler->inheritance;
unset($tpl->compiler); unset($tpl->compiler);
// remove header code // remove header code

View File

@@ -35,7 +35,6 @@ class Smarty_Internal_Extension_CodeFrame
if (!$cache) { if (!$cache) {
$properties['file_dependency'] = $_template->compiled->file_dependency; $properties['file_dependency'] = $_template->compiled->file_dependency;
$properties['includes'] = $_template->compiled->includes; $properties['includes'] = $_template->compiled->includes;
$properties['isChild'] = $_template->isChild;
} else { } else {
$properties['file_dependency'] = $_template->cached->file_dependency; $properties['file_dependency'] = $_template->cached->file_dependency;
$properties['cache_lifetime'] = $_template->cache_lifetime; $properties['cache_lifetime'] = $_template->cache_lifetime;

View File

@@ -480,7 +480,6 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
$resource = $this->cached; $resource = $this->cached;
} else { } else {
$this->mustCompile = !$is_valid; $this->mustCompile = !$is_valid;
$this->isChild = $properties['isChild'];
$resource = $this->compiled; $resource = $this->compiled;
$resource->includes = isset($properties['includes']) ? $properties['includes'] : array(); $resource->includes = isset($properties['includes']) ? $properties['includes'] : array();
} }
@@ -658,11 +657,9 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
{ {
// object properties of runtime template extensions will start with '_' // object properties of runtime template extensions will start with '_'
if ($property_name[0] == '_') { if ($property_name[0] == '_') {
$property_name[1] = chr(ord($property_name[1]) & 0xDF);
$class = 'Smarty_Internal_Runtime' . $property_name; $class = 'Smarty_Internal_Runtime' . $property_name;
if (!class_exists($class, false)) { if (class_exists($class)) {
require SMARTY_SYSPLUGINS_DIR . strtolower($class) . '.php';
}
if (class_exists($class, false)) {
return $this->$property_name = new $class(); return $this->$property_name = new $class();
} }
} }

View File

@@ -151,11 +151,11 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base
$_template->smarty->compile_check = $compileCheck; $_template->smarty->compile_check = $compileCheck;
} }
} }
if (isset($_template->parent) && isset($_template->parent->compiled) && if ($_template->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_AUTOMATIC && isset($_template->parent) &&
isset($_template->parent->compiled) && !$_template->source->isConfig &&
!in_array($_template->source->type, array('eval', 'string')) &&
!empty($_template->parent->compiled->includes) && !empty($_template->parent->compiled->includes) &&
$_template->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_AUTOMATIC && isset($_template->smarty->_cache['template_objects'][$_template->_getTemplateId()])
!$_template->source->handler->recompiled && $_template->source->type != 'string' &&
!isset($_template->smarty->_cache['template_objects'][$_template->_getTemplateId()])
) { ) {
foreach ($_template->parent->compiled->includes as $key => $count) { foreach ($_template->parent->compiled->includes as $key => $count) {
$_template->compiled->includes[$key] = $_template->compiled->includes[$key] =
@@ -232,6 +232,7 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base
public function compileTemplateSource(Smarty_Internal_Template $_template) public function compileTemplateSource(Smarty_Internal_Template $_template)
{ {
$_template->source->compileds = array(); $_template->source->compileds = array();
$_template->isChild = false;
$this->file_dependency = array(); $this->file_dependency = array();
$this->tpl_function = array(); $this->tpl_function = array();
$this->includes = array(); $this->includes = array();