General Principle of @-Notation in Neos?

sorry the many topics in one day. But today maybe is the day to realize a lot of knowledge-gaps and to fill the Base-Holes in understanding Neos :cry:.

I was looking around in documentation, google, forum and sourceCode, but at the end, it remains a big question mark:
I can not explain myself, how the @-notation works in Neos. I use it, but I have no idea, what I’m doing really…
That would not really a problem: I could even just use it - and that’s it.

But for me, it is always a lot easier, to learn things, retain and use it, if I know how they work.
Unfortunately, I find neither in the PHP language, nor somewhere else a fundamental explanation for how it is built, where it is put in in the Core, what are the siblings from «@cache», «@process», «@class», «@if» and at the end, where everywhere I can use it in Neos/Flow.

Maybe a stupid question, or I have overlooked several times, but

  • Did someone know a Documentation about the «General Principle of @-Notation»?
  • How and where that expands PHP, Flow or Neos?

A big topic :wink: so I think we don’t have a clear “big picture” style documentation. But basically @[whatever] are store a metadata the the TypoScript Runtime, so the magic is in the TypoScript package.

Basically you can not extend them (understand add other @[whatever]), but they offer enought flexibility :wink:


Can be use on any cache segment, to configure the TS ContentCache, powerful and highly flexible. But can be hard to get at the beginning for non basic configuration. But the default configuration is fine for most case. Take care when you play with cache configuration.



Can be use to post process any TS path, like this:

