Fork me on GitHub

please explain Caching  Bottom

Go to page 1 - 2 [+1]:

  • been looking around for a solid explanation of how Zikula implements Smarty Caching and cannot find it. Please tell me I missed it or where to find it if it exists.

    I know about the Smarty caching documentation and I know about the zikula docs on templating. I was hoping for something a bit more explanatory like 'this is how you should be using caching in your module'... which I cannot seem to locate. Anyone have any information? I promise to add it to the Wiki if I find it.
  • in general i implement caching in the controller like below (please note that the following example applies to zikula 1.3, but the principle is the same):

    Code

    // set caching to always on (this is optional)
    // if you specify it, it will be always on (or off if you specify false)
    // else, the value will be provided by Theme module
    $this->view->caching = true;

    // set lifetime (this is optional)
    // if you don't specify it, it will be provided by Theme module (default is 3600 seconds)
    $this->view->cache_lifetime = 7200;

    // use a cache ID. this is very important as it differentiates the caches from each other
    // eg if you want to cache an article, it's ok to use the $article_id
    // if you want to cache the first page from a list of articles belonging to a certain category
    // you should use all the above
    // eg $category_id . '_' . $page
    // the main purpose is that the cache_id should be unique
    $this->view->cache_id = $article_id;

    $template  = 'mytemplate.tpl';

    // check out if the contents is cached.
    // if it is, display the cached page
    if ($this->view->is_cached($template)) {
        return $this->view->fetch($template);
    }

    // if execution get's here, then the page is not cached
    // do stuff like fetch data from database etc.

    // return output
    return $this->view->fetch($template);


    In the template, if you want something to not be cached, you should use {insert} and {nocache}. But keep in mind that if you use
    data inside these blocks (which you probably are), these data must be assigned from the controller before the cached page is returned.

    For example if i have the following in my template

    Code

    {nocache}
    My name is {$myname}
    {/nocache}


    then the variable $myname has to be assigned to the template by the controller BEFORE the controller returns the cached template.

    I would be interested to know if anyone has different techniques/solutions for enabling caching as in general it is very important for sites having a lot of visitors.
  • so.... if a module doesn't implement what you have above, then no caching is done at all? There isn't any 'automatic' caching by pnRender/View ?
  • The site administrator can set default behaviour (better), but modules can override that behaviour for example and be told to never cache.

    I would point out also that direct access to the view object properties is now forbidden and will be removed in a later version - use setters.

    Drak

    --
    Zikula Lead Developer
    Board Member of the Zikula Foundation
    Follow me on twitter.com/zikuladrak
  • drak

    The site administrator can set default behaviour (better)


    so... if the module NEVER mentions caching, it will utilize caching if the site admin chooses it? How is this accomplished? Is there a check in the ->fetch() method that returns the cached page if available? If so, why do it in the module code? if not, how does it work?
  • Yes. There is no particular reason for a module to change cache settings unless it is to specifically turn it off under all circumstances. It's totally automatic, the rendering object just takes care of it.

    Drak

    --
    Zikula Lead Developer
    Board Member of the Zikula Foundation
    Follow me on twitter.com/zikuladrak
  • I'm sorry to be so dull and belligerent, but I know you're used to it. icon_razz

    so... this last bit of code from Thanasis above;

    Code

    // check out if the contents is cached.
    // if it is, display the cached page
    if ($this->view->is_cached($template)) {
        return $this->view->fetch($template);
    }

    // if execution get's here, then the page is not cached
    // do stuff like fetch data from database etc.

    // return output
    return $this->view->fetch($template);


    this is not required?? just do a standard ->fetch() ??

    Also, what about cacheids? does the rendering object assign some kind of ID automatically? how does it know what to use?
  • I'm no expert in this but I think it really depends on your module logic. There may be some sense in not processing certain logic if caching exists for that template already but that would really depend on what you are doing in the first place. In general, a standard fetch() is all you need to do - the caching was designed to be free and getting involved in it may introduce unnecessary complexity in your module. Certainly there are cases where you need to explicitly turn it off - that's maybe more common.

    Cache IDs are based on things specific to that template - owning module, template name, language and calculated automatically. You can override this if you wish, but it's not necessary.

    Drak

    --
    Zikula Lead Developer
    Board Member of the Zikula Foundation
    Follow me on twitter.com/zikuladrak
  • The check for being cached or not and delivering the cached template immediately can be quite improtant for some modules where a lot of processing is being done that is not needed when the template is cached.
    I dont see any automatic cache_id generation in Zikula_View, only:

    Code

    $this->cache_id = '';

    in the constructor. Doesnt the cache_id need to be set for caching to work? If I read this correct then there will be no automatic caching if modules dont use methods for enabling cache and setting a cache_id. Or ?

    So functions to use instead of direct access would be setCaching, setCache_Id and setCache_lifetime from Zikula_View.

    --
    campertoday.nl, Module development, Dutch Zikula Community
  • The cache_id and compile_id is used to make calculations. As far as I am aware, there is no real need to set any of these manually, the framework takes care of these because in the end all these are used to do is generate filenames and they are done uniquely already.

    Drak

    --
    Zikula Lead Developer
    Board Member of the Zikula Foundation
    Follow me on twitter.com/zikuladrak
  • As pointed out in the link here, the cached template is automatically returned by Smarty by using display() and fetch() functions.

    So even if you don't implement the code below

    Code

    if ($this->view->is_cached($template)) {
        return $this->view->fetch($template);
    }


    the cached page will be returned to you anyway by Smarty with the use of fetch() function called by the controller to get the output.

    But the whole point of my example above is to save valuable resources.

    What is the point of fetching data from the database if you are going to use the cached template anyway?

    And there is no way you can run a site with thousands of visitors if you don't optimize your module code (both database queries and code execution).

    As for the cache id, i am 99% sure that is needed (i will leave 1% out because i haven't double checked it) and i will explain why.

    Suppose you have a display function that you are showing an article.
    And suppose you have an article with id=1 and an article with id=2.

    If you turn on caching and you don't specify cache_id, then when you display the article with id=1, a cached output of it will be stored.
    The cached output is actually stored in a filename containing
    1) language
    2) Theme name
    3) Module name
    4) template name
    5) cache_id
    6) compile_id
    You can see this if you closely examine the ztemp/view_cache folder (and of course Zikula_View).

    Immediately, if you try to show article with id=2, Smarty will check for a cached template. And since you haven't used a cache_id, then the 'signature' of the cached template for the article with id=2, will be the same as the article with id=1. That means that instead of the system showing the second article, you will be presented with the cached version of the first article.

    But if you used a cache_id, then the cached file created would be different for each article, so the system (Smarty actually) would return the correct one.

    And since we are on the subject, i have been thinking about a feature that is missing, the ability to enable/disable render caching per module. This feature is actually available for Theme caching but not yet available for view/render caching.
  • Yes, you are right about the ID of object because otherwise we're simply caching the template and not the template + data which would result in false cache results. For single lists you would simply need the item ID, however, for paginated lists, you are going to need a range of IDs, for example the cache ID could be "10-19", or "10,12,15,18,20" for a search. All of which makes implementing cache support a bit more tricky for the module developer, especially for paginated data. Maybe the parameters of the pagination would be good, like start id, + number of items (for flat searches).

    Regards,

    Drak

    --
    Zikula Lead Developer
    Board Member of the Zikula Foundation
    Follow me on twitter.com/zikuladrak
  • It all really depends on what you want to cache.
    If you want to cache an article, then the article_id is all you need.
    If you need to cache a list of articles, then you will probably need the page you are on eg articles_1, articles_2 and so on.

    The point is to create a unique cache_id (and compile_id).

    And now that i think about it, we don't use the function name in the filename creation, so in the extreme case that you have a function display1 and a function display2, and they both have an article with id=1, then you might get a false cache there also.

    So if you have such scenario, it's better to include the function name in your cache_id also eg 'display_1' instead of just '1'.

    best,

    Thanasis
  • Correct me if I am wrong, but I think for compile_id is ok to leave because it's calculated based on module name, template name, theme name, and language. That gives us a unique compile per template, so there should be no need to manually alter that. The addition of the cache id allows the templates to be caches according to their data content.

    Drak

    --
    Zikula Lead Developer
    Board Member of the Zikula Foundation
    Follow me on twitter.com/zikuladrak
  • yes, you are probably correct, but i can't remember exactly what the deal is with compile_id. I don't use it and i have never encountered any issues. Maybe i should take a closer look at it though.

Go to page 1 - 2 [+1]:

This list is based on users active over the last 60 minutes.