Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Questions on best practices // add FAQ for common cases (maybe on Docs.Neos.io) #21

Open
skurfuerst opened this issue Feb 8, 2019 · 1 comment

Comments

@skurfuerst
Copy link
Member

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, using this.... 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

@mhsdesign
Copy link
Member

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants