smarty-php / smarty

Smarty is a template engine for PHP, facilitating the separation of presentation (HTML/CSS) from application logic.
Other
2.25k stars 705 forks source link

append-option in capture not working with included templates anymore #1062

Open asdfklgash opened 1 week ago

asdfklgash commented 1 week ago

We're running a complex structure of template includes and there we use {capture} with "assign". To keep the array in the scope of the parent template we pre-defined the variable on top of the template that includes the other templates. That worked so far with v4.5.3, but not anymore with v5.4.0+. I think also it never worked in v5 as the file was not changed since creation.

As I saw in v.4.5.3 there was some code for scope handling in the append() function - but that's not there anymore in v5.4. For testing I added the global scope to the $this->assign() in src/Data.php:189 and it worked again.

Also with a little bit more debugging the already existing value from the main template gets fetched and the new capture-append-content is added but it's saved with SCOPE_LOCAL (as default) and so there is added a new variable for the included template.

wisskid commented 1 week ago

It is quite possible that you experience differences, because the way variable scopes work has been redesigned in v5. Can you share your code snippet?

asdfklgash commented 1 week ago

Just digging a bit deeper I see our plugin "include_if_exists" to just include templates when they exists (based on https://code.google.com/archive/p/smartyplugin-include-if-exists/) needs an additional param scope for the include during compile time.

It looks like it works with the regular include on a correct base but with our include_if_exists the scope is different from the main file (all entries are appended but not available in the main file)... I try to put it together for an runnable example.

asdfklgash commented 1 week ago

Reading the documentation on scopes (https://smarty-php.github.io/smarty/stable/designers/language-variables/language-variable-scopes/) I assume that "A template sees all the variables of its own object and all variables assigned to the objects in its chain of parent objects."

So when defining $th_campaigns in campaigns.inc.tpl it should also be seen by all sub-templates. That seems to work so far. But the capture append= block then calls an assign() with scope SCOPE_LOCAL and sets the (right) array with the values from the parent templates just in local context so that the values are gone in the parent template.

Calling all the includes with scope='parent' it seems to work.

So I don't know if that is the expected (changed) behavior with the scope regarding includes or just a bug?