|
Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon. |
|
View previous topic :: View next topic |
Author |
Message |
n0xor Smarty Rookie
Joined: 04 Dec 2014 Posts: 6
|
Posted: Thu Dec 04, 2014 2:21 pm Post subject: Really cache variables/arrays/objects |
|
|
I've had the problem that it seemed just impossible for me to cache real data in the template. I'm from Germany so it's a bit hard to explain what I mean, but the case is that I was not able to cache the contents of a variable and use that in a nocache block.
What I was trying to achieve: I'm working on a platform presenting some real life shops and the user should see if the shop is opened and the opening time of the current day. When it comes to performance I wanted to cache all those sides. The only problem is if I decide to cache those pages for multiple days that THE WRONG day is cached and displayed.
I've struggled a bit but found the following solution (yes I know it's a very strict solution and I would really appreciate if someone brilliant shows up and provide some genius regex for detecting the variables)
The Plugin:
Code: |
function smarty_prefilter_assign_serialize($source, Smarty_Internal_Template $template)
{
$return = ""; $pos; $pos2; $pos3; $lastpos = 0;
$pos = stripos($source, '{assign_serialize "', $lastpos);
while(is_numeric($pos))
{
$pos2 = stripos($source, '"', stripos($source, '"', $pos+19)+1)+1;
$pos3 = stripos($source, '"', $pos2)+1;
$return .= substr($source, $lastpos, $pos).'{assign "'.substr($source, $pos+19, $pos2-($pos+19));
$varName = substr($source, $pos2+1, $pos3 - $pos2 - 2);
$posRef = array(stripos($varName, '['),stripos($source, '->'));
$var;
if(is_numeric($posRef[0])&&(!is_numeric($posRef[1])||is_numeric($posRef[1])&&$posRef[0]<$posRef[1]))
{
$var =$template->smarty->tpl_vars[substr($varName, 0, $posRef[0])]->value[substr($varName, $posRef[0]+1, -1)];
} elseif(is_numeric($posRef[1]))
{
$var = $template->smarty->tpl_vars[substr($varName, 0, $posRef[1])]->value->{substr($varName, $posRef[1]+2)};
} else
{
$var = $template->smarty->tpl_vars[$varName]->value;
}
if(is_object($var) && method_exists($var, "getSerialized"))
{
$return .= urlencode(serialize($var->getSerialized())).'"';
} else
{
$return .= urlencode(serialize($var)).'"';
}
$lastpos = $pos3;
$pos = ($pos3 === false)?$pos3:stripos($source, '{assign_serialize "', $lastpos);
}
return $return.substr($source, $lastpos);
}
|
In the Template:
Code: | {assign_serialize "tplVarName" "$arr[1]" nocache}
{nocache}
{$tplVarName = unserialize(urldecode($tplVarName))}
{$tplVarName["someIndex"]->someMethod()}
{/nocache}
|
Due to this code there is no need to fetch a lot of data from a database, if that data is used in a dynamic context. Hope that helps someone
I haven't found anything like this so I decided to share this with you. Somewhere on my search through the Internet it said this feature will be included in 3.2. If that is true I hope this code snippet helps developing that feature!
If there are any questions on usage don't hesitate to ask. Any suggestions for improvements are always welcome.
Hope that there are not 2 much mistakes in spelling (I'm awake 32+h by now) |
|
Back to top |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Fri Dec 05, 2014 4:02 am Post subject: |
|
|
Your problem is that you are trying to cache whole page. Don't. Cache separate blocks, then you can actually cache the data you want for the time you need to. If you then cache the whole page, that is assembled from these blocks, you can do that for minutes instead of days. And the cache will still be effective. |
|
Back to top |
|
|
|
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
|