diff --git a/INHERITANCE_RELEASE_NOTES.txt b/INHERITANCE_RELEASE_NOTES.txt index 0d772385..f3416fea 100644 --- a/INHERITANCE_RELEASE_NOTES.txt +++ b/INHERITANCE_RELEASE_NOTES.txt @@ -1,3 +1,9 @@ +3.1.31 +New tags for inheritance parent and child +{block_parent} == {$smarty.block.parent} +{block_child} == {$smarty.block.child} + +3.1.28 Starting with version 3.1.28 template inheritance is no longer a compile time process. All {block} tag parent/child relations are resolved at run time. This does resolve all known existing restrictions (see below). diff --git a/NEW_FEATURES.txt b/NEW_FEATURES.txt index f20a9f0f..adbc1099 100644 --- a/NEW_FEATURES.txt +++ b/NEW_FEATURES.txt @@ -2,6 +2,12 @@ This file contains a brief description of new features which have been added to Smarty 3.1 +Smarty 3.1.31 + New tags for inheritance parent and child + ========================================= + {block_parent} == {$smarty.block.parent} + {block_child} == {$smarty.block.child} + Smarty 3.1.30 Loop optimization {foreach} and {section} diff --git a/change_log.txt b/change_log.txt index 7cc23662..9c6f8dd7 100644 --- a/change_log.txt +++ b/change_log.txt @@ -3,6 +3,8 @@ - bugfix some $smarty special template variables are no longer accessed as real variable. using them on calls like {if isset($smarty.foo)} or {if empty($smarty.foo)} will fail http://www.smarty.net/forums/viewtopic.php?t=26222 + - temporary fix for https://github.com/smarty-php/smarty/issues/293 main reason still under investigation + - improvement new tags {block_parent} {block_child} in template inheritance 19.09.2016 - optimization clear compiled and cached folder completely on detected version change diff --git a/lexer/smarty_internal_templateparser.y b/lexer/smarty_internal_templateparser.y index 0e540cad..eacc421f 100644 --- a/lexer/smarty_internal_templateparser.y +++ b/lexer/smarty_internal_templateparser.y @@ -534,11 +534,11 @@ tag(res) ::= LDEL SMARTYBLOCKCHILDPARENT(i). { $j = strrpos(i,'.'); if (i[$j+1] == 'c') { // {$smarty.block.child} - res = SMARTY_INTERNAL_COMPILE_BLOCK::compileChildBlock($this->compiler); + res = $this->compiler->compileTag('block_child',array());; } else { // {$smarty.block.parent} - res = SMARTY_INTERNAL_COMPILE_BLOCK::compileParentBlock($this->compiler); - } + res = $this->compiler->compileTag('block_parent',array());; + } } diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index 51243054..1116bd4a 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -114,7 +114,7 @@ class Smarty extends Smarty_Internal_TemplateBase /** * smarty version */ - const SMARTY_VERSION = '3.1.31-dev/26'; + const SMARTY_VERSION = '3.1.31-dev/28'; /** * define variable scopes diff --git a/libs/sysplugins/smarty_internal_compile_block.php b/libs/sysplugins/smarty_internal_compile_block.php index e2878947..5098d62f 100644 --- a/libs/sysplugins/smarty_internal_compile_block.php +++ b/libs/sysplugins/smarty_internal_compile_block.php @@ -47,13 +47,6 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_Compile_Shared_Inher */ public $optional_attributes = array('assign'); - /** - * nesting level of block tags - * - * @var int - */ - public static $blockTagNestingLevel = 0; - /** * Saved compiler object * @@ -85,8 +78,11 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_Compile_Shared_Inher // check and get attributes $_attr = $this->getAttributes($compiler, $args); $compiler->_cache[ 'blockNesting' ] ++; + $_className = 'Block_' . preg_replace('![^\w]+!', '_', uniqid(rand(), true)); $compiler->_cache[ 'blockName' ][ $compiler->_cache[ 'blockNesting' ] ] = $_attr[ 'name' ]; + $compiler->_cache[ 'blockClass' ][ $compiler->_cache[ 'blockNesting' ] ] = $_className; $compiler->_cache[ 'blockParams' ][ $compiler->_cache[ 'blockNesting' ] ] = array(); + $compiler->_cache[ 'blockParams' ][ 1 ][ 'subBlocks' ][ trim($_attr[ 'name' ], '"\'') ][] = $_className; $this->openTag($compiler, 'block', array($_attr, $compiler->nocache, $compiler->parser->current_buffer, $compiler->template->compiled->has_nocache_code, $compiler->template->caching)); @@ -103,47 +99,6 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_Compile_Shared_Inher $compiler->template->compiled->has_nocache_code = false; $compiler->suppressNocacheProcessing = true; } - - /** - * Compile saved child block source - * - * @param \Smarty_Internal_TemplateCompilerBase compiler object - * @param string $_name optional name of child block - * - * @return string compiled code of child block - */ - static function compileChildBlock(Smarty_Internal_TemplateCompilerBase $compiler, $_name = null) - { - if (!isset($compiler->_cache[ 'blockNesting' ])) { - $compiler->trigger_template_error(' tag {$smarty.block.child} used outside {block} tags ', - $compiler->parser->lex->taglineno); - } - $compiler->has_code = true; - $compiler->suppressNocacheProcessing = true; - $compiler->_cache[ 'blockParams' ][ $compiler->_cache[ 'blockNesting' ] ][ 'callsChild' ] = 'true'; - $output = "inheritance->callChild(\$_smarty_tpl, \$this);\n?>\n"; - return $output; - } - - /** - * Compile $smarty.block.parent - * - * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object - * @param string $_name optional name of child block - * - * @return string compiled code of child block - */ - static function compileParentBlock(Smarty_Internal_TemplateCompilerBase $compiler, $_name = null) - { - if (!isset($compiler->_cache[ 'blockNesting' ])) { - $compiler->trigger_template_error(' tag {$smarty.block.parent} used outside {block} tags ', - $compiler->parser->lex->taglineno); - } - $compiler->suppressNocacheProcessing = true; - $compiler->has_code = true; - $output = "inheritance->callParent(\$_smarty_tpl, \$this);\n?>\n"; - return $output; - } } /** @@ -175,7 +130,7 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_Compile_Shared_ $_block[ $name ] = 'true'; } } - $_className = 'Block_' . preg_replace('![^\w]+!', '_', uniqid(rand(), true)); + $_className = $compiler->_cache[ 'blockClass' ][ $compiler->_cache[ 'blockNesting' ] ]; // get compiled block code $_functionCode = $compiler->parser->current_buffer; // setup buffer for template function code @@ -186,7 +141,7 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_Compile_Shared_ $output .= "class {$_className} extends Smarty_Internal_Block\n"; $output .= "{\n"; foreach ($_block as $property => $value) { - $output .= "public \${$property} = {$value};\n"; + $output .= "public \${$property} = " . var_export($value,true) .";\n"; } $output .= "public function callBlock(Smarty_Internal_Template \$_smarty_tpl) {\n"; //$output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n"; diff --git a/libs/sysplugins/smarty_internal_compile_block_child.php b/libs/sysplugins/smarty_internal_compile_block_child.php new file mode 100644 index 00000000..bb070ebe --- /dev/null +++ b/libs/sysplugins/smarty_internal_compile_block_child.php @@ -0,0 +1,54 @@ + + */ +class Smarty_Internal_Compile_Block_Child extends Smarty_Internal_CompileBase +{ + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $option_flags = array(); + + /** + * Saved compiler object + * + * @var Smarty_Internal_TemplateCompilerBase + */ + public $compiler = null; + + /** + * Compiles code for the {block_parent} tag + * + * @param array $args array with attributes from parser + * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object + * @param array $parameter array with compilation parameter + * + * @return bool true + */ + public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter) + { + if (!isset($compiler->_cache[ 'blockNesting' ])) { + $compiler->trigger_template_error(' tag {$smarty.block.child} used outside {block} tags ', + $compiler->parser->lex->taglineno); + } + $compiler->has_code = true; + $compiler->suppressNocacheProcessing = true; + $compiler->_cache[ 'blockParams' ][ $compiler->_cache[ 'blockNesting' ] ][ 'callsChild' ] = 'true'; + $output = "inheritance->callChild(\$_smarty_tpl, \$this);\n?>\n"; + return $output; + } +} \ No newline at end of file diff --git a/libs/sysplugins/smarty_internal_compile_block_parent.php b/libs/sysplugins/smarty_internal_compile_block_parent.php new file mode 100644 index 00000000..0ec1e848 --- /dev/null +++ b/libs/sysplugins/smarty_internal_compile_block_parent.php @@ -0,0 +1,73 @@ + + */ +class Smarty_Internal_Compile_Block_Parent extends Smarty_Internal_Compile_Shared_Inheritance +{ + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $optional_attributes = array('name'); + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $shorttag_order = array('name'); + + /** + * Attribute definition: Overwrites base class. + * + * @var array + * @see Smarty_Internal_CompileBase + */ + public $option_flags = array(); + + /** + * Saved compiler object + * + * @var Smarty_Internal_TemplateCompilerBase + */ + public $compiler = null; + + /** + * Compiles code for the {block_parent} tag + * + * @param array $args array with attributes from parser + * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object + * @param array $parameter array with compilation parameter + * + * @return bool true + */ + public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter) + { + // check and get attributes + $_attr = $this->getAttributes($compiler, $args); + if (!isset($compiler->_cache[ 'blockNesting' ])) { + $compiler->trigger_template_error(' tag {$smarty.block.parent} used outside {block} tags ', + $compiler->parser->lex->taglineno); + } + $compiler->suppressNocacheProcessing = true; + $compiler->has_code = true; + $output = "inheritance->callParent(\$_smarty_tpl, \$this" . + (isset($_attr[ 'name' ]) ? ", {$_attr[ 'name' ]}" : '') . ");\n?>\n"; + return $output; + } +} \ No newline at end of file diff --git a/libs/sysplugins/smarty_internal_templateparser.php b/libs/sysplugins/smarty_internal_templateparser.php index 1dc87ff1..2431c9b9 100644 --- a/libs/sysplugins/smarty_internal_templateparser.php +++ b/libs/sysplugins/smarty_internal_templateparser.php @@ -1862,10 +1862,10 @@ class Smarty_Internal_Templateparser $j = strrpos($this->yystack[ $this->yyidx + 0 ]->minor, '.'); if ($this->yystack[ $this->yyidx + 0 ]->minor[ $j + 1 ] == 'c') { // {$smarty.block.child} - $this->_retvalue = SMARTY_INTERNAL_COMPILE_BLOCK::compileChildBlock($this->compiler); + $this->_retvalue = $this->compiler->compileTag('block_child', array());; } else { // {$smarty.block.parent} - $this->_retvalue = SMARTY_INTERNAL_COMPILE_BLOCK::compileParentBlock($this->compiler); + $this->_retvalue = $this->compiler->compileTag('block_parent', array());; } } diff --git a/libs/sysplugins/smarty_internal_testinstall.php b/libs/sysplugins/smarty_internal_testinstall.php index 2f1c3de0..7cb57557 100644 --- a/libs/sysplugins/smarty_internal_testinstall.php +++ b/libs/sysplugins/smarty_internal_testinstall.php @@ -368,6 +368,8 @@ class Smarty_Internal_TestInstall 'smarty_internal_compile_append.php' => true, 'smarty_internal_compile_assign.php' => true, 'smarty_internal_compile_block.php' => true, + 'smarty_internal_compile_block_child.php' => true, + 'smarty_internal_compile_block_parent.php' => true, 'smarty_internal_compile_break.php' => true, 'smarty_internal_compile_call.php' => true, 'smarty_internal_compile_capture.php' => true,