Workshop: TYPO3 für Einsteiger
Als Vorlage für die umzusetzende Website wird www.typo3.com verwendet. Das Layout dieser Seite basiert auf Tabellen und der erzeugte HTML-Code entspricht nicht dem HTML-Standard. Bei diesem Workshop wird die Seite nun pixelgenau mit einem CSS-basierten Layout realisiert, gleichzeitig ist der erzeugte Code XHTML-kompatibel, für Suchmaschinen optimiert und deutlich schlanker als das Original. Die TYPO3-Webseiten werden im Zuge der neuen Corporate Identity Ende Januar 2006 auf ein neues Design umgestellt. Das hier verwendete Projekt dient nur als Beispiel, das sich aber auf beliebige andere Seiten übertragen lässt.
Die für das Projekt notwendigen Dateien, die Datenbank, eine lauffähige, angepasste Version von WOS (siehe Artikel „TYPO immer dabei“ auf Seite 52 dieser Ausgabe) und weitere Hinweise zu diesem Workshop sind unter www.jweiland.net/t3n/ abrufbar. Dort finden sich auch weitere Informationen zum Aufbau des TYPO3-Beispielprojekts.
Die Seite enthält in der Vorlage insgesamt elf Tabellen mit zusammen 50 Tabellenzellen. Die Struktur der Seite besteht aus vier Hauptbereichen: einem Kopfbereich mit dem TYPO3-Logo und einem horizontalen Menü, einem zweiten Kopfbereich mit einem Bild links und einem Text auf farbigem Hintergrund, eine Suchfunktion und ein Menü auf der linken Seite sowie dem eigentlichen Content-Bereich.
Zur Umsetzung der Seite werden die Extensions „rlmp-tmplselector“ und „automaketemplate“ eingesetzt. Das HTML-Template für die Seite wird im Verzeichnis „fileadmin/templates/main“, die dazugehörigen CSS-Dateien unter „fileadmin/templates/main/css“ abgelegt.
Schritt 1: Grundstruktur der Seite
Das HTML-Template enthält ausschließlich die logische Struktur der Seite. Sämtliche Formatierungen und die Gestaltung des Layouts erfolgen mit CSS. Für jeden der vier Hauptbereiche wird ein div-Container im HTML-Template (schritt1.html) angelegt:
<div id="header"> </div> <div id="header2"> </div> <div id="left"> </div> <div id="content"> </div>Listing 1
Da jeder dieser Container Unterbereiche enthält, werden diese als Kind-Elemente ebenfalls mit div-Containern definiert. Damit wird die logische Struktur der Seite nachgebildet:
<div id="header"> <div id="logo"> </div> <div id="topmenu"> </div> </div> <div id="header2"> <div id="header-image"> </div> <div id="header-text"> </div> </div> <div id="left"> <div id="leftmenu"> </div> <div id="search"> </div> </div> <div id="content"> </div>Listing 2
Für jedes logische Element der Webseite wird also ein eigener div-Container erzeugt. Damit ist das HTML-Template bereits fertiggestellt. Im nächsten Schritt wird die Größe und Positionierung der Container auf dem Bildschirm in der Datei „schritt1.css“ festgelegt. Das ist einfach und benötigt keine speziellen Tricks:
#header {
position: absolute;
top: 0;
}
#logo {
position: absolute;
right: 50px;
top: 22px;
background: url(../img/typo3logo.gif) no-repeat;
width: 152px;
height: 43px;
}
#topmenu {
position: absolute;
left: 22px;
bottom: 10px;
}
#header2 {
position: absolute;
left: 0;
top: 85px;
width: 845px;
height: 154px;
background: #bcd54b;
}
#content {
position: absolute;
top: 295px;
left: 280px;
width: 527px;
}
#left {
position: absolute;
top: 239px;
left: 0;
background: url(../img/bg2.gif) repeat-y;
width: 240px;
height: 100%;
}
Listing 3
Wenn man sich die Webseite im Browser ansieht, erscheint bereits die Grundstruktur der Seite. Allerdings gibt es bisher weder Menüs, noch das Suchfeld oder Content:
Die noch leere Seite offenbart ein paar Probleme, die noch behoben werden müssen:
- Der linke Container mit dem hellblauen Hintergrund erscheint nicht im Internet Explorer.
- Der linke Container erscheint zwar in Firefox, aber auch ein Scrollbalken auf der rechten Seite, obwohl dieser nicht notwendig wäre. Es gibt schließlich noch keinen Content, für den es sich lohnt zu scrollen.
- Das Logo ist bis jetzt nur ein statisches Bild, in der Originalseite ist es jedoch auch ein Link zur Seite HOME.
Schritt 2: Problemstellen beheben
Für den linken Container ist eine Höhe von 100% angegeben, aber 100% wovon? Diese Angabe bezieht sich immer auf das Elternelement, und das ist in diesem Fall das Browserfenster. Da dem Browserfenster in Firefox automatisch eine Höhe von 100% zugewiesen wird, funktioniert das. Beim Internet Explorer ist das nicht der Fall, daher muss die Größe von 100% explizit angeben. Dazu werden in der CSS-Datei (schritt2.css) noch weitere nützliche Parameter festgelegt:
body, html {
border: 0;
margin: 0;
width: 100%;
height: 100%;
background: #ffffff;
font: normal 100.01% Arial, Helvetica, Verdana, sans-serif;
}
Listing 4
Der Rahmen und Außenabstand werden auf Null gesetzt, die Breite und Höhe auf 100% (und damit auf die Größe des Browserfensters). Mit diesen Änderungen zeigt der MSIE den linken Container – und den Scrollbalken.
Der Grund für den Scrollbalken ist einfach: Die Größe des Containers ist mit 100% (der Höhe des Browserfensters) angegeben, aber der Container beginnt nicht am oberen Rand, sondern unterhalb des zweiten Kopfbereichs mit einem Offset von 239px. Damit ist die Höhe der Gesamtseite 100% plus 239 Pixel. Da die Größe des Browserfensters nicht bekannt ist, kann für den linken Container auch keine absolute Größe in Pixel angegeben werden.
Um das Problem zu lösen, muss der linke Container einfach am oberen Rand des Browserfensters beginnen. Dort überlappt er zwar die Container „header“ und „header2“, jedoch bietet CSS die Möglichkeit zur Arbeit mit Layern. Mit Hilfe der Eigenschaft „z-index“ kann festlegt werden, dass „header“ und „header2“ auf einer höheren Ebene liegen als der Container „left“. Wenn später das Menü und die Suchbox eingebunden werden, muss man nur darauf achten, diese nach unten zu verschieben, damit sie von den Kopfbereichen nicht verdeckt werden. Auch muss für den Bereich „header“ eine Hintergrundfarbe angeben werden, da beim Standardwert „transparent“ sonst der hellblaue linke Hintergrund sichtbar wird.
Im Element „content“ wird mit der Extension „lorem ipsum“ etwas Beispieltext angelegt, damit der Textfluss sichtbar wird. Da auch die Formatierung des Content mittels CSS (und der Extension „css_styled_content“) vorgenommen werden soll, wird eine weitere CSS-Datei mit den Eigenschaften für den Inhaltsbereich benötigt. Zur Einbindung einer zusätzlichen CSS-Datei gibt es mehrere Möglichkeiten: im HTML-Template, in TypoScript oder durch Importieren in die bestehende CSS-Datei. Hier wird die Import-Methode genutzt; dies muss zu Beginn der CSS-Datei erfolgen. Die Datei content.css ist dabei eine Kopie der von der Extension „css_styled_content“ mitgelieferten Vorlage. Der CSS-Code für die modifizierten Container sieht wie folgt aus:
@import url (content.css);
#header {
position: absolute;
z-index: 5;
top: 0;
left: 0;
width: 845px;
height: 85px;
background: #ffffff;
}
#header2 {
position: absolute;
z-index: 5;
left: 0;
top: 85px;
width: 845px;
height: 154px;
background: #bcd54b;
}
#left {
position: absolute;
z-index: 0;
top: 0;
left: 0;
background: url(../img/bg2.gif) repeat-y;
width: 240px;
height: 100%;
}
Listing 5
Die Webseite sieht anschließend wie folgt aus:
Schritt 3: Klickbares Logo und horizontales Menü
In Schritt 3 wird das statische TYPO3-Logo entfernt und per TypoScript dynamisch eingebunden:
page.10.subparts.logo = IMAGE
page.10.subparts.logo {
file = fileadmin/templates/main/img/typo3logo.gif
stdWrap.typolink.parameter = 11
}
Listing 6
Mit der letzten Zeile wird die ID der Seite festgelegt, zu der man nach einem Klick auf das Logo gelangt. Alternativ könnte hier auch eine URL oder E-Mail-Adresse angegeben werden. In der CSS-Datei sollte anschließend noch die bisherige Hintergrund-Definition in den Eigenschaften von „logo“ entfernt werden.
Der Code dafür wird nicht in den SETUP-Bereich des Haupt-Templates eingegeben, sondern als eigenes TypoScript-Modul (Workshop: Logo) auf der Seite „Basis Templates“ erstellt und dann über die Funktion „Include Basis Templates“ in das Template (in diesem Fall auf der Seite „Schritt 3“) eingebunden. Der TypoScript-Code wird dadurch modular und übersichtlich.
Durch Verwendung der Extension „automaketemplate“ und „rlmp-tmplselector“ wird jedem div-Container mit einer ID automatisch ein Subpart zugewiesen. Dadurch wird es sehr einfach, dynamische Elemente in TypoScript zu definieren.
Auch das horizontale Menü wird mittels CSS erzeugt. Da ein Menü strukturell nichts anderes ist als eine Liste von Links, werden die HTML Listen-Tags „ul“ und „li“ verwendet. Dazu sind nur ein paar Zeilen TypoScript notwendig:
page.10.subparts.topmenu = HMENU
page.10.subparts.topmenu.entryLevel = 1
page.10.subparts.topmenu.wrap = <ul>|</ul>
page.10.subparts.topmenu.1 = TMENU
page.10.subparts.topmenu.1 {
NO.allWrap = <li class="NO"> | </li>
ACT = 1
ACT.allWrap = <li class="ACT"> | </li>
}
Listing 7
Die Angabe „entryLevel=1“ sorgt dafür, dass das Menü eine Ebene tiefer beginnt und somit erst die Unterseiten der Seite „Schritt 3“ anzeigt. Der Code wird wieder als eigenes Modul (Workshop: horizontales Menü) auf der Seite „Basis Templates“ angelegt und dann im Template eingebunden. Das Menü sieht auf der Webseite zunächst so aus:
Es ist – wie zu erwarten – eine normale HTML-Liste und damit optisch noch ein bisschen anders als auf der Originalseite.
Aber mit wenigen Zeilen CSS kann das Aussehen des Menüs an die Vorgaben angepasst werden. Mit CSS besteht die Möglichkeit, nicht nur neue Klassen zu definieren, sondern auch die Eigenschaften von HTML-Tags zu ändern. Durch den Selektor „#topmenu“ gelten die geänderten Formatierungen nur für „ul/li“-Elemente, die sich innerhalb des Containers „topmenu“ befinden, alle anderen Listen bleiben unverändert:
#topmenu ul {
margin: 0;
padding: 0;
list-style: none;
}
#topmenu li {
float: left;
display: block;
position: relative;
top: 4px;
color: #000000;
padding: 0 10px 0 0;
font: normal 14px Verdana,Arial,Helvetica,sans-serif;
}
#topmenu li a {
text-decoration: none;
color: #000000;
}
#topmenu li a:hover {
color: red;
}
#topmenu li.ACT {
font-size: 18px;
position: relative;
top: 0px;
}
Listing 8
Mit der relativen Verschiebung um „+/-4“-Pixel wird erreicht, dass die Menüpunkte trotz der unterschiedlichen Schriftgrößen bei aktiven Seiten auf einer Grundlinie positioniert werden. Die float-Anweisung sorgt dafür, dass die Menüpunkte nebeneinander positioniert werden.
Schritt 4: Menü links und Suchfunktion
Das Menü in der linken Spalte wird ebenfalls als „ul/li“-Liste definiert, allerdings mit drei Ebenen. Um den Code für eine verschachtelte Liste zu erzeugen, wird die Eigenschaft „wrapItemAndSub“ verwendet. Dadurch werden die Unterlisten in Tags eingeschlossen. Auch dieses Menü wird als Modul (Workshop: vertikales Menü) auf der Seite „Basis Templates“ gespeichert und von dort in das Template auf der Seite „Schritt 4“ eingebunden:
page.10.subparts.leftmenu = HMENU
page.10.subparts.leftmenu.entryLevel = 2
page.10.subparts.leftmenu.stdWrap.wrap = <ul> | </ul>
page.10.subparts.leftmenu.1 = TMENU
page.10.subparts.leftmenu.1 {
expAll = 0
NO.wrapItemAndSub = <li class="NO"> | </li>
ACT = 1
ACT.wrapItemAndSub = <li class="ACT"> | </li>
CUR = 1
CUR.wrapItemAndSub = <li class="CUR"> | </li>
}
page.10.subparts.leftmenu.2 = TMENU
page.10.subparts.leftmenu.2.wrap = <ul> | </ul>
page.10.subparts.leftmenu.2 {
expAll = 0
NO.wrapItemAndSub = <li class="NO"> | </li>
ACT = 1
ACT.wrapItemAndSub = <li class="ACT"> | </li>
CUR = 1
CUR.wrapItemAndSub = <li class="CUR"> | </li>
}
page.10.subparts.leftmenu.3 = TMENU
page.10.subparts.leftmenu.3.wrap = <ul> | </ul>
page.10.subparts.leftmenu.3 {
expAll = 0
NO.wrapItemAndSub = <li class="NO"> | </li>
ACT = 1
ACT.wrapItemAndSub = <li class="ACT"> | </li>
CUR = 1
CUR.wrapItemAndSub = <li class="CUR"> | </li>
}
Listing 9
Damit das Menü unterhalb des grünen Kopfbereichs positioniert wird, wird für den Menü-Container ein oberer Außenabstand von 290 Pixeln definiert:
#leftmenu {
margin: 290px 0 0 0;
}
Listing 10
Das Menü kann auf eine beliebige Anzahl von Ebenen erweitert werden. Wieder werden nur ein paar Zeilen CSS benötigt, um es an die Vorgaben anzupassen. Für die erste Ebene sind folgende Zeilen notwendig:
#leftmenu ul {
margin: 0;
padding: 0;
list-style-type: none;
}
#leftmenu li {
text-decoration: none;
font: normal 13px Arial, Helvetica, Verdana, sans-serif;
padding: 5px 0 5px 30px;
}
#leftmenu li a {
text-decoration: none;
}
#leftmenu li a:hover {
color: red;
}
#leftmenu li a {
color: #000000;
}
#leftmenu li.ACT,
#leftmenu li.CUR {
background: url(../img/leftmenu-bg.gif) no-repeat;
font-weight: bold;
color: #000000;
}
Listing 11
Die weiteren Ebenen können formatiert werden, indem man Kopien dieser Struktur anlegt und die Tags „li“ austauscht mit „li li“ für die zweite, „li li li“ für die dritte Ebene und so weiter.
Übrigens hat die Verwendung von CSS-Menüs weitere Vorteile gegenüber der Originalseite:
- Mit der Struktur verschachtelter Linklisten wird das Menü auch für Besucher mit Sehbehinderungen zugänglich.
- Die Menüeinträge sind Textlinks, während das Menü der Originalseite mit Bildern erzeugt wird. Dadurch lädt die Seite nicht nur viel schneller, sondern das Menü kann auch von Suchmaschinen erfasst werden.
Zum Thema Suchmaschinen: Mit CSS gibt es weitere Methoden, die Indexierung und die Positionierung der Seite zu verbessern. Der Content kann an den Anfang der Seite gerückt werden, um dessen Relevanz zu erhöhen. Dazu wird im HTML-Template der „content“-Container vor allen anderen Containern platziert. Damit verändert sich die Reihenfolge bei der Code-Erzeugung der Webseite. Die Positionierung der Elemente auf dem Bildschirm wird – unabhängig von der Reihenfolge beim Rendering – über die CSS-Datei gesteuert. Für den Besucher sieht die Webseite exakt so aus wie vorher, für Suchmaschinen allerdings nicht:
<div id="content"> </div>
<div id="header">
<div id="logo"> </div>
<div id="topmenu"> </div>
</div>
<div id="header2">
<div id="header-image"> </div>
<div id="header-text"> </div>
</div>
<div id="left">
<div id="leftmenu"> </div>
<div id="search"> </div>
</div>
Listing 12
Die Suchfunktion wird auf allen Seiten unterhalb des linken Menüs eingebunden. Dazu wird das Typoscript-Modul „Workshop: Suchfunktion“ eingebunden. Dies enthält ein HTML-Formular, das beim Absenden auf die Seite mit den Suchergebnissen verzweigt. Dort ist im Content ein Plugin „Indexsuche“ enthalten. Damit auf der Ergebnisseite nicht zwei Formulare zum Eingeben von Suchbegriffen sind, wird über ein Extension-Template auf dieser Seite die Suchfunktion ausgeblendet, indem das TypoScript-Objekt gelöscht wird:
page.10.subparts.search >Listing 13
Schritt 5: Bild und Text im Kopfbereich
Zwei weitere Content-Elemente der Originalseite müssen noch integriert werden: das Bild und der Text im Container „header2“. Ein Redakteur muss in der Lage sein, diese Elemente beim Erstellen der Seite auszutauschen. Er kann dies in den Seiteneinstellungen (Seiten-Header) tun:
- Das Bild wird im Feld „Datei“ angegeben.
- Der Text wird in das Feld „Untertitel“ eingetragen.
Wiederum sind nur ein paar Zeilen Typoscript erforderlich, um die beiden Elemente dynamisch einzufügen:
page.10.subparts.header-image = IMAGE
page.10.subparts.header-image {
file.import.field = media
file.import = uploads/media/
file.import.listNum = 0
}
page.10.subparts.header-text = TEXT
page.10.subparts.header-text {
value = {page:subtitle}
insertData = 1
}
Listing 14
Dieser Code wird auf der Seite „Basis Templates“ im Modul „Workshop: Header2“ gespeichert und im Template von „Schritt 5“ eingebunden. Der Text wird mittels CSS positioniert und formatiert:
#header-text {
position: absolute;
bottom: 20px;
right: 35px;
font: normal 20px Verdana, Arial, Helvetica, sans-serif;
color: #ffffff;
text-align: right;
}
Listing 15
Schließlich wird noch eine weiße Linie mit einer Breite von 1 Pixel auf der rechten Seite des Bildes eingefügt:
#header-image img {
border-right: 1px solid white;
}
Listing 16
Ein erster Vergleich des erzeugten HTML-Codes zeigt, dass die neue Seite rund ein Drittel weniger Zeilen enthält und der Content deutlich weiter oben positioniert ist. Auch bei ausgeschaltetem CSS ist der Inhalt problemlos lesbar. Die Seite ist konform zu XHTML- und CSS-Standards und sieht in allen gängigen Browsern identisch aus.
Schritt 6: Rootline und Copyright
Allerdings fehlt noch eine Kleinigkeit: Die Originalseite hat direkt unterhalb des Content einen Copyright-Hinweis. Problematisch: Die Höhe des Content ist unbekannt und auf jeder Seite unterschiedlich. Der Content-Container ist absolut positioniert, daher wissen nachfolgende div-Elemente nichts über seine Position und Größe und würden nicht automatisch darunter platziert. Ein einfacher Trick bringt die Lösung: Der Content-Bereich wird in einen weiteren Container verschachtelt und dieser absolut positioniert. Dazu ist eine Erweiterung des ursprünglichen HTML-Templates notwendig:
<div id="content-wrapper">
<div id="rootline"> </div>
<div id="content"> </div>
<div id="copyright"> </div>
</div>
Listing 17
Dadurch benötigt der „content“ selbst keine absolute Positionierung mehr:
#content-wrapper {
position: absolute;
top: 295px;
left: 280px;
width: 527px;
}
#content {
position: relative;
}
#copyright {
padding: 20px 0 0 0;
clear: both;
font: normal 11px Arial,Helvetica,Verdana,sana-serif;
color: #999999;
}
Listing 18
Das Rootline-Menü benötigt nur wenige Zeilen Typoscript-Code, der als weiteres Basis-Modul in das Template eingebunden wird:
page.10.subparts.rootline = HMENU
page.10.subparts.rootline {
special = rootline
special.range = 1|-1
1 = TMENU
1.target = _top
1.NO.linkWrap = | > |*||*| |
}
Listing 19
Schritt 7: Zentrierung im Browserfenster
Momentan ist die Webseite – wie das Original – links im Browserfenster positioniert. Soll die Seite dagegen zentriert im Browserfenster angezeigt werden, muss die gesamte Seite in einen zusätzlichen Container („outer-wrapper“) eingebettet werden:
<div id="outer-wrapper">
<div id="content-wrapper">
<div id="rootline"> </div>
<div id="content"> </div>
<div id="copyright"> </div>
</div>
<div id="header">
<div id="logo"> </div>
<div id="topmenu"> </div>
</div>
<div id="header2">
<div id="header-image"> </div>
<div id="header-text"> </div>
</div>
<div id="left">
<div id="leftmenu"> </div>
<div id="search"> </div>
</div>
</div>
Listing 20
Um die Zentrierung im Internet Explorer zu erreichen, muss man die Textausrichtung für das Element „body“ auf „zentriert“ setzen. Da der Content selbst nicht zentriert angezeigt werden soll, wird die Ausrichtung im „outer-wrapper“ wieder auf linksbündig gesetzt:
body, html {
position: relative;
text-align: center;
...
}
#outer-wrapper {
text-align: left;
margin: 0 auto 0 auto;
width: 845px;
position: relative;
height: 100%;
}
Listing 21
Fazit
Mit ein paar CSS-Grundkenntnissen ist es möglich, in kurzer Zeit standardkonforme Webseiten mit TYPO3 zu erstellen. Einen guten Einstieg in CSS bietet das Buch „CSS Praxis“ von Kai Laborenz. Mit Hilfe von TypoScript-Modulen, die man auch in anderen Projekten immer wieder verwenden kann, ist der Code gut strukturiert und leicht pflegbar.


















