Für TYPO3: Bootstrap-Akkordeon ohne Extension

Bootstrap Akkordeon

Wir verwenden gerne TYPO3. Dabei möchten wir möglichst wenige Extensions einbinden (Ausführliches dazu hier). Wer auf seiner Website das Bootstrap-Framework eingebunden hat, kann dessen Collapse-Funktion nutzen und mit TypoScript ein Accordion für die Anzeige von aufklappbaren Inhalten bauen. Für die Inhaltselemente Text und Text mit Bild findet Ihr unten den Code.

Im Inhaltselement soll unter Erscheinungsbild -> Einrückung und Rahmen eine zusätzliche Option Akkordeon erscheinen. Dazu wird Code 1 in die Page TsConfig der Seite eingetragen, auf der die Option zur Verfügung stehen soll, sonst natürlich in der Root-Seite Eurer Website.

Jetzt ist die zusätzliche Option im Backend anwählbar. Für den Dropdown-Effekt im Frontend wird das TypoScript angepasst (Code 2).

Bitte beachtet, dass jQuery und das Bootstrap-JavaScript eingebunden sein müssen.

Foto: © Otto Durst - Fotolia.com

Code: 
# Code 1
TCEFORM.tt_content.section_frame {
  addItems.100 = Akkordeon
}
# Code 2
# Wenn die Option "Akkordeon" angewählt ist, erhält die Überschrift 
# als Wrap das Bootstrap-Markup. Im Attribut data-target ist die 
# ID des Elements festgelegt, das durch Anklicken des Headers 
# auf- und zugeklappt wird. Durch die Eigenschaft dataWrap bleiben 
# die IDs eindeutig, da sich die Zahl bei jedem neuen Element um 1 erhöht.
 
lib.stdheader.stdWrap.outerWrap.cObject = CASE
lib.stdheader.stdWrap.outerWrap.cObject {
    key.field = section_frame
    100 = TEXT
    100.value = |
    100.stdWrap.dataWrap = <div data-toggle="collapse" data-target="#acc-{cObj:parentRecordNumber}">|</div>
  }
 
# Wenn die Option "Akkordeon" angewählt ist, erhält der Container 
# für das Element "Text mit Bild" als Wrap das Bootstrap-Markup. 
# Auch hier wird durch dataWrap die #Eindeutigkeit der IDs sichergestellt. 
 
tt_content.textpic.20.stdWrap.outerWrap.cObject = CASE
tt_content.textpic.20.stdWrap.outerWrap.cObject {
    key.field = section_frame
    100 = TEXT
    100.value = |
    100.stdWrap.dataWrap = <div id="acc-{cObj:parentRecordNumber}" class="collapse out"> | </div>
  }
 
#Derselbe Effekt wie davor, diesmal für das Element "Text". 
 
tt_content.text.20.stdWrap.outerWrap.cObject = CASE
tt_content.text.20.stdWrap.outerWrap.cObject {
    key.field = section_frame
    100 = TEXT
    100.value = |
    100.stdWrap.dataWrap = <div id="acc-{cObj:parentRecordNumber}" class="collapse out"> | </div>
  }
 
# Ohne diese Zeilen würde durch den vorherigen Code der Textteil 
# des Elementes "Text mit Bild" erneut den Wrap erhalten und 
# dauerhaft verschwinden.
tt_content.textpic.20.text.20 < tt_content.text.20
tt_content.textpic.20.text.20.stdWrap.outerWrap.cObject.100.stdWrap.dataWrap >
Bild des Benutzers alexander

Alexander Künzl

Alexander Künzl ist seit 2012 im Unternehmen und kümmert sich um Projektmanagement, Suchmaschinenoptmierung und Webmarketing. Das Content Management System seiner Wahl ist TYPO3.

Kommentare

Hallo,

Ich habe versucht, die Anleitung in Typo3 v.6.2 umzusetzen,
aber es taucht keine zusätzliche Option "Akkordeon" auf unter "Erscheinungsbild".
Was habe ich falsch gemacht ?

page = PAGE
page.includeCSS {
bootstrap = fileadmin/BOOTSTRAP/css/bootstrap.min.css
}
page.includeJSFooter {
jquery = fileadmin/JQUERY/jquery.min.js
bootstrap = fileadmin/BOOTSTRAP/js/bootstrap.min.js
}

# Code 1
TCEFORM.tt_content.section_frame {
addItems.100 = Akkordeon
}

# Code 2
# Wenn die Option "Akkordeon" angewählt ist, erhält die Überschrift
# als Wrap das Bootstrap-Markup. Im Attribut data-target ist die
# ID des Elements festgelegt, das durch Anklicken des Headers
# auf- und zugeklappt wird. Durch die Eigenschaft dataWrap bleiben
# die IDs eindeutig, da sich die Zahl bei jedem neuen Element um 1 erhöht.

