Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cacheing of variables in foreach fails #110

Closed
0xFEEDC0DE64 opened this issue Nov 30, 2015 · 4 comments
Closed

Cacheing of variables in foreach fails #110

0xFEEDC0DE64 opened this issue Nov 30, 2015 · 4 comments

Comments

@0xFEEDC0DE64
Copy link

I need to cache a big list in a foreach. But I dont want to cache which one will be highlighted.
The {foreach} itself gets cached, but not variable in the {if}!

See this very small test case:

testcase.php:

<?php

require_once('smarty/Smarty.class.php');

$smarty = new Smarty;

$smarty->setCaching(true);

if(!$smarty->isCached('testcase.tpl')) {
    $smarty->assign('list', [
        ['id' => 1, 'name' => 'test 1'],
        ['id' => 2, 'name' => 'test 2'],
        ['id' => 3, 'name' => 'test 3']
    ]);
}

$smarty->assign('current', 2, true);

$smarty->display('testcase.tpl');

testcase.tpl

<ul>
{foreach from=$list item=item}
    <li>{$item.name} {if $current==$item.id} ACTIVE{/if}</li>
{/foreach}
</ul>

It is not possible because the if accesses the variable $item even if cache is enabled!
if ($_smarty_tpl->tpl_vars[\'current\']->value == $_smarty_tpl->tpl_vars[\'item\']->value[\'id\'])

it should look like this (note that this is handmade, not compilermade):

if ($_smarty_tpl->tpl_vars[\'current\']->value == 12)

testcase.php
testcase.tpl
7af6b444214920055f0e476b62736e9e88058c99_0.file.testcase.tpl.cache.php
7af6b444214920055f0e476b62736e9e88058c99.testcase.tpl.php

@uwetews
Copy link
Contributor

uwetews commented Dec 4, 2015

It's a know restriction that you can't combine normal variables and nocache variables in one tag.
We have this on our todo list, but first experiments showed that it is a very complex task.

Sorry I can't help at the moment.

@0xFEEDC0DE64
Copy link
Author

Isn't it possible that you check every expression while generating the compiled template if it is a cached expression?

@uwetews
Copy link
Contributor

uwetews commented Dec 5, 2015

The problem is that the value of $item.id is not know at compile time. An even worse the value of $item.id does change on each iteration of the foreach loop. The foreach loop is processed while rendering the compiled template. and the variable $item.id does exist only at that time. The cached template does not know any thing about all of this.

@uwetews
Copy link
Contributor

uwetews commented Feb 14, 2016

There is now a solution for your problem with the new tag {make_nocache}.
Read NEW_FEATURES.txt

<ul>
{foreach from=$list item=item}
    <li>{$item.name} {make_nocache $item}}{if $current==$item.id} ACTIVE{/if}</li>
{/foreach}
</ul>

This is now available in the master branch and will later be included in 3.1.30

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants