Neos.Fusion:Case in afx or should we have a Neos.Fusion:If?

As discussed in Feature request: @else and @elseif for Fusion - #9 by till.kleisli the @if attributes might not be the best way to implement conditional Output.

Now I tried to implement conditional output in afx

<div @if.matches={condition1}>
    One
</div>

<div @if.matches={condition2}>
    Two
</div>

this works fine, but the @if statements are quite hidden when you add more attributes like class or id. so I tried

<Neos.Fusion:Case>
    <Neos.Fusion:Matcher condition={condition1}>
        <div>One</div>
    </Neos.Fusion:Matcher>
    <Neos.Fusion:Matcher condition={condition2}>
        <div>Two</div>
    </Neos.Fusion:Matcher>
</Neos.Fusion:Case>

but when contition1 matches and condition2 not, the output is

<div>One</div>_____________NO_MATCH_RESULT_____________

For this example, with no default value, it even might be cool to have an IF object like the <f:if> Viewhelper in fluid. on the other hand, there might be a reason, why it was not implemented yet. :slight_smile:

<Neos.Fusion:If condition={condition1}>
    <div>One</div>
</Neos.Fusion:If>

Reason is that Matcher expects the fusion attribute renderer but afx places children in content.

You can do this:
!!! Does not work, see below !!!

<Neos.Fusion:Case>
    <Neos.Fusion:Matcher condition={condition1} @children="renderer">
        <div>One</div>
    </Neos.Fusion:Matcher>
    <Neos.Fusion:Matcher condition={condition2} @children="renderer">
        <div>Two</div>
    </Neos.Fusion:Matcher>
</Neos.Fusion:Case>

Also it might make sense to add a fallback to content if renderer cannot be rendered like for Map and Loop.

Tested further and this approach does not work:

<Neos.Fusion:Case>
    <Neos.Fusion:Matcher condition={condition1}>
        <div>One</div>
    </Neos.Fusion:Matcher>
    <Neos.Fusion:Matcher condition={condition2}>
        <div>Two</div>
    </Neos.Fusion:Matcher>
</Neos.Fusion:Case>

because it would transpile as:

item_1 = Neos.Fusion:Case {
   content = Neos.Fusion:Join {
       item_1 = Neos.Fusion:Matcher {
           condition = ${condition1}
           content = Neos.Fusion:Tag {
               ...
           }
        }
       item_2 = Neos.Fusion:Matcher {
           condition = ${condition2}
           content = Neos.Fusion:Tag {
               ...
           }
        }
   }

Problem is that the path content is added on two levels. The second one inside the matcher can be circumvented via @children=renderer but there is no such sytax that adds afx children as properties to the parent object directly which would be required for the Neos.Fusion:Case so unless we come up with a smart solution for that afx will not work with Case (yet)

1 Like

Because fusion ignores whitespaces between attributes, i usally write @ifs like that:

<div
    @if.matches={condition}
    class="my-class"
    id="id"
    data-sth="abc"
    to-be-continued
>
    Content
</div>

So the @if in the beginning is seen from the first view.

1 Like

@martoro Thank you for diving into it. I’ll try to think about a smart solution… :slight_smile:
Is there an easy way to display the fusion code that is generated by afx? Or did you just do it by hand?

@benjamink yes, it’s definitely easier to read, when the @if is in a seperate line. But I still think there should be a dedicated fusion object for it.