lib.stdheader.stdWrap.outerWrap.cObject = CASE
lib.stdheader.stdWrap.outerWrap.cObject {
key.field = section_frame
100 = TEXT
100.value = |
100.stdWrap.dataWrap = <div data-toggle="collapse" data-target="#acc-{cObj:parentRecordNumber}">|</div>
}

# Wenn die Option "Akkordeon" angewählt ist, erhält der Container
# für das Element "Text mit Bild" als Wrap das Bootstrap-Markup.
# Auch hier wird durch dataWrap die #Eindeutigkeit der IDs sichergestellt.

tt_content.textpic.20.stdWrap.outerWrap.cObject = CASE
tt_content.textpic.20.stdWrap.outerWrap.cObject {
key.field = section_frame
100 = TEXT
100.value = |
100.stdWrap.dataWrap = <div id="acc-{cObj:parentRecordNumber}" class="collapse out"> | </div>
}

#Derselbe Effekt wie davor, diesmal für das Element "Text".

tt_content.text.20.stdWrap.outerWrap.cObject = CASE
tt_content.text.20.stdWrap.outerWrap.cObject {
key.field = section_frame
100 = TEXT
100.value = |
100.stdWrap.dataWrap = <div id="acc-{cObj:parentRecordNumber}" class="collapse out"> | </div>
}

# Ohne diese Zeilen würde durch den vorherigen Code der Textteil
# des Elementes "Text mit Bild" erneut den Wrap erhalten und
# dauerhaft verschwinden.
tt_content.textpic.20.text.20 < tt_content.text.20
tt_content.textpic.20.text.20.stdWrap.outerWrap.cObject.100.stdWrap.dataWrap >

page = PAGE
page.10 = TEXT
page.10 < styles.content.get

Bild des Benutzers alexander

Hallo,

dieser Code hier;

TCEFORM.tt_content.section_frame {
addItems.100 = Akkordeon
}

muss in der Root-Seite unter Seite bearbeiten im Reiter Ressourcen in das Feld TypoScript-Konfiguration eingetragen werden. Dann sollte die Auswahlmöglichkeit erscheinen.

...und wenn man die Reihenfolge einhält, dann kann man sich auch die letzten beiden Zeilen sparen. - Da beißt sich die Katze sonst in den Schwanz. Also "tt_content.text" vor "tt_content.textpic".

Sorry ich hab scheiße erzählt. Die müssen doch drin bleiben :P - Grrr Dein Captcha kann man schlecht lesen

Alex, danke für das Tut, aber leider fehlt noch der CSS Wrap panel-group durch den eine Bootstrap Accordion Gruppe definiert wird. Erst dadurch klappt ein zuvor geöffnetes Inhaltselement wieder zu, wenn ein anderes der gleichen Gruppe geöffnet wird. Leider bleiben so alle Inhaltselemente offen, nachdem sie angeklickt wurden. Hast du dafür einen Workaround?

Vielen Dank für die Denkanstöße! Ich denke, es ist am einfachsten, sich an das Bootstrap Markup zu halten. Unter http://www.w3schools.com/bootstrap/bootstrap_ref_js_collapse.asp findet man hier ein funktionierendes Beispiel, in dem ein Inhalt zugeklappt wird, wenn ein anderer aufgeklappt wird. Tatsächlich ist ein umschließender Container <div id="accordion" class="panel-group"> erforderlich. Damit das funktioniert, habe ich zwei weitere Rahmen definiert: Akkordeon-Start und Akkordeon-End. Das heißt ins Page TsConfig, ob auf der Rootseite oder in einer ausgelagerten Datei, muss also

#Code 1
TCEFORM.tt_content.section_frame {
addItems.100 = Akkordeon
addItems.101 = Akkordeon-Start
addItems.102 = Akkordeon-End
}

Im folgenden habe ich das TypoScript angepasst, sodass der erste Datensatz, der mit Akkordeon-Start angesprochen wird, das beginnende <div id=accordion" class="panel-group"> erhält, aber einen schließenden </div> zuwenig. Der letzte Datensatz muss den Rahmen Akkordeon-End erhalten, denn hier wird das am Anfang fehlende, schließende </div> mitgeliefert:

