Jump to content

Caching Question


Pete
 Share

Recommended Posts

Hi chaps

I've got a quick question about caching - I can't cache a whole template as I've got stuff in head.inc that needs to remain dynamic throughout the site. Is there some way to get around this?

Also, if there is a way to achieve this, is there a way to make part of a template that's set to be cached non-cacheable?

My example is that I have an article template that includes the head.inc and foot.inc files. There's a member bar in the head.inc that needs to remain un-cached (it can display alerts for new messages from my forums etc). Further down the article template is a section that spits out the latest comments on the article - again from my forums - and so that cannot be cached either.

I realise I could use MarkupCache to cache certain bits of the page around the non-cache items and just append the page ID to the cache names, but that could result in many thousands of small cache files in one folder which isn't too tidy, plus I'd prefer to have the options that are available in the template cache (as in the knock-on effects on other pages in the site).

Any suggestions are most welcome :)

On another note, I have a suggestion to improve the cache feature:

I have a field in my articles template called "game" (it's a gaming site, but it may as well be a blog or other article site). Each article is linked to one or more games using this field.

Each game page never changes often, so can be cached indefinitely aside from one small block of code that fetches in a list of related artilcles.

Currently in the cache options, we have the setting: "Clear cache for the saved page and other pages that I specify...". I think it would be great if there were a similar option where you could specify "Clear cache for the saved page and other pages in the following fields..." - then you could select fields linked to other pages that you know will have to have their cache emptied too. That way you can more specifically target which pages are cleared.

My only problem there is that I would need to have that option in addition to "Clear cache for the saved page and parents (including homepage)" so I'm not sure how that could work on the current form - maybe just as a checkbox in addition to the radio buttons so they can be used in combination, which I imagine would then cover all scenarios.

Link to comment
Share on other sites

Two quick notes/ideas:

  • For topbar: disable template caching for logged in members (I think that is default anyway and don't remember if you can change that currently)
  • Use ajax to get latest comments from forums, then your html could be fully cached and you pull those comments on client side.
Link to comment
Share on other sites

Are you sure that you need template caching? Template caching doesn't have to be used, it's just an optimization for situations where it makes sense, and this may not be one of them.

But what Antti mentioned with using some JS for your dynamic parts can be a good way to go because even if the entire page is cached, the JS portion still executes when the page is viewed and can always be dynamic.

Another option is that you could make a simple module that hooks Page::render and replaces your empty <div id='member_bar'></div> and <div id='comments'></div> with dynamically populated versions. This will work even if your template output is cached. Here's an example of such a module:

<?php

class PetesModule extends WireData implements Module {

   public static function getModuleInfo() {  
       return array(
           'title' => 'Module for Pete',
           'summary' => 'Replace member_bar and comments divs with dynamic populated versions',
           'version' => 100,
           'autoload' => true,
           'singular' => true,
       );
   }

   public function init() {
       $this->addHookAfter('Page::render', $this, "pageRender");
   }

   public function pageRender($event) {
       $page = $event->object;

       // abort for templates you know you won't be needing
       if(!in_array($page->template->name, array('template1', 'template2'))) return;

       $out = $event->return;

       $bar = "<div id='member_bar'> ...dynamic content... </div>"; 
       $out = str_replace("<div id='member_bar'></div>", $bar, $out); 

       $comments = "<div id='comments'> ...comments here... </div>";
       $out = str_replace("<div id='comments'></div>", $comments, $out); 

       $event->return = $out; 
   }
}
  • Like 1
Link to comment
Share on other sites

It's possible that caching may not be needed, but I'm looking into it as it's a fairly well-visited site with a few hundred thousand page views a month (not massive, but not small either, so any increase in loading time is a bonus).

The real reason I was looking into it is that by the time I'd finished my article template I'd called in various other bits and bobs (an example being Google's YouTube API for PHP to fetch and display a video - used the API as I needed to check if a video had a screenshot with it - most do, but you can't check without the API), plus there were a lot of blocks put together from content from other pages that, whilst the content won't change, was enough that it got me thinking about the overhead as one of the templates will be pulling in information from about 7 different pages so if I can cache that then that would be good.

Thanks for the module - that looks to solve my problem completely since 95% of the content will never change, but those two bits will.

I was also wondering if the way you and some of the others use templates could also achieve the same result? Not a problem if it doesn't, but I was just curious.

Link to comment
Share on other sites

I was also wondering if the way you and some of the others use templates could also achieve the same result? Not a problem if it doesn't, but I was just curious.

I'm not sure that any template file methodology really matters here, at least not without getting complex. But you could certainly achieve the same result as the module just by placing tags (or blank div's, like in the module) into your markup, using MarkupCache, and then replacing the tags/divs with the dynamic versions. But I think using the module is probably more straightforward/easier. Using the module method, you don't have to use MarkupCache, just template caching.

Link to comment
Share on other sites

Here's another scenario that's slightly more suited to some sort of cache I think.

All my articles have a publish_date field (datetime). On a sidebar, I'd like to list all the years for articles, and if I click on a year, list all the months that have articles for that year (it's basically an archive link list).

This basically works fine as I've already built the code behind it, however I'm very conscious that to pull this together it has to iterate through EVERY article.

Would the most sensible way to cache this be to use a module again, cache the result using MarkupCache and then perform a check for a new page being saved using the article template and rebuild the list? I'm thinking that to be flexible I'd probably just be safer caching a serialized array of all the relevant years and months. Also, since articles are becoming a bit sporadic on this site, how long can you actually cache something for using MarkupCache?

Just wondering if that makes sense or if there's a better way - I'd rather not have to iterate through every article every time someone hits that section of the site ;)

I'm also finally going to play with pagination tonight. Should be fun! :)

Link to comment
Share on other sites

Pete, I think MarkupCache is always a good way to go, but if you are worried about having some process clear it, then I'd suggest just using a short cache time instead. Something like a 5-10 minute markup cache would probably provide a good balance of keeping things cached and up-to-date.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...