# Foo contain the string "test"
foo = 'test'
# Wrap the value (from the string contains is path 'foo') with h2 tag
foo.@process.toHeader = ${'<h2>' + value + '</h2>}
foo.@process.trimIt = ${String.trim(value)}

In this example ‘value’ is a string, but depending on your TS, it can be anything, and you have the full EEL power to transform the value.



You can register a custom PHP implementation for a TS prototype to build TS object that match specific requirements



Skip the rendering of the current TS path is the expression (EEL) return false. Like don’t render an image if the Person page has not image attached. This little @if can help to remove logic from your templates.


1 Like

@dfeyer one point of magic more for typoScript :upside_down:: Cool in a manner.
Thanks for your help!

Eventually I may find the key for :kissing_heart: the deeper understanding of TypoScript

  • runtime-order (like other php-frameworks who are running like in a flow-chart), or at least the point of execution (when exactelly / how often)
  • missing of reusable variables or properties in the prototype-context (in contrast to php/js)
  • difference between prototype with or without path, or prototype in prototype
  • @-magic

I was waiting for the first Neos-Book for more farsightedness. But it seams to move without end

Thanks for your help

Not sure if I understand this one :frowning:

You can not declare a prototype inside an other prototype, but you can override an existing prototype inside an other one and that’s really flexible.

prototype(Your.Package:Foo) < prototype(TYPO3.TypoScript:Value) {
   value = 'Hello'

This prototype will output the string “Hello”

prototype(TYPO3.Neos.NodeTypes:Content) {
    prototype(Your.Package:Foo) {
       value = 'Bonjour'

But if your prototype is rendered inside a Content prototype it will output “Bonjour”. You can use this in many use case, think about custom CSS classes, …

Maybe your question can be a bit more clear on this point ?

Writting a book is hard, but you can help us improve the documentation, by give us pointer where the documation is not clear, not complete enought, …


@dfeyer thanks a lot for [quote=“dfeyer, post:4, topic:1275”]
you can not declare a prototype inside an other prototype, but you can override an existing prototype
Now the next question-mark is gone.

Should be done. if I properly understood and potted it in the topic Overview of General Principle of Prototype.

With study sourceCode, I draw my own flowcharts or found helpful which I extended. At the end I get an image of the rough sequence of code from CMS/Frameworks.
For me, Images helps incredibly more than abstract text.

For Yii, Zendframework, Contao, and (in the early years) for typo3, I could do it in this manner. Because the developers use simple but (at beginning) not less magical-looking code. At the end I got something like: Zend, Yii, WP or this.
Most of the time, I could comprehend the code, or I have to do study to get it. But in Neos with TypoScript-magical «@» also with difficult to grasp «prototype-logic», it is much harder to understand or look in the code, because I can’t follow a tangible code-thread.
So, because I can’t do it for my own like I did before, I hope to find somewhere an Image or something similar for understand what is Neos doing for

  • dispatch a request, like in a flow-chart: This I meant with «runtime-order».
    bad translation into English I think now

For me it is a big mystery, how the prototype from Typoscript is working. For example:
Why it is not an overkill, to do things like this in prototype-declaration:

prototype(Vendor.Site:xyNodeType) < prototype(Content) {

        id = ${q(node).property('id')}
        id.@if.condition = ${q(node).property('id') != '' && q(node).property('id') != null ? true : false}
        class = ${q(node).property('class')}
        class.@process.addEndInfo = ${value + '-EndInfo'}
        class.@if.condition = ${q(node).property('class') != '' && q(node).property('class') != null ? true : false}
 dataArray = TYPO3.TypoScript:RawArray
 dataArray {
        when = ${q(node).property('scrollMeOptionWhen')}
        when.@if.1 = ${q(node).property('scrollMeOptionWhen') != '' && q(node).property('scrollMeOptionWhen') != null}
        from = ${q(node).property('scrollMeOptionFrom')}
        from.@if.1 = ${q(node).property('scrollMeOptionFrom') != '' && q(node).property('scrollMeOptionFrom') != null}
        to = ${q(node).property('scrollMeOptionTo')}
        to.@if.1 = ${q(node).property('scrollMeOptionTo') != '' && q(node).property('scrollMeOptionTo') != null}
        #10 times more like this...


instead of declaration some reusable properties/variables like this:

$id = ${q(node).property('id')}
$class = ${q(node).property('class')}

#or like in js
var id = ${q(node).property('id')}
var class = ${q(node).property('class')}

I can’t find something similar like variables/properties or simple conditional or delete/unset an property in an easy way, like in php/js.

  • this means: «missing of reusable variables or properties in the prototype-context (in contrast to php/js)»

So I guess (and hope), the TypoScript-Magic will cache the hole Typoscript and all properties within. And will only execute once and at next dispatch-process it will choose the calculated end-values of the hole TS, like other CMS with something like:

cached-data-exist-and-are-still-valid ? deliver cached-data : createAndCalculate-newCacheOfResultingValue, store it in fileSystem/cacheSystem and deliver the result.

But this is only an hypothesis.
Because I can’t find the particular codeLines nor the particular cache-File or understand at least the underlying logic from TypoScript.
So I try to toddle with a blindfold and guess witch code will be a bit more effektiv, or at least reasonably error-free. But in this manner the comprehension or at least to get an imagination, what I could do with «an other use of», takes much longer (In best case).

  • This is why I asked for «the point of execution (when exactely / how often)» for the declared TypoScript-Prototype or Typoscript-Logic in the dispatch-process of Neos.
    I hope it would give me a bit more knowledge, without dazzling too. But sometimes, when I stare in the code, the thought appear, «a dark blindfold protects from total blindness».

Nevertheless, I still hope that the TypoScript-magic is not too impossible to comprehend for an average mind - If it will find more and more keys for behind new opening doors.

The stuff is definitely comprehensible. If I just would find half a day I could draw charts for all parts of this. In fact I should do that especially for TypoScript… But time…

We miss a walkthrough / big picture on how a request is processed in Neos - from resolving a node to rendering a result (mostly through TypoScript). @wbehncke did a great talk about this and also gave a good introduction into TypoScript that could help you. Maybe he can share his presentation.

From reading your questions I assume you compare TypoScript to procedural languages which it is not by its nature (but the name might imply). But I guess you already read which also isn’t very exhaustive yet.

Regarding caching:

There’s the content cache ( which caches the complete output of a path (which could be an instantiated prototype) and a runtime cache that will re-use values of a single path (e.g. when evaluating this.myProperty in Eel).


The context in TypoScript is where the current state and thus comes closest to variables in other languages. Since it’s side effect free outside of a path it can only be passed down and not upwards in the rendering definitions (these are naturally nested in TypoScript).

So far, I could write / talk a lot more about this. If you are interested in visualizing some of this I’d welcome it.

Hey everybody :slight_smile:

Great to see this nice discussion going on here!

@mad would you be willing to maybe improve the documentation in this regard with the stuff you learned in this thread?

It’s quite easy, just head over to - find the files you want to change, press “edit” on the top left corner, and write away.

That would be awesome :sunny:
All the best,

1 Like

Hi @sebastian,
yes, I would. But have first to grasp and find a bigger view of. Maybe with @wbehncke’s presentation I will climb the next step… Currently I have only loose ends, flapping in my mind.