#Code 2
lib.stdheader.stdWrap.outerWrap.cObject = CASE
lib.stdheader.stdWrap.outerWrap.cObject {
key.field = section_frame
100 = TEXT
100.value = |
100.stdWrap >
100.stdWrap.dataWrap = <div class="panel panel-default"><div class="panel-heading"><span class="panel-title"><a data-toggle="collapse" data-parent="#accordion" href="#content{cObj:parentRecordNumber}"> | </a></span></div>
101 = TEXT
101.value = |
101.stdWrap >
101.stdWrap.dataWrap = <div class="panel-group" id="accordion"><div class="panel panel-default"><div class="panel-heading"><span class="panel-title"><a data-toggle="collapse" data-parent="#accordion" href="#content{cObj:parentRecordNumber}"> | </a></span></div>
102 = TEXT
102.value = |
102.stdWrap >
102.stdWrap.dataWrap = <div class="panel panel-default"><div class="panel-heading"><span class="panel-title"><a data-toggle="collapse" data-parent="#accordion" href="#content{cObj:parentRecordNumber}"> | </a></span></div>
}

# Wenn die Option "Akkordeon" angewählt ist, erhält der Container
# für das Element "Text mit Bild" als Wrap das Bootstrap-Markup.
# Auch hier wird durch dataWrap die #Eindeutigkeit der IDs sichergestellt.

tt_content.textpic.20.stdWrap.outerWrap.cObject = CASE
tt_content.textpic.20.stdWrap.outerWrap.cObject {
key.field = section_frame
100 = TEXT
100.value = |
100.stdWrap.dataWrap = <div id="content{cObj:parentRecordNumber}" class="panel-collapse collapse"><div class="panel-body"> | </div></div></div>
101 = TEXT
101.value = |
101.stdWrap.dataWrap = <div id="content{cObj:parentRecordNumber}" class="panel-collapse collapse"><div class="panel-body"> | </div></div></div>
102 = TEXT
102.value = |
102.stdWrap.dataWrap = <div id="content{cObj:parentRecordNumber}" class="panel-collapse collapse"><div class="panel-body"> | </div></div></div></div>
}

#Derselbe Effekt wie davor, diesmal für das Element "Text".

tt_content.text.20.stdWrap.outerWrap.cObject = CASE
tt_content.text.20.stdWrap.outerWrap.cObject {
key.field = section_frame
100 = TEXT
100.value = |
100.stdWrap.dataWrap = <div id="content{cObj:parentRecordNumber}" class="panel-collapse collapse"><div class="panel-body"> | </div></div></div>
101 = TEXT
101.value = |
101.stdWrap.dataWrap = <div id="content{cObj:parentRecordNumber}" class="panel-collapse collapse"><div class="panel-body"> | </div></div></div>
102 = TEXT
102.value = |
102.stdWrap.dataWrap = <div id="content{cObj:parentRecordNumber}" class="panel-collapse collapse"><div class="panel-body"> | </div></div></div></div>
}

# Ohne diese Zeilen würde durch den vorherigen Code der Textteil
# des Elementes "Text mit Bild" erneut den Wrap erhalten und
# dauerhaft verschwinden.
tt_content.textpic.20.text.20 < tt_content.text.20
tt_content.textpic.20.text.20.stdWrap.outerWrap.cObject.100.stdWrap.dataWrap >
tt_content.textpic.20.text.20.stdWrap.outerWrap.cObject.101.stdWrap.dataWrap >
tt_content.textpic.20.text.20.stdWrap.outerWrap.cObject.102.stdWrap.dataWrap >

Das funktioniert so leider noch nicht, weil die von Typo3 automatisch mitgelieferten csc-Default-Klassen die Accordion-Funktionalität beeinträchtigen. Daher habe ich noch ein TypoScript-Schnipsel in ein Erweiterungstemplate für meine Seite, auf der sich dieses Accordion befindet, eingefügt. Allerdings gibt es bestimmt elegantere Lösungen:

#Code 3
tt_content.stdWrap >

Die entsprechende Layout-Anpassung ist nur noch reine CSS-Fleissarbeit. Bei mir funktioniert alles wunderbar mit Typo3 7.6.6 und Bootstrap 3.

Hallo Alexander, vielen Dank für Dein Input. Leider kalappt bei mir der collapse nur einmal. Ich klicke drauf, es öffnet sich der toggle, ich klicke nochmal, der toggle schließt sich. Dann ist Ende und es bleibt geschlossen. Deine letzten beiden Zeilen habe ich im Typoscript
Folgender Code ist da nach einmal auf- und zuklappen zu sehen (da ist von JavaScript einmal ein Class="collapsed" ergänzt, das verschwindet, wenn man nochmal draufklickt):
<div id="c951" class="csc-default"><div data-toggle="collapse" data-target="#acc-1" aria-controls="#acc-1" class="collapsed"><div class="csc-header csc-header-n1"><h1>test Accordion Typoscript</h1></div></div><div id="acc-1" class="collapse" aria-expanded="false" "="" style="height: 0px; display: none;"><p class="bodytext">test</p></div></div>

Hier ist es zu sehen:
http://asienhaus.der-koenig.net/test/
Typo3 6.2.17

Hast Du eine Idee woran das liegen kann?

VG
Jürgen

Neuen Kommentar schreiben