Jump to content

Cache entire page except some part of it? Approaches?


Aleksey Popov
 Share

Recommended Posts

Tell me please, is it possible to cache entire page with the exception of some part of it. For example I need to load a new random image with every new page update but all others parts of page should be cached for months.
 
(may disappear later on a production site)

btw: thanks for all PW developers for engine )))
Link to comment
Share on other sites

 I'm afraid it will complicate the design and also may potentially cause overload. No?

It's pretty simple really. Shouldn't complicate or overload anything.

Personally I would go the JS route, but just throwing another option out there.

Link to comment
Share on other sites

Most of what we do in templates has little to do with Pw solution. 99 is plain php js HTML and css. There's no Pw out of the box way. If I understand correctly you enable template cache for whole page but want a little part dynamic. So you're left with js or street replace output with php (again not pw). Using markup cache might be possible with an easy template but don't think worth of caching all 'around' that little dynamic part. Also markup cache has a fixed expire time you set and not by rules like when a page updates.

If you're afraid of js I would try catching output with hook on Page::render and str_replace the parts you need.

Once using procache instead of template cache eBen this won't work cause no php and mysql. So you're left with js again.

Link to comment
Share on other sites

On the other hand your page is not heavy for ProcessWire and if you don't expect thousands of visitors every day the site it should perform very well even without caching. This would not mean that you should not use ProCache (Not much time to implement and cheap to buy).

But as Soma suggested there's nothing wrong with a few lines of Javascript. 

Link to comment
Share on other sites

An image is a already separate file from the HTML page, so it will be served independently anyways. You can keep the HTML img tag static and just swap out the image by doing something like this:

<img src="/penguin/?of=d00m.jpg" />
<?php
    if ($input->get->of == 'd00m.jpg') {
        header("Content-type: image/jpeg");
        readfile($page->pics->getRandom()->size(50,50)->url);
        die();
    }

Pros:

– that url serves a random image every time, no matter how you access it

Cons:

– the url serves a random image every time, no matter how you access it

I’m not really sure how this technique competes against a JS solution, but it’s an approach you can take.

  • Like 4
Link to comment
Share on other sites

Most of all I'm UX and frontend designer so that's not a problem to make a kind of static js slider.

Of course, this project has a very small amount of site visitors, and I will cache main page and sections. A plain pages I leave uncached.

But it would be ideal if it should be possible to cache entire page and leave only a fragment. This is inverse case to the markup cache module usage.

It just interesting to me to understand the limits of.
Link to comment
Share on other sites

@Jan

Nice technique, but won't that only pull a random image for the first page view that creates the cache file?

For that to work, do you need to add "of" to the cache disabling variables in the cache settings for the template?

Wouldn't PageRender just serve the cache file without ever getting to the PHP in your template?

Link to comment
Share on other sites

@Jan Romero

Looks good, but when you enable template caching it will cache the output and therefore show the same image again. Unless you configure the cache to ignore caching when using the GET variable, but in this case there is no caching at all

Edit: Sorry didn't look carefully :)

@Aleksey Popov

I guess you're after a solution some other template engines are offering where you specify a sction like this:

{nocache} Hey, I'm dynamic {/nocache}

As far as I know, there is no solution out of the box. Use the techniques from Soma or Reno. A module to build something like this in ProcessWire would be easy, but you wouldn't gain any performance compared to the other solutions.

Cheers

  • Like 1
Link to comment
Share on other sites

I knew Pete had asked about this ages ago, took me a minute to find it.

Check out this reply from Ryan — it's basically an example of the str_replace() idea Soma mentioned above.

This works great with Template cache, but not with ProCache (which completely bypasses php). JS solution works with ProCache also.

  • Like 1
Link to comment
Share on other sites

Why shouldn't jan's example not work? I used a similar tchnique just recently. The image src is just a static url to return a random image. Of course in this case it's only good to serve one image src, limited to whatever image, but I think most of the time theres a need to do a little more with little junks of HTML. That's where js or str replace come in next.

  • Like 1
Link to comment
Share on other sites

Just thinking about it again jan's example, I think you guys are right in that if the php is in the cached template itself it wouldn't work as that code would never get executed, but remember that you can define GET vars on template settings, where when present to not cache the page. But you can also use a page for those calls without caching or use a php script bootstrap PW.

Considering using template cache with a js inline call to a url that is current page with a GET var "mysnippet". Enter a cache time and add "mysnippet" to the "Cache disabling GET variables" appearing underneath.

Now consider this snippet:

$content .= "<script src='{$page->url}?mysnippet=bit'></script>";
if($input->get->mysnippet == "bit"){
    header("Content-Type: application/javascript");
    echo "document.write('<div class=\"bit\">');\n";
    foreach($page->images->find("sort=random") as $img) echo "document.write(\"<img src='$img->url'>\");\n";
    echo "document.write('</div>');";
    exit();
}

Will output random sorted images from the page in a template cached page.

Edit: This only works when you use delayed output, hence the $content .= opposed to the direct echo "..." inside the condition, since this allows you to exit the script and not get other markup output before or afterwards.

Same example 

$content .= $page->body;

$content .= "<script src='{$page->url}?mysnippet=bit'></script>";

if($input->get->mysnippet == "bit"){
    $images = '';
    foreach($page->images->find("sort=random") as $img) {
        $images .= '<img src="' . $img->url . '">';
    }
    header("Content-Type: application/javascript");
    echo <<<_MKP
    document.write('<div class="bit">$images</div>');
_MKP;
    exit();
}

$content .= $page->sidebar;
  • Like 3
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...