
Kleine Sammlung von Typo3 Snippets und nützlichen Quellen zum gleichen Thema für alle Kursteilnehmer des Typo3 Einsteiger Seminars. Die hier aufgelisteten Snippets sind nur eine lose Auflistung von Fragmenten aus den verschiedensten Aufgabenbeeichen, die vielleicht hilfreich sein könnten. Von der Optimierung der generierten HTML Syntax, über Navigationsvarianten bis zu speziellen Wrap Anweisungen.
Was ist TypoScript eigentlich? Grundsätzlich: TypoScript ist keine Programmiersprache. Es ist eher eine Konfigurationssprache – vergleichbar mit der Windows Registry. Und wie die Windows Registry ist TypoScript mächtiger als man auf den ersten Blick vermutet. Die offizielle Dokumentation findet man unter TSref bei Typo3. Und noch eine Analogie zur Windows Registry – je mehr Module und Plugins man lädt, desto größer wird der TypoScript Anteil des Projektes. Viele Plugins (bspw. Better Contact) lassen sich komplett über TypoScript konfigurieren.
Die Scriptsyntax lässt sich übrigens auch in seperate Dateien auslagern. Und mit SweeTs gibt es für den Editor PSPad sogar entsprechendes Syntax-Highlighting. Ähnliches liefert DEV3 – TYPO3 Enterprise Development für Eclipse. Eingebunden werden solche externen Dateien dann über:
<INCLUDE_TYPOSCRIPT: source="FILE: fileadmin/scriptdatei.ts">
Folgendes ist dabei zu beachten:
- Im Template muss das Include in einer eigenen Zeile stehen, sonst wird es nicht erkannt.
- Das Include wird vor dem Parsen des TS ausgeführt und funktioniert nicht mit Conditions und Verschachtelungen.
- Die Dateigröße darf nicht größer als 100KB sein.
- Die URL der Datei muss ausgehend von PATH_side sein, darf also kein “..” enthalten.
- Die Dateien werden “gecacht”, d.h. Änderungen greifen nicht sofort, sondern erst nach dem Leeren des Caches, in der Installationsanleitung bei SweeTS findet man aber einen Lösungsvorschlag, um dieses Problem zu umgehen.
Genug der Vorrede, hier nun ein paar Snippets aus der Welt von TypoScript. Viel mehr davon findet man bspw. unter TYPO3 Wizard: Snippets oder bei TYPO3 snippets.
Absatzidentifizierung verbessern (die leeren A-Tags)
Verändert man die Vorgaben für CSS Styled Contents nicht, so liefert Typo3 jeden Absatz mit einem leeren A-Tag aus. Dieser Tag enthält die eindeutige Referenz für den Absatz (‘c’+UID des Datenbank Eintrages). Grundsätzlich ist dieser Ansatz ja nicht schlecht – immerhin kann man so theoretisch auf jeden einzelnen Textbaustein der gesamten Seite verweisen, aber der Code lässt sich optimieren. Zum einen sind Tags ohne Inhalt (wenn es sich nicht um selbst-schließende Tags handelt) in XHTML strict gar nicht zugelassen, zum zweiten kann es hilfreich sein jeden Absatz mit einer eigenen ID zu versehen (in Hinblick auf CSS und Javascript Spielereien). Eine ID lässt sich ebenso als Sprungmarke nutzen wie ein A-TAG mit einem NAME-Attribut. Der TypoScript code dafür:
tt_content.stdWrap.dataWrap = <div id="c{field:uid}">|</div>
Jede Seite identifizieren (Optimierung body tag)
Wohl noch häufiger als die notwendige Identifizierung jedes einzelnen Textbausteins ist die Unterscheidung verschiedener Seiten, auch wenn Sie auf ein- und demselbem Template basieren, auch hier kann man sich die UID zu Nutze machen:
page.bodyTagCObject = HTML
page.bodyTagCObject.value.field = uid
page.bodyTagCObject.value.wrap = !!<=|>
Inhalte nur umschließen, wenn nicht leer
Ein Wrap ist manchmal nur dann nötig, bzw. sollte auch nur dann stattfinden, wenn auch Inhalte vorhanden sind, die Syntax hierfür ist:
tt_content.stdWrap {
wrap = <div>|</div>
required = 1
}
Inhalte aus einer anderen Spalte ausgeben
Nützlich für den Fall, dass auf bestimmten Seiten die Inhalte an anderer Stelle dargestellt werden sollen, als es “normaler” Weise in dem Template vorgesehen ist, ohne dafür ein neues Template zu erstellen. Um diese Angabe auf einen bestimmten Seitenbereich einzugrenzen kann man PIDinRootline nutzen:
#Alle Seiten unterhalb von der Seite mit der uid 1
[PIDinRootline = 1]
#Wobei die ColPos die Spalte definiert
#(Normal=0, Links=1, Rechts=2, Rand=3)
temp.boxes = CONTENT
temp.boxes {
table = tt_content
select {
pidInList.field = uid
orderBy = sorting
where = colPos = 2
}
}
[END]
Eine Basis Konfiguration
Ein Satz an allgemeinen Konfigurationsregeln für die Ausgabe von XHTML Seiten.
config {
doctype = xhtml_strict
xhtml_cleaning = all
xmlprologue = none
metaCharset = utf-8
additionalHeaders = Content-Type:text/html;charset=utf-8
htmlTag_langKey = de
locale_all = de_DE
language = de
removeDefaultJS = 1
simulateStaticDocuments = 0
baseURL = http://www.beispiel.de
#für den Fall das RealUrl verwendet wird
#tx_realurl_enable = 1
}
Aufräumen bei der HTML Ausgabe
CSS Styled Contents und der RTE Parser produzieren mir persönlich zuviele Klassen und Verschachtelungen, da kann man ruhig ein wenig anpassen:
#entfernen von class="bodytext" aus den <p>-Tags
lib.parseFunc_RTE.nonTypoTagStdWrap.encapsLines.addAttributes.P >
#Entfernen der style Attribute (Hoehe und breite) für Bild-Wrapper
tt_content.image.20.rendering.dl.imageRowStdWrap.dataWrap =
<div class="csc-textpic-imagerow">|</div>
tt_content.image.20.rendering.dl.oneImageStdWrap.dataWrap =
<dl class="csc-textpic-image###CLASSES###">|</dl>
## Liste der Tags, die nicht mit p-Tags umschlossen werden
lib.parseFunc_RTE.nonTypoTagStdWrap.encapsLines.encapsTagList =
div,p,pre,h1,h2,h3,h4,h5,h6,address
Navigation
Nachfolgend noch ein Beispiel für ein Navigationsmenü, hier aufgeteilt auf zwei Ebenen (oberste Navigationsebene, enthält neben dem Titel noch einen Untertitel) und einem zweiten Menü für die untergeordneten Seiten:
#Hauptnavigtion (1. Ebene)
lib.mainMenu = HMENU
lib.mainMenu.1 = TMENU
lib.mainMenu.entryLevel = 0
lib.mainMenu.1.expAll = 0
lib.mainMenu.1.noBlur = 1
lib.mainMenu.1.NO = 1
lib.mainMenu.1.NO {
stdWrap.cObject = COA
stdWrap.cObject {
10 = TEXT
10.field = title
10.stdWrap.htmlSpecialChars = 1
10.wrap = <strong>|</strong> 
20 = TEXT
20.field = subtitle
20.stdWrap.htmlSpecialChars = 1
20.wrap = <em>|</em>
}
linkWrap = <li id="mm_{elementUid}">|</li>
subst_elementUid = 1
}
lib.mainMenu.1.ACT = 1
lib.mainMenu.1.ACT < .lib.mainMenu.1.NO
lib.mainMenu.1.ACT.linkWrap = <li id="mm_{elementUid}" class="active">|</li>
#Untergeordnetes Menü 2-3 Ebene
lib.subMenu = HMENU
lib.subMenu {
entryLevel = 1
1 = TMENU
1 {
NO = 1
NO {
linkWrap = <li>|</li>
}
ACT = 1
ACT {
stdWrap.cObject = COA
stdWrap.cObject {
10 = TEXT
10.field = title
10.stdWrap.htmlSpecialChars = 1
10.wrap = <strong>|</strong>
}
linkWrap = <li>|</li>
}
}
2 = TMENU
2 {
wrap = <ul>|</ul>
NO = 1
NO {
linkWrap = <li>|</li>
}
ACT = 1
ACT {
stdWrap.cObject = COA
stdWrap.cObject {
10 = TEXT
10.field = title
10.stdWrap.htmlSpecialChars = 1
10.wrap = <strong>|</strong>
}
linkWrap = <li>|</li>
}
}
}
Zugegeben, auf den ersten Blick ist TypoScript sicher ein wenig gewöhnungsbedürftig, aber wer ernsthafter mit Typo3 arbeiten will, der kommt nicht umhin, sich tiefer in die Materie einzuarbeiten. Neben der bereits erwähnten TSRef findet man bei Typo3 u.a. auch noch den Artikel TypoScript Syntax and In-depth Study, ein umfassendes Tutorial zur Syntax und Funktionsweise vom TypoScript und eine mehrteilige deutschsprachige Einführung findet man beim Webworking Blog. In diesem Sinne, erfolgreiches Skripten.