Augmenter does not work like expected in backend rendering

Hi,

im using Neos.Fusion:Augmenter to add my wrapper class directly to the ContentCollection div.

Here an simplified example:

prototype(Vendor.Site:Content.Button.List) < prototype(Neos.Neos:ContentComponent) {

    // ...

    content = Neos.Neos:ContentCollection {
        tagName = 'div'
        nodePath = 'buttons'
    }

    renderer = Vendor.Site:Component.Molecule.ButtonList {
        @apply.props = ${props}
    }
}


prototype(Vendor.Site:Component.Molecule.ButtonList) < prototype(Neos.Fusion:Component) {

    // ...

    renderer = afx`
        <Neos.Fusion:Augmenter class="ButtonList">
            {props.content}
        </Neos.Fusion:Augmenter>
    `
}

The frontend renders like expected:

<div class="ButtonList neos-contentcollection">
    <div>childNode</div>
    <div>childNode</div>
    <div>childNode</div>
</div>

But in the Backend i get something like that:

<div class="ButtonList">
    <div class="neos-contentcollection">
        <div>childNode</div>
        <div>childNode</div>
        <div>childNode</div>
    </div>
</div>

Is something missig? Or doesn’t work the augmenter not with contentCollections in general? :slight_smile:

Hi,

the ContentCollection has a ContentElementWrapping that adds some meta tags around it in the backend that will later be removed via JS.
But for the Augmenter it looks like multiple tags and then it has to add a surrounding div.

Those two objects don’t like each other so much sadly.

You can either fix this by directly using the ContentCollectionRendererer and take care of the caching config etc. yourself.

Or you define the node itself as the content collection without the node in-between and therefore have already the ContentElementWrapping from the ContentComponent and you can turn off the one from the collection.

1 Like

Hi Sebastian,

Thank you, this was very helpful.
I remembered this blog post (https://mind-the-seb.de/blog/preventing-deep-content-nesting-in-neos-cms ) and experimented a bit. I don’t like to set the caching by my own. But i like the clean content tree.

Im using atomic fusion and the next step should be adding css modules.
So i need a solution with a reusable component for manipulating the content collection without loosing the default contentElementWrapping.

Now my solution is a helper component with the Augmenter. It is theoretically reusable in my other components with similar collections. I think a separate component with the augmenter to add own attributes is useful for separation of concerns.

Im Using The Columns Node as ContentCollection and the fusion is the normal atomic fusion stuff. To putt the wrapper component with the augmenter between the content-collection and contentElementWrapping, i use @process and @position. And now it’s working like expected. :slight_smile: It’s a clean html markup in frontend and backend. :slight_smile:

"LeanWorks.Site:Content.Columns":
  superTypes:
    "Neos.Neos:Content": true
    "Neos.Neos:ContentCollection": true
  ui:
    icon: grip-lines
    label: "Columns"
  constraints:
    nodeTypes:
      "*": false
      "LeanWorks.Site:Content.Column": true
  properties: 
      # ...




prototype(LeanWorks.Site:Content.Columns) < prototype(Neos.Neos:ContentComponent) {

    content = Neos.Neos:ContentCollection {
        tagName = 'div'
    }

    # putt own wrapping between contetCollection and contentElementWrapping
    content.@process.wrapContent = LeanWorks.Site:Component.Molecule.Columns.Collection {
        orientation = ${q(node).property('orientation')}
        gapSize = ${q(node).property('gapSize')}
        content = ${value}
    }

    # do contentElementWrapping after my own wrapping
    content.@process.contentElementWrapping.@position = 99

    renderer = ${props.content}
}




prototype(LeanWorks.Site:Component.Molecule.Columns.Collection) < prototype(Neos.Fusion:Component) {

    orientation = 'horizontal'
    gapSize = 16

    renderer = afx`
        <Neos.Fusion:Augmenter
            class={
                'Columns' +
                (props.orientation ? ' Columns--'+props.orientation : null) +
                (props.gapSize ? ' Columns--gapSize-'+props.gapSize : null)
            }
            >
            {props.content}
        </Neos.Fusion:Augmenter>
    `
}

But i’m not shure where the Collection component should live. It’s an Atom, Molecule or like another namespace? :thinking:

I think about these namespaces:

  • Component.Moledule.Columns.Collection,
  • Component.Molecule.Collection.Columns,
  • Component.Collection.Column

My HTML now looks like that and it’s working in backend too without loosing the default wrapping. :slight_smile:

<div class="Columns Columns--horizontal neos-contentcollection">
    <div class="Column neos-contentcollection">...</div>
    <div class="Column neos-contentcollection">...</div>
    <div class="Column neos-contentcollection">...</div>
    <div class="Column neos-contentcollection">...</div>
</div>

Cool, happy to hear it works now :slight_smile:

Regarding the naming… that’s why I personally neither do or recommend the naming part of atomic design. IMO it wastes brain power.
I have f.e. a components folder and there for each usable component a subfolder with separated integration and presentation parts.