fusion-afx
fusion-afx copied to clipboard
Questions on best practices // add FAQ for common cases (maybe on Docs.Neos.io)
Hey everybody,
I've been trying AFX recently to build a Backend module, and I have stumbled over a few cases which are unclear to me. I'm writing my questions in a kind of FAQ style, so that we can publish this afterwards, and have more and more AFX best practices documented.
How to render a block conditionally?
In Fluid, one can use the <f:if condition="...">...</if>
ViewHelper to render a block conditionally.
In my AFX code, I have done the following:
<Neos.Fusion:Value @if.hasChildren={...} @children="value">
...
</Neos.Fusion:Value>
Is this a best practice or would you do it differently? Can I attach the @if to an arbitrary DOM node as it is Fusion in the end?
How do you build If/Else cases in AFX?
I'd love if the syntax {myCondition ? <FirstAfxComponent /> : <SecondAfxComponent />}
worked, just like React. However, in my understanding, this won't work because everything in {...}
is directly interpreted as Eel.
So what I did instead was using Neos.Fusion:Case
:
prototype(Sandstorm.NeosAcl:Presentation.NodeList.NodeRow.Acl) < prototype(Neos.Fusion:Case) {
@context.acl = ${this.acl}
moreThanThreeAcls {
condition = ${Array.length(acl) > 3}
element = Neos.Fusion:Component {
acl = ${acl}
renderer = afx`
...
`
}
}
default {
condition = true
element = Neos.Fusion:Component {
acl = ${acl}
renderer = afx`
...
`
}
}
}
I dislike the above approach because of the following:
- it's very verbose.
- we need to pass the
acl
prop from props to Context, then back from context to Props in the inner Components.
How would you write this idiomatically?
How do you handle "computed state" in a Component?
Example:
prototype(Sandstorm.NeosAcl:Presentation.NodeList.NodeRow) < prototype(Neos.Fusion:Component) {
# public API
node = null
# Internal "API"
@context.node = ${this.node}
showLinkUri = Neos.Fusion:UriBuilder {
action = "show"
arguments.node = ${node.nodePath}
}
renderer = afx`...`
in the above example, the node
is a public prop; and I want to generate a certain link with this Node as input. The control flow above is IMHO non-obvious:
- we need to put the
node
into context, usingthis....
notation - we need to define a new internal prop, where we use the context value.
I know I could write <...NodeRow showLinkUri.arguments.node={node}>
on calling the component, but I feel this exposes too much of the internal behavior of NodeRow
to the outside world...
How would you write this idiomatically? Is there any convention on how to name/build "computed properties"?
Forms
I've tried creating helpers for generating forms, similar to <f:form>
. I think this has not been done before, has it? I think it would be super useful as well...
I see one conceptual problem there: For forms to work, we need a "data channel" from the form element to its form fields and back again, to be able to remember the form fields, the bound value, etc etc. Pretty similar to how react's context
works.
However, an Neos.Fusion:Component
only passes through props
and clears all other variables from the Fusion stack (which is generally great of course) -- should we extend it to e.g. keep "private" context variables starting with __
?
Menus
How do I build menus in AFX? (Asking because the Menu
prototype inherits from Neos.Fusion:Template
).
All the best and thanks :)
Sebastian
i read this once and was wondering why there are no answers here ;) found em accidentally here in slack: https://neos-project.slack.com/archives/C5WMNAHCG/p1549614519062500
(all beneath this post)