Skip to content

Building content accordions in TYPO3 CMS

How to build content accordions with gridelements and without complicated code

Whenever it was necessary output content elements in a certain hierarchy I felt that the builtin options of TYPO3 are not intuitive to use. But with the help of the gridelements extension it's really easy to implement a simple hierarchy that is easy to maintain for the editor and does not require complicated TypoScript constructs.

The idea is to define a gridelements container that is a single row/column and just acts as a grouping container. Every content element in this container is rendered within the accordion.

The configuration of this container is very simple:


backend_layout {
colCount = 1
  rowCount = 1
  rows {
    1 {
      columns {
        1 {
          name = Content
          colPos = 0
          allowed = header,textmedia

A Fluid template is set for the container without any additional options (the number 1 is the ID of the CE Backend layout)


tt_content.gridelements_pi1.20.10.setup {
  1 < lib.gridelements.defaultGridSetup
  1 {
    cObject.file = EXT:yourextensionkey/Resources/Private/Extensions/gridelements/accordion.html

The last remaining part is the Fluid template. The example template below generates the markup for a bootstrap accordion. A for loop iterates over all child content elements of the container and uses a VHS view helper (link to the documentation) to render the content element wrapped in the necessary divs.


<div id="c{data.uid}" class="row gridelement"
  <div class="col-xs-12">
     <div class="panel-group content-panel" id="accordion{data.uid}" role="tablist" aria-multiselectable="true">
       <f:for each="{data.tx_gridelements_view_children}" as="content">
         <div class="panel panel-default">
           <div class="panel-heading" role="tab" id="heading{content.uid}">
           <h3 class="panel-title">
             <a role="button" data-toggle="collapse" data-parent="#accordion{data.uid}" href="#collapse{content.uid}" aria-controls="collapse{content.uid}">
<i class="glyphicon glyphicon-menu-down pull-right"></i>
           <div id="collapse{content.uid}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading{content.uid}">
            <div class="panel-body">
             {vhs:content.render(contentUids: {0: content.uid})

I think this is a very simple and clean implementation that can be easily extended to all other scenarios where it's necessary to wrap content elements in a hierarchy. Another use case for this setup would be an image carousel or a tab representation of the content.