"Dafür gibt's aber 'ne Extension"
Warum weniger Extensions besser sind: Beispiel für ein Bootstrap-Karussell in TYPO3
Wer ein Content-Management-System für seine Website aussucht , sollte sich auch die Kernfunktionen ansehen. Ein System, das möglichst viele gewünschte Features schon "an Bord" hat, macht die Pflege deutlich einfacher. Extensions, Module, Plugins, je nach Terminologie des CMS, bringen nicht nur Vorteile. Wir zeigen am Beispiel TYPO3 6.1/6.2 mit einem einfachen Bilderslider aus dem Framework Bootstrap, wie man sich eine Extension sparen kann.
Extensions erweitern Funktionen und die Arbeit
Warum sollte man überhaupt möglichst wenige Extensions verwenden? Weil sie in mehrerer Hinsicht einen Unsicherheitsfaktor darstellen können:
- Extensions müssen ständig weiterentwickelt werden, weil sich immer wieder die Rahmenbedingungen ändern, neue Funktionen implementiert oder Sicherheitslücken geschlossen werden müssen. Wenn der Entwickler keine Zeit oder Lust mehr hat, die Erweiterung auf dem neuesten Stand zu halten, können Sicherheitslücken entstehen, die der Benutzer erst merkt, wenn ein Schaden entstanden ist. Neben dem damit verbundenen Ärger muss er sich einen Ersatz für die Extension suchen und die Website zuweilen mit großem Aufwand anpassen.
- Die Wartung der Website wird einfacher und nimmt weniger Zeit in Anspruch, wenn keine Updates für Extensions eingespielt werden müssen. Außerdem besteht bei weniger Erweiterungen seltener die Gefahr, dass eine Extension mit der neuen Version des Kernsystems nicht mehr kompatibel ist. Hier sind nicht die Major Releases wie das neue TYPO3 6.2, Joomla! 3 oder Drupal 8 gemeint, sondern die kleinen regelmäßigen Modifikationen, die in jedem Open-Source-System vorkommen.
- Jede Extension muss vom System "verkraftet" werden: Sie bringt oft mehr Daten mit, als für die gewünschte Funktion eigentlich benötigt würden und wird an verschiedenen Stellen im System registriert. All dies kostet Sprecherplatz und Performance.
- Eine neue Extension sorgt möglicherweise dafür, dass bereits vorhandene Erweiterungen nicht mehr richtig funktionieren.
Ein Basis-Bilderkarussell mit Bootstrap und dem FILES-Objekt von TYPO3
Das CSS-Framework bietet einen großen Werkzeugkasten für moderne Websites. Es basiert auf einem zwölfspaltigen responsiven Gridsystem und enthält zusätzlich Extras wie kleine Icons, ein Dropdown-Menü, eine Breadcrumb-Navigation und einen Bilderkarussell. Dazu müssen den entsprechenden HTML-Elementen einfach die im Bootstrap-CSS definierten Klassen zugewiesen werden. Zusammen mit der FILES-Objekt entsteht ein Slider mit vielen Funktionen:
- Neben der Datei bootstrap.css müssen bootstrap.js und jQuery eingebunden werden. JQuery ist oft schon durch TYPO3 oder eine andere Extension vorhanden. Die Javascript-Dateien sollten in den Footer gesetzt werden.
- In TYPO3 wird ein Datensatz des Content-Objekt des Typs "Images" angelegt und entweder per Upload oder aus dem Fileadmin mit Bildern befüllt. Jedes Bild hat Felder für Titel, Alt-Text, Linkziel und Beschreibung. Auf alle vier Felder kann der Slider später zugreifen, es sind aber alle Felder optional.
- Ein Typoscript-Content-Objekt wird einem bereits vorhandenen oder neu angelegten TypoScript-Template definiert.
- Das TypoScript-Objekt wird über den Viewhelper < f:cObject typoscriptObjectPath="lib.slider"/> ins HTML-Template eingebunden.
- Fertig! Der Slider ist durch Bootstrap flexibel und verkleinert die Bilder, sobald der Bildschirm schmäler wird. Durch den Zugriff auf ein Verzeichnis können beliebig viele Bilder in den Slider geladen werden
- Der Slider tut im Einsatz Folgendes:
- Jedes Bild wird geladen, dazu Titel und Alt-Text.
- Als zweiter Schritt wird zu jedem Bild der Beschreibungstext auf das Bild gelegt und mit dem im "Links"-Feld angegebenen Seite verlinkt. Dadurch hat der Slider bei Bedarf eine eingebaute Navigation.
- Außerdem lädt der Slider dynamisch für jedes Bild einen kleinen Navigator, den man direkt zum Bild gelangt.
Foto: © gigi200043 - Fotolia.com
##### 1. Zugriff auf die Bildersammlung lib.slider = COA ##### 1. eine Startvariable festlegen lib.slider.5 = LOAD_REGISTER lib.slider.5.counter = 0 ##### 2. Zugriff auf die Bilder lib.slider.10 = FILES lib.slider.10.references { table = tt_content #####UID des "Images"-Content-Elements, in das die Bilder geladen werden uid = 123 fieldName = image } ##### 3. Ausgabeiteration der Buttons steuern lib.slider.10.renderObj = COA ##### 3.1. Zählervariable festlegen lib.slider.10.renderObj.10 = LOAD_REGISTER lib.slider.10.renderObj.10 { ### Die Startvariable wird der Zählervariablen zugewiesen divCounter.data = register:counter ### Die Startvariable wird wird bei jedem Durchlauf um eins erhöht counter.data = register:counter counter.stdWrap.wrap = |+1 counter.prioriCalc=1 } ##### 3.2 Die Zählervariable wird als Text ausgegeben und mit Optionsplit als Listenelemente gewrappt lib.slider.10.renderObj.15 = TEXT lib.slider.10.renderObj.15.data = register:divCounter lib.slider.10.renderObj.15.wrap = <li data-target="#carousel-example-generic" data-slide-to="|" class="active"></li>|*|<li data-target="#carousel-example-generic" data-slide-to="|" class=""> </li>|*|<li data-target="#carousel-example-generic" data-slide-to="|" class=""></li> ##### 3.3 Container um den gesamten lib.slider.10 lib.slider.10.stdWrap.wrap3 = <ol class="carousel-indicators">|</ol> ##### 4. Ausgabeiteration der Bilder steuern ##### 4. 1 Kopie des FILES-Objekts lib.slider.20 < lib.slider.10 lib.slider.20.renderObj = COA ##### 4.2 Das Bild wird geladen lib.slider.20.renderObj.10 = IMAGE lib.slider.20.renderObj.10 { file.import.data = file:current:publicUrl ##### 4.3 Das Bild erhält Alt-Text und Titel aus den Bildeigenschaften altText.data = file:current:alternative altText.htmlSpecialChars = 1 titleText.data = file:current:title titleText.htmlSpecialChars = 1 } lib.slider.20.renderObj.15 > ##### 4.4 Aus dem Feld "Description" wird ein Caption-Text erzeugt, der einen Link mit der im Linkfeld eingetragenen Adresse erhält lib.slider.20.renderObj.20 = TEXT lib.slider.20.renderObj.20 { stdWrap.data = file:current:description stdWrap.removeBadHTML = 1 stdWrap.typolink.parameter.data = file:current:link ##### 4.5 Container um die Caption wrap = <div class="carousel-caption active">|</div>|*|<div class="carousel-caption">|</div>|*|<div class="carousel-caption">|</div> } ##### 4.4 Container um die Bilder und Captions, das erste Element erhält eine andere Klasse als die anderen lib.slider.20.renderObj.wrap = <div class="item active">|</div>|*|<div class="item">|</div>|*|<div class="item">|</div> ##### 4.5 Container um den gesamten lib.slider.20 lib.slider.20.stdWrap.wrap3 = <div class="carousel-inner">|</div> ##### 5. Container um des gesamte Element lib.slider.stdWrap.wrap3 ( <div id="carousel-example-generic" class="carousel slide" data-ride="carousel"> | <a class="left carousel-control" href="#carousel-example-generic" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left"></span> </a> <a class="right carousel-control" href="#carousel-example-generic" data-slide="next"> <span class="glyphicon glyphicon-chevron-right"></span> </a> </div> )