Smarty Forum Index Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon.

Nested includes with caching and assigned vars

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> General
View previous topic :: View next topic  
Author Message
wern0561
Smarty Rookie


Joined: 05 Jan 2009
Posts: 13

PostPosted: Mon Sep 09, 2013 9:50 pm    Post subject: Nested includes with caching and assigned vars Reply with quote

SYNOPSIS
Basically, what I am looking for is a way to assign variables within a template that get saved and reused in the cached version so that I can use the cached variables to include other files. This may seem odd but the included sub-template contains an expensive database call and complex logic. Its slow to generate but doesn't change much. I want to cache this sub-template for much longer than the parent template is cached. Is this possible or am I going about this the wrong way?

MORE DETAIL
From within my main document I have some simple logic that checks what vars are passed in the url to determine what template to load with smarty and assign some variable. I have one main template which is the shell of the site. It then includes a menu template and content template. These second level templates get cached using smarty. The content templates get their data from a custom plugin that just instantiates an object that contains the 'content' logic and assigns this object to the template as a variable.

This works fine but the problem comes in with a few of my 'content' templates that need to load templates into them as well. What I would like to do is use the output from my assigned object variable to tell it what 3rd level template to load and cache. Unfortunately, my assigned variables aren't being baked into the cached 'content' template so the 3rd level templates don't get included and instead through errors for an undefined index.

I've read and reread the docs on 'controlling caching', {include}, {assign}, and {capture}. I am a little unclear as to how (if at all) to get these variables saved into the cached template so it can be reused to control the including of other templates.

Here is an example of what i'm trying to do.

Code:

{assign_object filename="content_details" assign="obj"}
...
{include file=$obj->subTemplate cache_lifetime=$obj->subTemplateCacheLife compile_id=$obj->subTemplate cache_id=$obj->subTemplateId}
...


Any thoughts are ideas are appreciated.
Back to top
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Mon Sep 09, 2013 11:21 pm    Post subject: Reply with quote

Can you execute {assign_object... } in nocache mode?

Code:
{assign_object filename="content_details" assign="obj" nocache}
...
{include file=$obj->subTemplate cache_lifetime=$obj->subTemplateCacheLife compile_id=$obj->subTemplate cache_id=$obj->subTemplateId}


If yes it should work.
Back to top
View user's profile Send private message
wern0561
Smarty Rookie


Joined: 05 Jan 2009
Posts: 13

PostPosted: Mon Sep 09, 2013 11:32 pm    Post subject: Reply with quote

Thanks for the suggestion. Yes. I can do that but it kind of defeats the purpose of caching the output of that template to begin with.

The obj being assigned does a database lookup and some php logic. I would really like to cache the output but pass along just a few variables.

Something like this would be even fine. (I've tried and this doesn't seem to work)
Code:

{assign_object filename="content_details" assign="obj"}
...
{assign var="subTemplate" value=$obj->subTemplate}
{assign var="subTemplateCacheLife " value=$obj->subTemplateCacheLife}
{assign var="subTemplateId" value=$obj->subTemplateId}

{include file={$subTemplate} cache_lifetime={$subTemplateCacheLife} compile_id={$subTemplate} cache_id={$subTemplateId}}
...
Back to top
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Tue Sep 10, 2013 3:16 pm    Post subject: Reply with quote

This is currently not possible.
The problem to assign a varibale in a cached template and make it's value available as nocache values or as in your example as parameters when calling subtemplates with different caching parameter has already been addressed in the developement of the next major version 3.2. I currently have not yet a release date for it.

I will look if I can find a workaround for 3.1 for you,
Back to top
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Tue Sep 10, 2013 3:49 pm    Post subject: Reply with quote

Okay here is a sort of "dirty" workaround for you.

Save the following as block.cache.php in your plugins folder
Code:
<?php
 function smarty_block_cache($params, $content, $template, $repeat)
{
  if ($content !== null) {
       $assign = $params['assign'];
      return  "/*%%SmartyNocache:{$template->properties['nocache_hash']}%%*/<?php \$_smarty_tpl->tpl_vars['{$assign}'] = new Smarty_variable('{$content}');?>\n/*/%%SmartyNocache:{$template->properties['nocache_hash']}%%*/";
  }
}


