Adding attributes to the neos-contentcollection div

Hey,
I am new to Neos and i try to build a website with accordion elements.

I managed to create a Collection and Items but the accordion is not working, because of the wrapping contentcollection div.

Is there a way to change the wrapping element?

This is what i get:

<ul class="accordion" data-accordion="" data-allow-all-closed="true" data-multi-expand="true" role="tablist"
  data-e="3n65z8-e">
  <div class="neos-contentcollection">
    <li class="accordion-item" data-accordion-item="">
      <a class="accordion-title" href="#">Titel</a>
      <div class="accordion-content" data-tab-content="">Inhalt</div>
    </li>
    <li class="accordion-item" data-accordion-item="">
      <a class="accordion-title" href="#">Titel 2</a>
      <div class="accordion-content" data-tab-content="">Inhalt 2</div>
    </li>
  </div>
</ul>

and this is what i need:

<ul class="accordion" data-accordion="" data-allow-all-closed="true" data-multi-expand="true" role="tablist"
  data-e="3n65z8-e">
  <li class="accordion-item" data-accordion-item="">
    <a class="accordion-title" href="#">Titel</a>
    <div class="accordion-content" data-tab-content="">Inhalt</div>
  </li>
  <li class="accordion-item" data-accordion-item="">
    <a class="accordion-title" href="#">Titel 2</a>
    <div class="accordion-content" data-tab-content="">Inhalt 2</div>
  </li>
</ul>

I found a way to get the right attributes and the class by doing it like this:

prototype(WG.Site:Content.Accordion) < prototype(Neos.Neos:ContentComponent) {
  content = Neos.Neos:ContentCollection {
attributes.class.@process.collectionClass >
attributes = ' class="accordion" data-accordion data-multi-expand="true" data-allow-all-closed="true"'
  }

 renderer = afx`
{props.content}
 `
}

but I am sure this is not a perfect way.

I have also a div wrapping list elements now.

Hi @BoxerBuffa ,

as far as I know using the “@process” approach is a fully valid approach.

I have following code for a similar use case, a “Carousel” element with Bootstrap 5:

prototype(My.Site:Content.Carousel) < prototype(Neos.Neos:ContentComponent) {
identifier = ${'carousel-id-' + q(node).property('_identifier')}

carouselItems = Neos.Neos:ContentCollection {
    nodePath = 'carouselItems'
    attributes.class = 'carousel-inner'

    prototype(Neos.Neos:ContentCase) {
        @process.addItemClass = Neos.Fusion:Augmenter {
            class = 'd-block w-100'
        }
    }

    content.itemRenderer.@process.wrapWithContainer = ${'<div class="carousel-item' + (iterator.isFirst ? ' active' : '') + '">' + value + '</div>'}
}

renderer = afx`
    <div class="carousel slide" id={props.identifier} data-bs-interval="false">
        {props.carouselItems}
        <button class="carousel-control-prev" type="button" data-bs-target={'#' + props.identifier} data-bs-slide="prev">
            <span class="carousel-control-prev-icon" aria-hidden="true"></span>
            <span class="visually-hidden">Previous</span>
        </button>
        <button class="carousel-control-next" type="button" data-bs-target={'#' + props.identifier} data-bs-slide="next">
            <span class="carousel-control-next-icon" aria-hidden="true"></span>
            <span class="visually-hidden">Next</span>
        </button>
    </div>
`
}

With the

content.itemRenderer.@process.wrapWithContainer

I can also control the wrapper of the child elements.

With the

@process.addItemClass = Neos.Fusion:Augmenter...

I can also add additional CSS classes to the child element itself.

Maybe this helps to further implement your use case.

1 Like

you could also change the tagName:

prototype(WG.Site:Content.Accordion) < prototype(Neos.Neos:ContentComponent) {
    content = Neos.Neos:ContentCollection {
        tagName = "ul"
        [...]
    }
}

btw i dont know if it is wise to remove the “neos-contentcollection” class … is it used for editing? i guess:

neos-development-collection/ContentCollection.fusion at master · neos/neos-development-collection (github.com)

  # The following is used to automatically append class and data attribute needed for editing.
  # You can disable the following line with:
  # prototype(Neos.Neos:ContentCollection) {
  #   attributes.class.@process.collectionClass >
  # }
  # in your site's Fusion if you don't need that behavior.

voila :wink:

prototype(WG.Site:Content.Accordion) < prototype(Neos.Neos:ContentComponent) {
  content = Neos.Neos:ContentCollection {
    tagName = "ul"

    attributes {
      class = "accordion"
      data-accordion = true
      data-multi-expand = "true"
      data-allow-all-closed = "true"
    }
  }

  renderer = afx`
    {props.content}
  `
}

note that due to some logic in neos-development-collection/ContentCollection.fusion at master · neos/neos-development-collection (github.com) the "neos-contentcollection” class will still be appended to your ul tag.

1 Like

Thank you Guys for the quick answer! Good to hear that I was not totally wrong :slight_smile:

I like Neos so fare, its fun to work with, but sometimes a little hard to find the “best” solution.

btw you could minify this a bit:

prototype(WG.Site:Content.Accordion) < prototype(Neos.Neos:ContentCollection) {
  tagName = "ul"

  attributes {
    class = "accordion"
    data-accordion = true
    data-multi-expand = "true"
    data-allow-all-closed = "true"
  }
}

just as a quick reminder: you dont need to set the nodePath for the Neos.Neos:ContentCollection as your used to with documents with nodePath = 'main' when your current node is a content collection:

Neos does this:

Check if the given node is already a collection, find collection by nodePath otherwise, throw exception if no content collection could be found

1 Like

An other solution could be to use the augmenter as a wrapper for the collection and keep the contentComponent clean from html atributes and markup as described here: Augmenter does not work like expected in backend rendering - #3 by leanferret

1 Like