Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Problem with 'uncached' inside a Layout?


Go to End


6 Posts   1820 Views

Avatar
inCharge

Community Member, 102 Posts

27 September 2011 at 7:52pm

Edited: 27/09/2011 8:29pm

Partial cacheing: http://doc.silverstripe.org/sapphire/en/reference/partial-caching

The uncached tag doesn't seem to work when used inside a layout to cancel a cached tag in the main Page.ss. Or am I doing something wrong?

I have a cached tag in tutorial/templates/Page.ss and an uncached tag in tutorial/templates/Layout/Page.ss, but he contents of the uncached tag are still cached.

There is a workaround, which is to close the cached tag before $Layout and open another cached tag inside the layout file if necessary, then a nested uncached tag works.
Maybe it's good practice never to enclose $Layout in a cached tag, and to consider all layouts on a case-by-case basis. Whatever, I don't think the behaviour I'm seeing is intended. I can't see any reference to this issue in trac.

This is how to reproduce the problem using the tutorial theme. Or is the problem that I've misunderstood how the cached and uncached tags are used?

_config.php

SS_Cache::set_cache_lifetime('any', 24 * 60 * 60);

Page.php

	function CurrentDateTime() {
		return date('Y-m-d H:i:s');
	}

Page.ss
Note the cached tag wrapped around the $Layout

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" >
	<head>
		<% base_tag %>
		<link rel="stylesheet" type="text/css" href="tutorial/css/layout.css" />
		<link rel="stylesheet" type="text/css" href="tutorial/css/typography.css" />
		<link rel="stylesheet" type="text/css" href="tutorial/css/form.css" />
	</head>
	<body>
		<div id="Main">
<% cached 'Outer', ID, LastEdited, SiteConfig.LastEdited %>
<% include CacheStats %>
$Layout
<% end_cached %>
		</div>
		$SilverStripeNavigator
	</body>
</html>

Layout/Page.ss

<h1>Inside layout</h1>
<% include CacheStats %>

Includes/CacheStats.ss
Note the uncached tag wrapped around the first two timestamps in the table

		<div id="ContentContainer">
			<h2>Cache Stats:</h2>
			<table>
				<% uncached %>
				<tr>
					<td>Now</td>
					<td>$CurrentDateTime</td>
				</tr>
				<tr>
					<td>LastEdited</td>
					<td>$LastEdited</td>
				</tr>
				<% end_uncached %>
				<tr>
					<td>Cached</td>
					<td>$CurrentDateTime</td>
				</tr>
			</table>
		</div>

The page type is used to create a page in the CMS. Before viewing the published page, delete all files in silverstripe-cache/cache

The first time the page is viewed, both sets of times are the same.
The second time the page is viewed, the two values of Now are different, which should never happen. All times inside the layout are the same as before, they have been cached, even though they are in a cached tag.

Cache Stats:
	Now		2011-09-26 18:07:42
	LastEdited	2011-09-25 21:59:32
	Cached		2011-09-26 18:07:18

Inside layout

Cache Stats:
	Now		2011-09-26 18:07:18
	LastEdited	2011-09-25 21:59:32
	Cached		2011-09-26 18:07:18

The Now value should always show the current time, because it is uncached, right?

Avatar
tv

Community Member, 44 Posts

10 December 2011 at 7:28am

Hey inCharge, I am having this same problem. Did you ever figure out what was going on with this?

Avatar
inCharge

Community Member, 102 Posts

10 December 2011 at 1:12pm

The work-around I ended up using is to end the Page header's 'cached' statement just before the $Layout, and have another 'cached' statement for the footer, and another inside the layout..

This does mean that you end up with a lot of files in the cache, especially on a big site, but apart fropm that, it isn't as bad as it sounds. It makes sense that caching should be considered on a case-by-case basis for each layout. And it's often the case that the footer is the same for all pages, so using a cache ID like...

<% cached 'Footer', SiteConfig.LastEdited %>

...means one cached version of the footer is shared by every page on the site.

Avatar
tv

Community Member, 44 Posts

11 December 2011 at 3:16am

Thanks for the reply. That's what I was thinking - adding cache blocks inside each layout template.

Avatar
martimiz

Forum Moderator, 1391 Posts

11 December 2011 at 7:21am

Might be something like this: the SSViewer class, that renders the main page, will create a new SSViewer instance to render the $Layout subtemplate. So the main SSViewer has no control over what happens in the $Layout template. It just includes whatever HTML is returned and when $Layout falls within a cached block, it never even bothers to create that second viewer.

So what's left is your solution, I guess. Just wanted to know why :-)

Avatar
HARVS1789UK

Community Member, 31 Posts

1 June 2014 at 2:06am

This is slightly annoying :-(

I was following the approach of caching the entire page content on a page by page basis (in Page.ss) and then adding nested <% cached %> blocks with stricter/more common regeneration rules throughout my various layout/include files (or adding <% uncached %> tags for truly dynamic content)

It should be noted that the behaviour above mentions nesting blocks within Layout but the same is also true for includes.

Can't help but think this should be highlighted or at least mentioned in the docs?