Variables in Fusion / TypoScript2


(Martin Huber) #1

Hi together,
I try to get more overview in Fusion / TypoScript. So I used variables in my scripts. Like in this Post ( Variable in TypoScript 2 )

Most of the time it works with ease.
But when I try to define a variable outside of an fusion-path, within I loose the value and maybe the variable too.

#works:
//class has value of testNodeProperty within
prototype(Vendor.Site:TestNode) < prototype(TYPO3.Neos:Content) {
	testVari = ${q(node).property('testNodeProperty')}
	class = ${this.testVari}
}
```

#does NOT work:
// attributes.class has no value within
prototype(Vendor.Site:TestNode) < prototype(TYPO3.Neos:Content) {
testVari = ${q(node).property(‘testNodeProperty’)}
attributes {
class = ${this.testVari}
}
}

Simple Example: In real there are more calculations, if-then's, preg_replace ... With ${this.testVari} I would win more overview and simplicity.

***How could I use this.-syntax also in encapsulated (path-)situations?***
<small>Or should it work and there must be an error in my script?</small>

(Martin Ficzel) #2

this is a reference to the current fusion context-object. In the second example it would address a property testVari inside attributes wich obviously is not there.

I think the thing you are looking for is @context

prototype(Vendor.Site:TestNode) < prototype(TYPO3.Neos:Content) {
	@context.testVari = ${q(node).property('testNodeProperty')}
	attributes {
		class = ${testVari}
	}
}

By using @context you are really adding a variable that can be used anywere in eel. This is the same mechanism that gives you access to node, documentNode and site . Be aware that this should be used with care since fusion is meant to be as side effect free as possible.

It is good practice to make a prototype rely only on node, documentNode and site in the context but inside your prototype you can do whatever you like with it.


(Martin Huber) #3

Hey @martoro,
thank you very much.

To be honest, I used @context in some nodeTypes a lot.
[thought it is my own simple&dirty solution because of @christianm 's warning ( Typoscript2-Prototype with more then one ancestor? )
But I couldn’t find a solution with «simple property to prevent a huge amount of data into the context» -> thats the reason, why I left @context outside of this Topic.

With this Post I was looking for a solution to script without @context.
But I am glad about your advice!

I like to work with, because of more clarity, good readability, easy reusability and sometimes the heredity from a SuperPrototype to my Child-Prototype … (One more time, not the most proper solution – I guess).

Unfortunately: @context: is a big Question-mark

Maybe someone knows a good documentation or snippets about this topics: Basics of @context-concept, daily usage and deeper knowledge?

  • What is to do with, should do, or never should do with …
  • Could I have to clean the amount of data in @context with something like unset() or similar at the end of . Because of «long lifetime», «cache problem» or something else unknown?

(Martin Ficzel) #4

Basically all fusion-pathes that are rendered isolated should only rely on the default context (site,documentNode,node).

Maybe an example helps:

You know that neos will rerender content-nodes after some specific inspector properties are changed. In that moment not the whole site is rendered but only the fusion for this single content-node. In that moment only the default context (site,documentNode,node) is available.

If you are running into trouble and have to enforce the rerendering of the whole page on property-change then you are probably doing it wrong and should try to optimize your fusion code.


(Christian Müller) #5

The expression ${q(node).property('testNodeProperty')} works fine INSIDE of attributes as well, so that could be the way to go:

prototype(Vendor.Site:TestNode) < prototype(TYPO3.Neos:Content) {
    attributes {
        // Next line is important to not output testVari as attribute
        @ignoreProperties = ['testVari']
        testVari = ${q(node).property('testNodeProperty')}
        class = ${this.testVari}
     }
}

Now testVari is clearly scoped to attributes. If you need testVari as well in the prototype you can either repeat the expression or indeed use context. I this case it seems fine to do, I warn only about using it high up in the rendering structure as it will bubble down all the way. But if this prototype represents a content element usually that’s the end point anyway.


(Martin Huber) #6

Wouw,
thanks both.

@martoro: Example helps a lot – all the time!

@christianm: New Possibilities with @ignoreProperties =[‘testVari’]. Will try with.
And right know, In my case prototypes represents most of the time a ContentElement. So good to know, if this is «the end point», @context is an acceptable opportunity.


(Christian Müller) #7

It’s there for a reason, which is to solve this use case. My warning is a general one to help people not to “pollute” some up level context with a lot of variables that are then made available pretty much everywhere.


(George Dimitriadis) #8

Did the syntax @ignoreProperties = ['myProperty'] get deprecated ? I could only get this to work with nesting it in an Eel expression instead:

@ignoreProperties = ${['myProperty']}