In your template
Code:
{assign_object filename="content_details" assign="obj"}
...
{cache assign='subTemplate'}{$obj->subTemplate}{/cache}
{cache assign='subTemplateCacheLife'}{$obj->subTemplateCacheLife}{/cache}
{cache assign='subTemplateId'}{$obj->subTemplateId}{/cache} 


{include file=$subTemplate cache_lifetime=$subTemplateCacheLife  cache_id=$subTemplateId}
...


Another note: You do not need a compile_id.
Back to top
View user's profile Send private message
wern0561
Smarty Rookie


Joined: 05 Jan 2009
Posts: 13

PostPosted: Tue Sep 10, 2013 5:09 pm    Post subject: Reply with quote

Hi U.Tews. Thank you so much for your thorough and quick response. I will give that a try and see if it works.

I'm glad to hear this might find its way into a release in the future. I generally try hard to figure things out on my own but this really had me stumped.
Back to top
View user's profile Send private message
wern0561
Smarty Rookie


Joined: 05 Jan 2009
Posts: 13

PostPosted: Tue Sep 10, 2013 5:38 pm    Post subject: Reply with quote

U.Tews. I just tried the code you provided and it seems to be working perfectly. I inspected the cached files and everything seems to be correct. I'll continue reviewing it. If I find anything I'll post it but this seems to be working.

Thanks again.
Back to top
View user's profile Send private message
wern0561
Smarty Rookie


Joined: 05 Jan 2009
Posts: 13

PostPosted: Tue Sep 10, 2013 8:29 pm    Post subject: Reply with quote

So after looking at this a little closer I have found one issue but its a simple fix. The cache_lifetime expects an integer and the block function you initially provided is writing every variable as a string. When the {include} code saw a string it was defaulting to 3600 (an hour). I added a little check to see if the variable was numeric and handled it accordingly. So far this is working for me but it hasn't been tested very thoroughly.

Code:

<?php
 function smarty_block_cache($params, $content, $template, $repeat)
{
  if ($content !== null) {
       $assign = $params['assign'];
      if(!is_numeric($content)) $content="'$content'";
      return  "/*%%SmartyNocache:{$template->properties['nocache_hash']}%%*/<?php \$_smarty_tpl->tpl_vars['{$assign}'] = new Smarty_variable({$content});?>\n/*/%%SmartyNocache:{$template->properties['nocache_hash']}%%*/";
  }
}
Back to top
View user's profile Send private message
wern0561
Smarty Rookie


Joined: 05 Jan 2009
Posts: 13

PostPosted: Tue Sep 10, 2013 8:49 pm    Post subject: Reply with quote

No, this still does not work. Its assigning the variable as an integer now but its still being interpreted as a string, I think.

The resulting cached content page:
Code:

...
<?php $_smarty_tpl->tpl_vars['subTemplateCacheLife'] = new Smarty_variable(2625651);?>
<?php $_smarty_tpl->tpl_vars['subTemplateId'] = new Smarty_variable('657-8');?>

<?php echo $_smarty_tpl->getSubTemplate ("subTemplate.tpl", $_smarty_tpl->tpl_vars['subTemplateId']->value, $_smarty_tpl->compile_id, 1, null, array('cache'=>$_smarty_tpl->tpl_vars['subTemplateCacheLife']->value), 0);?>
...


but when you look at the cached subtemplate I find this:
Code:

...
  'cache_lifetime' => 3600,
...
Back to top
View user's profile Send private message
U.Tews
Administrator


Joined: 22 Nov 2006
Posts: 5068
Location: Hamburg / Germany

PostPosted: Tue Sep 10, 2013 9:06 pm    Post subject: Reply with quote

You did in {include } assign the lifetime to variable cache and not to cache_lifetime.

It does also work if life_time is passed as string.
Back to top
View user's profile Send private message
wern0561
Smarty Rookie


Joined: 05 Jan 2009
Posts: 13

PostPosted: Tue Sep 10, 2013 9:25 pm    Post subject: Reply with quote

You are correct. I am updating some old code to smarty 3 and I forgot to rename cache to cache_lifetime. That was sloppy on my part. Thanks.
Back to top
View user's profile Send private message
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> General All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP