[TYPO3-english] Do not cache part of Fluid template. How to?

Stephan Schuler Stephan.Schuler at netlogix.de
Thu Nov 7 17:57:02 CET 2013

Hash: SHA256

Hi Viktor.

I might not get your problem. But as far as I understand it, it's not related to Fluid but basic TYPO3 core caching.

The Fluid output is *not* cached as a string. The only out-of-the-box caching mechanism I know about is the compiling feature that creates PHP closures out of a certain Fluid. The closure takes all the params the original Template had and take and creates kind of "basic inline string concatenation", which avoids Fluid parsing again and again.

The template:

Gets parsed to something like
Return '<span>' . $argument[0] . '</span>';

As long as you don't put your user data inside your template but use proper arguments (which you did, according to your first email), Fluid caching should be seamless to you.

I obviously didn't explain the whole thing, since it's quite complex as soon as it comes to nesting of those. You might have noticed that I just used "Fluid" and avoided calling partials, ViewHelpers and templates.

I think your problem isn't related to Fluid at all but just boils down to regular core caching of USER and COA, which can be only avoided by using USER_INT or COA_INT.
The thing is: Fluid output usually results by either having the FLUIDTEMPLATE TypoScript object, which *is* cached by default, or having an extbase extension. The extbase extension decides on demand if it's rendered as USER or USER_INT, based on the action configuration.
Let's assume you have either the FLUIDTEMPLATE or the USER variant of the extbase extension.

Then just putting a not-cached thingy right around this will affect your output caching behavior in the way you expect, since it's usually embedded in a COA or CASE or whatever, which is cached itself. And as long as you do not "throw the no-cache-ability" up your TypoScript rendering hierarchy, they will always return the cached content without calling the not-cached Fluid template part.

Rendering of non-cached content goes this way:

There is cached object. Let's say it's "10 = COA".
This has cached objects inside. Let's say "10.10 = USER"
Both return strings and both give a cachable result.

Let's assume the following:
10 = COA
10.wrap = <span>|</span>
10.10 = USER

This could have the result "<span>foo</span>", where "foo" is the result of the user func.
Fully cached.

The 10.10 could be USER_INT instead:
10 = COA
10.wrap = <span>|</span>
10.10 = USER_INT

While rendering the cached part, the result should be something like this:
<span><!-- INT_34khsdfio3h4f --></span>
This one is fully cached, too. But "INT_34khsdfio3h4f" is a string placeholder to do some uncached stuff later and replace it.

In another rendering step, the "INT_*" part gets replaced by TYPO3 core.
This mechanism allows caching.

This is why your #4 approach works: Because "lib.noCache.pageHeader" results "INT_olij2eflhisdf" in the first place, gets cached as this very placeholder string and replaced by an non-cached execution variant at the very end of the TYPO3 frontend rendering process.

As you can see, this thing is far away from being ready to be used inside of a given FLUIDTEMPLATE or Extbase View. If you want to have a controller do like "$this->view->assign('user', $TSFE->fe_user->user);", then this works just. If you wrap the output of "{user.email}" in an "do not cache" fluid part (which could work like the COA_INT or USER_INT and return just the "<!-- INT_* -->" placeholder), this stops working at all. Your controller ends, the view is rendered completely and contains this placeholder segment. Then the post-processing core feature wants to interpret the INT_* fragment and has completely no knowledge about which controller context you're in. No settings, no variable container. You're out of extbase here. In terms of Flow, the subrequest is over.

That's the reason why I guess this imho will not work as you expect it.

There are several ways that will work.

1: Do what you suggested in #4. That's kind of ugly because you have really mixed stuff in terms of TypoScript, Extbase, and Fluid.

2: Your #4 approach could be enhanced. Create your very own "tsfeViewHelper" and call "<my:Tsfe path='fe_user.user.email' />". This is kind of tricky because you need to store something like a "view helper state" somewhere for recurring requests that lack the environment and arguments. But that could be working. The only drawback is that you are forced to make the actual rendering mechanism of your ViewHelper independent from Extbase and Fluid. Kind of like the cObjectViewHelper does.

3: Skip the whole thing and introduce kind of "global replace strings". They are ugly, difficult to maintain and might conflict when using special characters and being used in JSON or HTML attributes. But they are fast and cachable. You could use "###USERNAME###" right inside of your code and wrap the page.10 object with stdWrap.replace.

4: The username frontend stuff could be completely removed from PHP rendering and done completely on the client side. The most convenient approach I know about is AngularJS. Just expose "{user.name}" to you the HTTP output of your TYPO3 and use client side JavaScript code utilizing data binding of a user object in the client JS scope. I know that this needs to be considered well and isn't something you just push ontop of an existing page. But if you're site concept allows that and has heavy user interaction (like in an online shop, the minibasket is a good example for that) that should be placed ontop of fully cached pages, this is definitively worth a try.

For all non-cached FE stuff you should consider a very important thing: HTTP cache headers that allow or forbid client side caching. As soon as a single non-cached object USER_INT or COA_INT, currently) is rendered on a specific URL, this one returns some "do not cache" headers to the client. The definitively fastest solution is my fourth suggestion. It allows fully cached pages returning proper cache-headers being sent to the client. That allows the client for e.g. cache the "/home" page of your site completely. Not a single "301 Not Modified" request needs to be done. Will save some ms.
And ontop of that, that's just another thing you will need to consider as soon as you're playing around with advanced transparent caching mechanisms like Varnish.

I hope I could make one thing clear: It really depends on what you're trying to do.


Stephan Schuler

Telefon: +49 (911) 539909 - 0
E-Mail: Stephan.Schuler at netlogix.de
Website: media.netlogix.de

- --
netlogix GmbH & Co. KG
IT-Services | IT-Training | Media
Neuwieder Straße 10 | 90411 Nürnberg
Telefon: +49 (911) 539909 - 0 | Fax: +49 (911) 539909 - 99
E-Mail: info at netlogix.de | Internet: http://www.netlogix.de

netlogix GmbH & Co. KG ist eingetragen am Amtsgericht Nürnberg (HRA 13338)
Persönlich haftende Gesellschafterin: netlogix Verwaltungs GmbH (HRB 20634)
Umsatzsteuer-Identifikationsnummer: DE 233472254
Geschäftsführer: Stefan Buchta, Matthias Schmidt

- -----Ursprüngliche Nachricht-----
Von: typo3-english-bounces at lists.typo3.org [mailto:typo3-english-bounces at lists.typo3.org] Im Auftrag von Viktor Livakivskyi
Gesendet: Donnerstag, 7. November 2013 13:27
An: typo3-english at lists.typo3.org
Betreff: [TYPO3-english] Re: Do not cache part of Fluid template. How to?

So, nobody had done such common task, as output user's name in main Fluid template (not in plugin output)?
TYPO3-english mailing list
TYPO3-english at lists.typo3.org

Version: PGP Universal 3.3.0 (Build 9307)
Charset: utf-8


More information about the TYPO3-english mailing list