diff --git a/3.1.16_RELEASE_NOTES.txt b/3.1.16_RELEASE_NOTES.txt new file mode 100644 index 00000000..4a351fa5 --- /dev/null +++ b/3.1.16_RELEASE_NOTES.txt @@ -0,0 +1,35 @@ +In Smarty 3.1 template inheritance is a compile time process. All the extending of {block} tags +is done at compile time and the parent and child templates are compiled in a single compiled template. +{include} subtemplate could also {block} tags. Such subtemplate could not compiled by it's own because +it could be used in other context where the {block} extended with a different result. For that reasion +the compiled code of {include} subtemplates gets also merged in compiled inheritance template. + +Merging the code into a single compile template has some drawbacks. +1. You could not use variable file names in {include} Smarty would use the {include} of compilation time. +2. You could not use individual compile_id in {include} +3. Seperate caching of subtemplate was not possible +4. Any change of the template directory structure between calls was not necessarily seen. + +Starting with 3.1.15 some of the above conditions got checked and resulted in an exception. It turned out +that a couple of users did use some of above and now got exceptions. + +To resolve this starting with 3.1.16 there is a new configuration parameter $inheritance_merge_compiled_includes. +For most backward compatibility its default setting is true. +With this setting all {include} subtemplate will be merge into the compiled inheritance template, but the above cases +could be rejected by exception. + + +If $smarty->inheritance_merge_compiled_includes = false; {include} subtemplate will not be merged. +You must now manually merge all {include} subtemplate which do contain {block} tags. This is done by setting the "inline" option. +{include file='foo.bar' inline} + +1. In case of a variable file name like {include file=$foo inline} you must you the variable in a compile_id $smarty->compile_id = $foo; +2. If you use individual compile_id in {include file='foo.tpl' compile_id=$bar inline} it must be used in the + global compile_id as well $smarty->compile_id = $foo; +3. If call templates with different template_dir configurations and a parent could same named child template from different folders + you must make the folder name part of the compile_id. + + +In the upcomming major release Smarty 3.2 inheritance will no longer be a compile time process. +All restrictions will be then removed. + diff --git a/change_log.txt b/change_log.txt index a2c2aa6f..2657bbb1 100644 --- a/change_log.txt +++ b/change_log.txt @@ -1,4 +1,8 @@ ===== trunk ===== + 15.12.2013 + - bugfix {include} with {block} tag handling (forum topic 24599, 24594, 24682) (Issue 161) + Read 3.1.16_RELEASE_NOTES for more details + 07.11.2013 - bugfix too restrictive handling of {include} within {block} tags. 3.1.15 did throw errors where 3.1.14 did not (forum topic 24599) - bugfix compiler could fail if PHP mbstring.func_overload is enabled (Issue 164) diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index 897b385a..893ffb2e 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -299,6 +299,11 @@ class Smarty extends Smarty_Internal_TemplateBase * @var boolean */ public $merge_compiled_includes = false; + /** + * template inheritance merge compiled includes + * @var boolean + */ + public $inheritance_merge_compiled_includes = true; /** * cache lifetime in seconds * @var integer diff --git a/libs/sysplugins/smarty_internal_compile_block.php b/libs/sysplugins/smarty_internal_compile_block.php index 0699aa08..ba26ed0a 100644 --- a/libs/sysplugins/smarty_internal_compile_block.php +++ b/libs/sysplugins/smarty_internal_compile_block.php @@ -160,6 +160,7 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase if ($compiler->smarty->debugging) { Smarty_Internal_Debug::ignore($_tpl); } + $_tpl->tpl_vars = $compiler->template->tpl_vars; $_tpl->variable_filters = $compiler->template->variable_filters; $_tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash']; $_tpl->allow_relative_path = true; diff --git a/libs/sysplugins/smarty_internal_compile_include.php b/libs/sysplugins/smarty_internal_compile_include.php index 7a7f960c..1ea8b577 100644 --- a/libs/sysplugins/smarty_internal_compile_include.php +++ b/libs/sysplugins/smarty_internal_compile_include.php @@ -85,7 +85,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase $_caching = Smarty::CACHING_OFF; // flag if included template code should be merged into caller - $merge_compiled_includes = ($compiler->smarty->merge_compiled_includes || $compiler->inheritance || $_attr['inline'] === true) && !$compiler->template->source->recompiled; + $merge_compiled_includes = ($compiler->smarty->merge_compiled_includes ||($compiler->inheritance && $compiler->smarty->inheritance_merge_compiled_includes)|| $_attr['inline'] === true) && !$compiler->template->source->recompiled; // set default when in nocache mode // if ($compiler->template->caching && ($compiler->nocache || $compiler->tag_nocache || $compiler->forceNocache == 2)) { @@ -129,12 +129,15 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase } $has_compiled_template = false; - if ($merge_compiled_includes) { + if ($merge_compiled_includes && $_attr['inline'] !== true) { // variable template name ? if ($compiler->has_variable_string || !((substr_count($include_file, '"') == 2 || substr_count($include_file, "'") == 2)) || substr_count($include_file, '(') != 0 || substr_count($include_file, '$_smarty_tpl->') != 0 ) { $merge_compiled_includes = false; + if ($compiler->inheritance && $compiler->smarty->inheritance_merge_compiled_includes) { + $compiler->trigger_template_error(' variable template file names not allow within {block} tags'); + } } // variable compile_id? if (isset($_attr['compile_id'])) { @@ -142,10 +145,18 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase || substr_count($_attr['compile_id'], '(') != 0 || substr_count($_attr['compile_id'], '$_smarty_tpl->') != 0 ) { $merge_compiled_includes = false; + if ($compiler->inheritance && $compiler->smarty->inheritance_merge_compiled_includes) { + $compiler->trigger_template_error(' variable compile_id not allow within {block} tags'); + } } } + } + if ($merge_compiled_includes) { if ($compiler->template->caching && ($compiler->tag_nocache || $compiler->nocache) && $_caching != self::CACHING_NOCACHE_CODE) { $merge_compiled_includes = false; + if ($compiler->inheritance && $compiler->smarty->inheritance_merge_compiled_includes) { + $compiler->trigger_template_error(' invalid caching mode of subtemplate within {block} tags'); + } } } if ($merge_compiled_includes) { @@ -153,6 +164,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase $uid = sha1($_compile_id); $tpl_name = null; $nocache = false; + $_smarty_tpl = $compiler->template; eval("\$tpl_name = $include_file;"); if (!isset($compiler->smarty->merged_templates_func[$tpl_name][$uid]) || $compiler->inheritance) { $tpl = new $compiler->smarty->template_class ($tpl_name, $compiler->smarty, $compiler->template, $compiler->template->cache_id, $compiler->template->compile_id);