mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-04 10:24:26 +02:00
- improvement rework of 'scope' attribute handling see see NEW_FEATURES.txt https://github.com/smarty-php/smarty/issues/194
https://github.com/smarty-php/smarty/issues/186 https://github.com/smarty-php/smarty/issues/179
This commit is contained in:
@@ -50,46 +50,28 @@ Smarty 3.1.30
|
||||
Scope Attributes
|
||||
================
|
||||
The scope handling has been updated to cover all cases of variable assignments in templates.
|
||||
A new option flag 'bubble_up' is introduced.
|
||||
|
||||
|
||||
The tags {assign}, {append} direct assignments like {$foo = ...}, {$foo[...]= ...} support
|
||||
the following optional scope attributes:
|
||||
scope='parent' - the variable will be assigned in the current template and if the template
|
||||
was included by {include} the calling template
|
||||
scope='tpl_root' - the variable will be assigned in the current template and if the template
|
||||
was included by {include} the outermost root template
|
||||
scope='smarty' - the variable will be assigned in the current template and the Smarty object
|
||||
scope='global' - the variable will be assigned in the current template and as Smarty object
|
||||
global variable
|
||||
scope='root' - the variable will be assigned in the current template and if a data object was
|
||||
used for variable definitions in the data object or in the Smarty object otherwise
|
||||
scope='tpl_root' - the variable will be assigned in the outermost root template called by $smarty->display()
|
||||
or $smarty->fetch() and is bubbled up all {include} sub-templates to the current template.
|
||||
scope='smarty' - the variable will be assigned in the Smarty object and is bubbled up all {include} sub-templates
|
||||
to the current template.
|
||||
scope='global' - the variable will be assigned as Smarty object global variable and is bubbled up all {include}
|
||||
sub-templates to the current template.
|
||||
scope='root' - the variable will be assigned if a data object was used for variable definitions in the data
|
||||
object or in the Smarty object otherwise and is bubbled up all {include} sub-templates to the
|
||||
current template.
|
||||
scope='local' - this scope has only a meaning if the tag is called within a template {function}.
|
||||
The variable will be assigned in the local scope of the template function and the
|
||||
template which did call the template function.
|
||||
|
||||
The scope attribute can be combined with the new option flag 'bubble_up' like
|
||||
{$foo = 'bar' scope='global' bubble_up}
|
||||
In addition to the assignments according to the scope attributes tpl_root, smarty, global, root the varibale
|
||||
will also be assigned in all templates in the call chain from template root to the current template,
|
||||
including all local template function scopes of nested template function calls.
|
||||
In combination with scope local it does update the nested template function scopes.
|
||||
|
||||
Example:
|
||||
$smarty->display('main.tpl');
|
||||
|
||||
main.tpl:
|
||||
{include 'sub.tpl'}
|
||||
|
||||
sub.tpl:
|
||||
{$foo = 'bar' scope='global' bubble_up}
|
||||
|
||||
Will assign the variable 'foo' with value 'bar' as Smarty global variable, in 'sub.tpl' and in
|
||||
'main.tpl' because the 'bubble_up' option.
|
||||
|
||||
|
||||
The {config_load} tag supports all of the above except the global scope.
|
||||
|
||||
The scope attribute and bubble_up option flag can be used also with the {include} tag.
|
||||
The scope attribute can be used also with the {include} tag.
|
||||
Supported scope are parent, tpl_root, smarty, global and root.
|
||||
A scope used together with the {include} tag will cause that with some exceptions any variable
|
||||
assignment within that sub-template will update/assign the variable in other scopes according
|
||||
@@ -97,7 +79,16 @@ Smarty 3.1.30
|
||||
attribute and direct assignments in {if} and {while} like {if $foo=$bar}.
|
||||
Excluded are the key and value variables of {foreach}, {for} loop variables , variables passed by attributes
|
||||
in {include} and direct increments/decrements like {$foo++}, {$foo--}
|
||||
|
||||
|
||||
Note: The scopes should be used only to the extend really need. If a variable value assigned in an included
|
||||
sub-template should be returned to the calling sub-template just use {$foo='bar' scope='parent'}.
|
||||
Use scopes only with variables for which it's realy needed. Avoid general scope settings with the
|
||||
{include} tag as it can have a performance impact.
|
||||
|
||||
The {assign}, {append}, {config_load} and {$foo...=...} tags have a new option flag 'noscope'.Thi
|
||||
Example: {$foo='bar' noscope} This will assign $foo only in the current template and any scope settings
|
||||
at {include} is ignored.
|
||||
|
||||
|
||||
Caching
|
||||
=======
|
||||
|
@@ -1,4 +1,8 @@
|
||||
===== 3.1.30-dev ===== (xx.xx.xx)
|
||||
09.03.2014
|
||||
- improvement rework of 'scope' attribute handling see see NEW_FEATURES.txt https://github.com/smarty-php/smarty/issues/194
|
||||
https://github.com/smarty-php/smarty/issues/186 https://github.com/smarty-php/smarty/issues/179
|
||||
|
||||
04.03.2016
|
||||
- bugfix change from 01.03.2016 will cause $smarty->isCached(..) failure if called multiple time for same template
|
||||
(forum topic 25935)
|
||||
|
@@ -121,7 +121,7 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
/**
|
||||
* smarty version
|
||||
*/
|
||||
const SMARTY_VERSION = '3.1.30-dev/52';
|
||||
const SMARTY_VERSION = '3.1.30-dev/53';
|
||||
|
||||
/**
|
||||
* define variable scopes
|
||||
@@ -138,8 +138,6 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
|
||||
const SCOPE_GLOBAL = 32;
|
||||
|
||||
const SCOPE_BUBBLE_UP = 64;
|
||||
|
||||
/**
|
||||
* define caching modes
|
||||
*/
|
||||
|
@@ -22,9 +22,9 @@ class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase
|
||||
* @var array
|
||||
* @see Smarty_Internal_CompileBase
|
||||
*/
|
||||
public $option_flags = array('nocache', 'bubble_up');
|
||||
public $option_flags = array('nocache', 'noscope');
|
||||
|
||||
/**
|
||||
/**
|
||||
* Valid scope names
|
||||
*
|
||||
* @var array
|
||||
@@ -65,7 +65,11 @@ class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase
|
||||
$compiler->setNocacheInVariable($_attr[ 'var' ]);
|
||||
}
|
||||
// scope setup
|
||||
$_scope = $compiler->convertScope($_attr, $this->valid_scopes);
|
||||
if ($_attr[ 'noscope' ]) {
|
||||
$_scope = - 1;
|
||||
} else {
|
||||
$_scope = $compiler->convertScope($_attr, $this->valid_scopes);
|
||||
}
|
||||
// optional parameter
|
||||
$_params = "";
|
||||
if ($_nocache || $_scope) {
|
||||
|
@@ -46,7 +46,7 @@ class Smarty_Internal_Compile_Config_Load extends Smarty_Internal_CompileBase
|
||||
* @var array
|
||||
* @see Smarty_Internal_CompileBase
|
||||
*/
|
||||
public $option_flags = array('nocache', 'bubble_up');
|
||||
public $option_flags = array('nocache', 'noscope');
|
||||
|
||||
/**
|
||||
* Valid scope names
|
||||
@@ -83,7 +83,11 @@ class Smarty_Internal_Compile_Config_Load extends Smarty_Internal_CompileBase
|
||||
$section = 'null';
|
||||
}
|
||||
// scope setup
|
||||
$_scope = $compiler->convertScope($_attr, $this->valid_scopes);
|
||||
if ($_attr[ 'noscope' ]) {
|
||||
$_scope = - 1;
|
||||
} else {
|
||||
$_scope = $compiler->convertScope($_attr, $this->valid_scopes);
|
||||
}
|
||||
|
||||
// create config object
|
||||
$_output =
|
||||
|
@@ -43,7 +43,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
||||
* @var array
|
||||
* @see Smarty_Internal_CompileBase
|
||||
*/
|
||||
public $option_flags = array('nocache', 'inline', 'caching', 'bubble_up');
|
||||
public $option_flags = array('nocache', 'inline', 'caching');
|
||||
|
||||
/**
|
||||
* Attribute definition: Overwrites base class.
|
||||
@@ -214,7 +214,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
||||
}
|
||||
}
|
||||
// delete {include} standard attributes
|
||||
unset($_attr[ 'file' ], $_attr[ 'assign' ], $_attr[ 'cache_id' ], $_attr[ 'compile_id' ], $_attr[ 'cache_lifetime' ], $_attr[ 'nocache' ], $_attr[ 'caching' ], $_attr[ 'scope' ], $_attr[ 'inline' ], $_attr[ 'bubble_up' ]);
|
||||
unset($_attr[ 'file' ], $_attr[ 'assign' ], $_attr[ 'cache_id' ], $_attr[ 'compile_id' ], $_attr[ 'cache_lifetime' ], $_attr[ 'nocache' ], $_attr[ 'caching' ], $_attr[ 'scope' ], $_attr[ 'inline' ]);
|
||||
// remaining attributes must be assigned as smarty variable
|
||||
$_vars_nc = '';
|
||||
$_vars = 'array()';
|
||||
|
@@ -76,21 +76,31 @@ class Smarty_Internal_Method_ConfigLoad
|
||||
* load config variables into template object
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl
|
||||
* @param array $_config_vars
|
||||
* @param array $new_config_vars
|
||||
*
|
||||
*/
|
||||
public function _loadConfigVars(Smarty_Internal_Template $tpl, $_config_vars)
|
||||
public function _loadConfigVars(Smarty_Internal_Template $tpl, $new_config_vars)
|
||||
{
|
||||
$this->_assignConfigVars($tpl->parent, $tpl, $_config_vars);
|
||||
if ($tpl->parent->_objType == 2 && ($tpl->source->scope || $tpl->parent->scope)) {
|
||||
$scope = $tpl->source->scope | $tpl->scope;
|
||||
if ($scope) {
|
||||
// update scopes
|
||||
foreach ($tpl->smarty->ext->_updateScope->_getAffectedScopes($tpl->parent, $scope) as $ptr) {
|
||||
$this->_assignConfigVars($ptr, $tpl, $_config_vars);
|
||||
$this->_assignConfigVars($tpl->parent->config_vars, $tpl, $new_config_vars);
|
||||
$tagScope = $tpl->source->scope;
|
||||
if ($tagScope >= 0) {
|
||||
if ($tagScope == Smarty::SCOPE_LOCAL) {
|
||||
$this->_updateVarStack($tpl, $new_config_vars);
|
||||
$tagScope = 0;
|
||||
if (!$tpl->scope) {
|
||||
return;
|
||||
}
|
||||
if ($scope & Smarty::SCOPE_LOCAL) {
|
||||
//$this->_updateVarStack($tpl, $varName);
|
||||
}
|
||||
if ($tpl->parent->_objType == 2 && ($tagScope || $tpl->parent->scope)) {
|
||||
$mergedScope = $tagScope | $tpl->scope;
|
||||
if ($mergedScope) {
|
||||
// update scopes
|
||||
foreach ($tpl->smarty->ext->_updateScope->_getAffectedScopes($tpl->parent, $mergedScope) as $ptr) {
|
||||
$this->_assignConfigVars($ptr->config_vars, $tpl, $new_config_vars);
|
||||
if ($tagScope && $ptr->_objType == 2 && isset($tpl->_cache[ 'varStack' ])) {
|
||||
$this->_updateVarStack($tpl, $new_config_vars);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,32 +109,30 @@ class Smarty_Internal_Method_ConfigLoad
|
||||
/**
|
||||
* Assign all config variables in given scope
|
||||
*
|
||||
* @param \Smarty_Internal_Data $scope_ptr
|
||||
* @param array $config_vars config variables in scope
|
||||
* @param \Smarty_Internal_Template $tpl
|
||||
* @param array $_config_vars
|
||||
* @param array $new_config_vars loaded config variables
|
||||
*/
|
||||
public function _assignConfigVars(Smarty_Internal_Data $scope_ptr, Smarty_Internal_Template $tpl, $_config_vars)
|
||||
public function _assignConfigVars(&$config_vars, Smarty_Internal_Template $tpl, $new_config_vars)
|
||||
{
|
||||
// copy global config vars
|
||||
foreach ($_config_vars[ 'vars' ] as $variable => $value) {
|
||||
if ($tpl->smarty->config_overwrite || !isset($scope_ptr->config_vars[ $variable ])) {
|
||||
$scope_ptr->config_vars[ $variable ] = $value;
|
||||
foreach ($new_config_vars[ 'vars' ] as $variable => $value) {
|
||||
if ($tpl->smarty->config_overwrite || !isset($config_vars[ $variable ])) {
|
||||
$config_vars[ $variable ] = $value;
|
||||
} else {
|
||||
$scope_ptr->config_vars[ $variable ] =
|
||||
array_merge((array) $scope_ptr->config_vars[ $variable ], (array) $value);
|
||||
$config_vars[ $variable ] = array_merge((array) $config_vars[ $variable ], (array) $value);
|
||||
}
|
||||
}
|
||||
// scan sections
|
||||
$sections = $tpl->source->config_sections;
|
||||
if (!empty($sections)) {
|
||||
foreach ((array) $sections as $tpl_section) {
|
||||
if (isset($_config_vars[ 'sections' ][ $tpl_section ])) {
|
||||
foreach ($_config_vars[ 'sections' ][ $tpl_section ][ 'vars' ] as $variable => $value) {
|
||||
if ($tpl->smarty->config_overwrite || !isset($scope_ptr->config_vars[ $variable ])) {
|
||||
$scope_ptr->config_vars[ $variable ] = $value;
|
||||
if (isset($new_config_vars[ 'sections' ][ $tpl_section ])) {
|
||||
foreach ($new_config_vars[ 'sections' ][ $tpl_section ][ 'vars' ] as $variable => $value) {
|
||||
if ($tpl->smarty->config_overwrite || !isset($config_vars[ $variable ])) {
|
||||
$config_vars[ $variable ] = $value;
|
||||
} else {
|
||||
$scope_ptr->config_vars[ $variable ] =
|
||||
array_merge((array) $scope_ptr->config_vars[ $variable ], (array) $value);
|
||||
$config_vars[ $variable ] = array_merge((array) $config_vars[ $variable ], (array) $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,6 +140,21 @@ class Smarty_Internal_Method_ConfigLoad
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update config variables in template local variable stack
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl
|
||||
* @param array $config_vars
|
||||
*/
|
||||
public function _updateVarStack(Smarty_Internal_Template $tpl, $config_vars)
|
||||
{
|
||||
$i = 0;
|
||||
while (isset($tpl->_cache[ 'varStack' ][ $i ])) {
|
||||
$this->_assignConfigVars($tpl->_cache[ 'varStack' ][ $i ][ 'config' ], $tpl, $config_vars);
|
||||
$i ++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gets a config variable value
|
||||
*
|
||||
|
@@ -383,8 +383,10 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||
} else {
|
||||
$this->tpl_vars[ $varName ] = new Smarty_Variable($value, $nocache || $this->isRenderingCache);
|
||||
}
|
||||
if (isset($scope) || isset($this->scope)) {
|
||||
$this->smarty->ext->_updateScope->_updateScope($this, $varName, $scope);
|
||||
if ($scope >= 0) {
|
||||
if (isset($scope) || isset($this->scope)) {
|
||||
$this->smarty->ext->_updateScope->_updateScope($this, $varName, $scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -403,7 +403,6 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
$this->smarty->_debug->end_compile($this->template);
|
||||
}
|
||||
$this->_tag_stack = array();
|
||||
self::$_tag_objects = array();
|
||||
// free memory
|
||||
$this->parent_compiler = null;
|
||||
$this->template = null;
|
||||
@@ -1140,9 +1139,6 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
$err = var_export($_scopeName, true);
|
||||
$this->trigger_template_error("illegal value '{$err}' for \"scope\" attribute", null, true);
|
||||
}
|
||||
if (isset($_attr[ 'bubble_up' ]) && $_attr[ 'bubble_up' ] && $_scope > 2) {
|
||||
$_scope += Smarty::SCOPE_BUBBLE_UP;
|
||||
}
|
||||
}
|
||||
return $_scope;
|
||||
}
|
||||
|
Reference in New Issue
Block a user