DEPRECATION WARNING

This documentation is not using the current rendering mechanism and is probably outdated. The extension maintainer should switch to the new system. Details on how to use the rendering mechanism can be found here.

Moderne Templateerstellung, Teil 1 (MTB_de/1)

Author:Kasper Skårhøj
Created:2002-11-01T00:32:00
Changed by:kay stenschke
Changed:2004-07-25T08:12:10
Author:Kasper Skårhøj
Email:kasper@typo3.com
Info 3:Deutsche Übersetzung: Leander Kirstein-Heine und Kay Stenschke
Info 4:

Moderne Templateerstellung, Teil 1 (MTB_de/1)

Extension key: doc_tut_templselect_de

Copyright 2003-2004, Kasper Skårhøj, <kasper@typo3.com>

Deutsche Übersetzung: Leander Kirstein-Heine, < lkh@cnc-online.net > und Kay Stenschke, < kay@stenschke.com >

Dieses Dokument wurde unter der Open Content License veröffentlicht,

die unter http://www.opencontent.org/opl.shtml abrufbar ist.

Der Inhalt dieses Dokuments bezieht sich auf TYPO3

- einem GNU/GPL CMS/Framework verfügbar unter www.typo3.com

Inhaltsverzeichnis

Moderne Templateerstellung, Teil 1 (MTB_de/1) 1

Einführung 1

Worum geht es? 1

Die Grundlagen 4

Einleitung 4

Los geht's – Installation des ”dummy”-Pakets 4

Erstellen einer Seitenstruktur 5

Seitenbaum und Template Datensätze (template records) erklärt 7

Grundlagen der Anweisungen im Feld "Setup” 10

Weitere Beispiele zu PAGE und cObjects 12

Nochmals zu PAGE Objekten 17

Teil 1: Integration einer HTML Vorlage 21

Implementierung eines CMS 21

Das HTML Template 22

Grundlagen zum TEMPLATE cObject 25

Die Template Auto-parser Erweiterung 27

Alles zusammensetzen 31

Das Menü erstellen 34

Seiteninhalte einfügen 38

XHTML Konformität 44

Aufräumarbeiten 46

Weitere HTML-Design Betrachtungen 47

Schlussbemerkung: 50

Einführung

Worum geht es?

Diese Anleitung zeigt Ihnen von Grund auf, wie Sie mit dem Content Management System TYPO3 eine Website basierend auf einer HTML Vorlage (genannt Template) erstellen.

Für Entwickler auf Anfängerniveau.

Die Website, die Sie erstellen werden, sieht so aus:

img-1

Die Seite enthält einen Bereich für das dynamische Menü (links) und den dynamischen Seiteninhalt (rechts) - alles Übrige ist statischer Inhalt des HTML-Templates.

Ziel

Ziel dieser Anleitung ist es, Ihnen das Rüstzeug zu vermitteln um mit modernen Techniken TYPO3 basierte Websites zu erstellen. Es vermittelt Ihnen schnell praktische Erfahrungen mit dem System und ein Gesamtverständnis aller Faktoren für die Websiteerstellung mit TYPO3.Wenn Sie den Eindruck haben, diese Anleitung sei zu lang und sich etwas kürzeres wünschen, dann sollten Sie sich vielleicht ein anderes CMS suchen. Ein leistungsfähiges und komplexes Werkzeug wie TYPO3 kann auf weniger Seiten nicht beschrieben werden. Und auch diese Anleitung kann nur einen ersten Eindruck vermitteln.

Auch wenn TYPO3 kostenlos ist, heißt das nicht, dass der Entwickler sich keine Zeit zum Kennenlernen nehmen muss. Es erfordert genau sovielZeit und Einsatz wie jede kommerzielle Alternative auf gleichem Niveau. Seien Sie also vorgewarnt:einen Düsenjet fliegen zu könnenverlangt verschiedenste Fähigkeiten und folglich auch Zeit zum Erlernen. Mit dieser Anleitung werden sie aberhoffentlich so schnell wie möglich auf das Rollfeld gebracht werden um starten und bald abheben zu können.

Gliederung

Die Anleitung besteht aus vier Teilen:

Die Grundlagen: - eine Anleitung für Anfänger zum Erstellen von Websites mit TYPO3-Standardvorlagen, TypoScript und Content Objects (cObjects, also den Inhaltsobjekten). Jeder, der mit TYPO3 entwickeln möchte,sollte mit den hier beschriebenen Konzepten vertraut sein.

Teil 1: Integration e ines HTML-Templates - dieser Teilt richtet sich speziell an beteiligte HTML-Webdesignermit einem begrenzten technischen Wissen.

Teil 2: Erstellen einer Vorlagenauswahl - dieser Teil richtet sich an Webdesigner mit guten Kenntnissen von PHP, SQL und allgemeinen Programmierkonzepten.

Teil 3: Erweitern des integrierten Zugriffschemas: - für erfahrene TYPO3/PHP-Entwickler.

Hinweis: Teil 2 und Teil3 finden Sie in einem `weiterem Dokument <htt p://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=490&cHash=27f9c79d2 5>`_ `in der extension (Erweiterung)" <http://typo3.org/doc.0.html?&tx _extrepmgm_pi1[extUid]=490&cHash=27f9c79d25>`_ `doc_tut_templselect2” <http://typo3.org/doc.0.html?&tx_extrepmgm_pi 1[extUid]=490&cHash=27f9c79d25>`_

Sie müssen diese Anleitung nicht komplett durcharbeiten sondern können direkt zu zu dem für sie relevanten Thema springen. Wenn Sie die Anleitung jedoch komplett durcharbeiten,werden Sie Abschnitte finden, die aufeinander aufbauen und dadurch Schritt für Schritt Ihre Fähigkeiten verbessern. Das Verständnis der Inhalte beim Springen zwischen verschiedenen Anleitungen kann möglicherweise verschiedenes Grundwissen und Erfahrungen vorraussetzen

Die Extension

Alle Dateien dieser Anleitung finden Sie in ein einer TYPO3-Extension (Erweiterung).Normalerweise enthalten ExtensionsSkripte und Hilfsmittel, die die Möglichkeiten von TYPO3 erweitern. Diese Extensionhat allerdings keine Auswirkungen auf die Kernfunktionalität von TYPO3 sondern wird nur dazu benutzt, die Dateien dieser Anleitungauf Ihren Server zu bringen und um dieses Dokument online auf typo3.org zu präsentieren.

Um also mit diesem Dokument arbeiten zu können, installieren Sie zuerst das das dummy-package(siehe Grundlagenteil) und importieren Sie dann die extension “doc_tut_templselect“ vom TER (TYPO3 Extension Repository) mit dem Erweiterungsmanager. Dann haben Sie alle Dateien auf Ihrem Server zur Verfügung wenn Sie sie benötigen.

Dieses Dokument kann entweder online gelesen werden oder Sie können es als SXW-Datei (OpenOffice-Dokument) von typo3.org downloaden.

Kosten

Um dieses Dokument lesen zu können müssen Sie nichts bezahlen. Es hat jedoch denAutor, Kasper Skårhøj, eine kompletteWoche gekostet es vorzubereiten, zu schreiben und zu vervollständigen.Wenn diese Anleitung für Sie oder Ihr Unternehmen hilfreich istund Ihnen dabei hilft, leistungsfähige Websitesfür Ihre Kunden zu erstellen, erwägen Sie bitte die Möglichkeit einer Aufmerksamkeit.Reines Schulterklopfen ernährt niemanden und möglicherweise könnte diese Anleitung dann die letzte gewesen sein...

Die Grundlagen

Einleitung

Dieser Abschnitt wird den Anfänger schnell damit vertraut machen, wie das TYPO3 Frontend (also die Website, die TYPO3 erzeugt) funktioniert. Es erklärt was TypoScript Templates, Content Objects und HTML- Templatessind. Wenn Sie diese Grundlagen schon kennen, können Sie schon zum nächsten Abschnitt übergehen. Auf jeden Fall sollten Sie das dummypackage installieren und einige Seiten darin erstellen. Dies wird im folgenden besprochen:

Zielgruppe

Alle Entwickler, für die TYPO3 neu ist, unabhängig von ihren sonstigen Erfahrungen.

Einige Teile beziehen sich auf Technologien wie SQL, HTML, CSS und PHP. Der Inhalt ist im allgemeinen technischer Art, daer Sie durch die Installation des ”dummy”-Paketes führt und die Grundlagen derTemplatefunktionaltät inTYPO3 erklärt.

Los geht's - Installation des ”dummy”-Pakets

Um schnell loslegen zu können werden wir ein neues Dateiframeworkund eine leere Datenbank für TYPO3 installieren. Am einfachsten geht das mit dem ”dummy“-Paket.Ein Paket oder ”package” enthält denallgemeinen TYPO3 Quellcode sowie die lokal benötigten Dateien und ggf. Datenbankinhalte - und somit die komplette Website. Im Falle des dummy-Paketshandelt es sich um eine leere Website ohne Inhalt. Aber dies ist für eine neues Projekt sehr nützlich.

Also laden Sie sich das "dummy”-Paket herunter und installieren Sie es auf Ihrem Webserver. Nach dem Entpacken rufen Sie einfach die Datei index.phpauf und Sie werden durch folgende Schritte geführt:

Eingabe der Datenbankinformationen:

img-2

Erstellen einer neuen Tabelle:

img-3

Import der dummy Datenbank, "database.sql":

img-4

Das Backend aufrufen:

img-5

(Der Begriff Backend bezeichnet Anwendungen die auf einem Server ausgeführt werden, in diesem Fall das Administrationsinterface von Typo3.)Um diese Schritte erfolgreich durchlaufen zu können muss der Webserver Benutzer für die Datei localconf.php Schreibrechtebesitzen (Sie werden darauf hingewiesen, falls dies nicht der Fall sein sollte) und Sie müssen weiterhin den Benutzernamen und das Passwort des Datenbankbenutzers kennen.

Erstellen einer Seitenstruktur

Das erste was jetzt zu tun ist, ist die Seitenstruktur festzulegen. Eine gute Seitenstrukturenthält Seiten auf mindestens zwei Ebenen. Auf jeden Fall müssen wir mit einer Startseite der untersten (root) Ebene beginnen.

img-6

Geben Sie einen Seitentitel ein, machen Sie die Seite sichtbar und speichern Sie sie:

img-7

Jetzt könnten Sie so weiter machenund die gesamte Seitenstruktur erstellen. Es gibt es aber einen Assistenten, um diese Schritte viel einfacher durchzuführen.Wechseln Sie in das Modul: "Funktionen“,wählen Sie den Assistenten "Erzeuge mehrere Seiten”, geben Sie mehrere Seitentitel ein und klicken Sie anschließend auf die Schaltfläche"Seiten erstellen”.

img-8

(Für diesen Assistenten muss die Extension"Create multiple pages” installiert sein.)

Als Ergebnis sollten Sie einen solchen Seitenbaum erhalten:

img-9

Jetzt erstellen Sie weitere Seiten auf der nächsten Ebene, das Ergebnis sollte dann so aussehen:

img-10

Seitenbaum und Template Datensätze (template records) erklärt

Klicken Sie auf das Icon einer Seite und wählen Sie dann "Anzeigen” aus:

img-11

Das Ergebnis der Ansicht der Seite "Licensing“ sieht wie folgt aus:

img-12

Die Seite "Licensing" hat die uid"5” und zum Betrachten des Seiteninhalts muss der Parameter "id=5” an das index.php Skript des Frontends übergeben werden.

Die Ausgabe besagt nun aber, dass kein Template gefunden wurde. Das heißt, dass bei der Erzeugung der Seite keinTemplate gefunden wurde - ausgehend von der untersten Ebene des Seitenbaums für die Seite mit der id5. Zum besseren Verständnis hier etwas Theorie zur Erklärung:

TYPO3 ist ein CMS für mehrere Websites. Das bedeutet, dass Sie in einer Seitenstruktur unendlich viele Websiteshaben können. Jede Site in der Seitenstruktur muss eine Startseite haben, die dadurch gekennzeichnet ist, dass Sie ein Template enthält. Dieses Template muss als "Rootlevel” gekennzeichnet sein. Wenn also ein Template mit dieser "Rootlevel”-Kennzeichnung in einer Seite enthalten ist, heißt das, dass "ab jetzt eine neue Website innerhalb derSeitenstruktur beginnt”.

Die "root line“ (Ursprungspunkt) ist ein Synonym für "Pfad“. Man kann zum Beispiel auch sagen, dass die Seite "License A” in der Seitenstruktur den Pfad "TYPO3 > Root page > Licensing > License A” hat.Wenn wir die id von "License A” an das Skript index.php übergeben, wird bei der Erzeugung der Seite, ausgehend von der Position von "License A“ rückwärts bis zum Ursprungspunkt des Seitenbaumes (dem "page tree root“) nach einem Template Datensatz gesucht, der die Darstellung der Seite definiert.

Erstellen eines Template Datensatzes (template record)

Was wir also machen müssen ist einen Datensatz für ein Template auf der "Root page“zu erstellen. Der einfachste Weg dafür ist das "Template” Modul zu benutzen.

img-13

Die nächste Abbildung zeigt Ihnen diese Ansicht des "Template” Moduls, das Sie später zur Bearbeitung der Vorlage verwenden werden:

img-14

Jetzt schauen wir uns aber erst mal die "Root page" mit dem "Liste" Modul an:

img-15

Wie Sie sehen gibt es dort ein "Template” auf der "Root page”.

Diese Vorlage enthält die grundlegenden Anweisungen für die Generierung der Website durch die Frontend Engine ab diesem Punkt, welche Funktionen sie enthält, wie sie konfiguriert ist usw. Ein Template wird immer benötigt um mit einer neuen Website in TYPO3 zu beginnen (unter Verwendung der Standard Frontend Engine). Sie können selbstverständlich individuell festlegen, wie viel von Ihrem Webdesign das Template direkt kontrolliert; Sie können eine komplette Website in einem Template programmieren. Sie können das Template aber auch anweisen eine selbst programmierte PHP-Funktion aufzurufen, die Ihre Seite rendert und den gesamtenSeiteninhalt liefert (basierend auf XML, XSLT oder anderen Datenbanken - wie immer Sie mögen. Sie können ebenso einen Mittelweg beschreiten, der das beste beider Welten vereinigt. Und genau das ist es, was wir hier beschreiben.

Schauen wir uns den Inhalt des Templates an. Dort gibt es drei Felder von besonderem Interesse:

img-16

Der "Template title”ist nur der Titel des Templates und wird sonst nirgendwo angezeigt.

Der "Website title”wird den Seitentiteln vorangestellt, so wie zwischen den <title> Tags jeder herkömmlichen Seite.

Im "Setup” Feld fügen Sie die Anweisungen ein, wie die Seite auf verschiedene Weisen dargestellt werden soll. Diese Anweisungen werden in einer hierarchischen Informationsstrukur eingebunden, die von der TypoScript Syntax vorgegeben wird. Da die Anweisungen des Feldes"Setup” durch die TypoScript-Syntax definiert sind, werden Templates häufig als "TypoScript Templates” bezeichnet.

Die Einstellungen "Clear constants” und "Clear setup” bedeuten, dass kein TypoScript Konfigurationscode, falls vorhanden,von den Templates höher im Baum (näher an der Wurzel) übernommen wird.Diese Checkboxen sollten für die Templates angekreuzt werden, welcheals Basistemplatedienen sollen ("Rootlevel”).

Die "Rootlevel” Checkbox sagt nur aus: "diese Vorlage kennzeichnet den Beginn einer neuen Website”.

Nun zurück zur Ansicht der der Seite "Licensing”:

img-17

Jetzt erscheint etwas anderes. Folgendes ist passiert:

img-18

  • Anfrage der Seite mit der uid"5” ( 1)
  • Auswahl des ersten Template Datensatzesfür diese Seite (pid=5);nicht gefunden!
  • Da für die Seite mit der uid "5“kein Template gefunden wurde, wird die vorherigeSeite in der Hierarchie überprüft ( 2)
  • Die "Root page” (id=1) hat ein Template. Also wurde ein Template gefunden!
  • Da ein Template für die Seite mit der uid"1” gefunden wurde, wird überprüft, ob "Rootlevel” gesetzt ist ...
  • Ja "Rootlevel” ist gesetzt. Gut, das ist der Anfang der Website, also ...
    • Parsen (Analyse und Verarbeitung)der TypoScript Konfiguration im Feld"Setup”.
    • Führe die Anweisungen im Feld"Setup” aus.

Grundlagen der Anweisungen im Feld "Setup”

Wenn ein Template Datensatz vorhanden ist, liegt das Hauptinteresse beim Feld "Setup” dieses Templates. In dieses Feldtragen Sie einen Satz Anweisungen ein, die festlegen was geschieht, wenn wir eine Seite im Frontend aufrufen.

Die beste Möglichkeit dieses Feld zu bearbeiten ist im "Template” Modul mit der Ansicht"Info/Modify”:

img-19

Klicken Sie auf das "Bearbeiten” Symbol und es geht los:

img-20

Hier eine kurze Erklärung:

Das PAGE Object (1)

Zuerst definieren wir eine neues Objekt auf oberster Ebene ("Toplevel Object” - TLO), "page” genannt. Objekttyp ist "PAGE”(sie können auch einen Frameset definieren; siehe TSref). Anstatt "page” könnten Sie auch andere Bezeichnungen wählen,mit Ausnahme reservierter TLOs, siehe TSref about Toplevel Objects .Als Eigenschaft für das "page” Objekt definieren wir die vorgeschriebeneEigenschaft "typeNum” und setzen ihren Wert auf 0 (Null).

Das bedeutet jetzt, dass das Toplevel Objekt "page” die Standardbehandlung jedes Seitenaufrufs innerhalb eines Zweiges des Seitenbaums vorgibt, in dem unser Template den Beginn der Website kennzeichnet.

Nun wollen wir dem "page” Objekt Anweisungen geben, was es zu tun hat. Dazu müssen wir einen Blick auf die möglichen Eigenschaften für PAGE Objekte werfen. Einige Eigenschaften sind Metaeigenschaften wie die "Config-" oder "includeLibs" Eigenschaften. Andere dienen dazu, zu definieren, welche HTML-Ausgaben dieses PAGE Objekt erzeugen soll.

Der bedeutendste Satz der Eigenschaften für PAGE Objekte ist die numerische Liste der Inhaltsobjekte ( content objects - cObjects) . Jedesdieser Content Objects kann eine Zeichenkette mit HTML-Inhalt übertragen, der zusammen den Inhalt zwischen den <body> Tags der Seite bildet.

Das Content Object (2)

Im Beispiel oben ist ein sehr einfaches Content Object - TEXT - definiert,mit dem Index "10” innerhalb der numerischen Liste der Content Objects im PAGE Object "page”. Dieses cObject hat die Eigenschaft "value”, die auf "HELLO WORLD” gesetzt wurde. Dies hat zur Folge, dass dieser Text vom cObject zurückgegeben wird und zum Inhalt auf der Website zwischen den <body> Tags wird:

img-21

Die möglichen Eigenschaften für das TEXT cObject finden Sie hier .

TypoScript - keine Programmiersprache

Bevor wir fortfahren, beachten Sie bitte, dass TypoScript keine prozedurale Programmiersprache ist. Sie könnten leicht zudieser Annahme kommen. Wenn Sie Erfahrung mit anderen Programmiersprachen haben und wissen wie sie arbeiten, kann dies ein gefährlicher Cocktail werden mit dem Ergebnis totaler Verwirrung. TypoScript konfiguriert tatsächlich nur das System, um in einer bestimmten Weise zu agieren.

Um zu wissen, was TypoScript wirklich ist, um den Unterschied zu verdeutlichen und zum Verständnis, wie es in TYPO3eingesetzt wird, empfiehlt sich ein Blick in dieses Dokument, das die Grundlagen vermittelt .

Weitere Beispiele zu PAGE und cObjects

Dieser Abschnitt stellt Ihnen ein paar weitere Beispiele zu PAGE und cObjects vor, damit Sie das Konzept völlig erfassen. Wenn Sie dies verstehen, dann verstehen Sie auch "TypoScript Templates” wenn die Strukturen komplexer werden.

Zwei cObjects

Was passiert, wenn Sie ein weiteres Content Object einfügen:

# Default PAGE object:
page = PAGE
page.typeNum = 0

# Content object one:
page.10 = TEXT
page.10.value = HELLO WORLD!

# Content object two:
page.20 = TEXT
page.20.value = HELLO UNIVERSE!

(Übrigens, Zeilen die mit ”#” oder ”/” beginnen sind Kommentare.)

Ausgabe:

<body bgcolor="#FFFFFF">
HELLO WORLD!HELLO UNIVERSE!
</body>

So wie erwartet werden mehrere Content Objects einfach aneinander gehängt.

Ändern der Reihenfolge

Was passiert, wenn die Reihenfolge der Definitionen geändert wird?

# Default PAGE object:
page = PAGE
page.typeNum = 0

# Content object two:
page.20 = TEXT
page.20.value = HELLO UNIVERSE!

# Content object one:
page.10 = TEXT
page.10.value = HELLO WORLD!

Ausgabe:

<body bgcolor="#FFFFFF">
HELLO WORLD!HELLO UNIVERSE!
</body>

Das gleiche: die Reihenfolge der Ausgabe entspricht dem Index in der Liste.

Dynamischer Inhalt

Was ist aber nun, wenn wir wollen, dass das TEXT cObject den Seitentitel einfügt?

Schauen Sie dazu `in die TSref um festzustellen, ob das TEXT cObject < http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm _pi1[tocEl]=350&cHash=b49de28f83>`_ Eigenschaften besitzt, die es Ihnen erlauben, dieseszu realisieren. Siehtganz so aus. Außer der "value” Eigenschaft hat das TEXT cObject auf der gleichen Ebene auch " stdWrap” Eigenschaften (klicken Sie hier) , die benutzt werden können, um Daten dynamisch zu holen und zu verarbeiten.

Da die Übertragung des cObjects TEXT im Hauptbereich des PAGE Objekts erfolgt, wird der aktuelle Datensatz der Datensatz der aktuellen Seite. Wenn sich also die stdWrap Eigenschaft "field” auf einen Feldnamen bezieht, so wird der Inhalt vom aktuellen Seitendatensatz geholt. An dieser Stelle wird das Feld "title“ den Seitennamen beinhalten (dieses erfordert selbstverständlich Wissen darüber, welche Felder in der Seitentabelle verfügbar sind!)

# Default PAGE object:
page = PAGE
page.typeNum = 0

# Content object outputting current page title:
page.10 = TEXT
page.10.field = title

Ausgabe:

<body bgcolor="#FFFFFF">
Licensing
</body>

Da die aktuelle Seite die "Licensing” Seite war, war das auch der Titel bei der Ausgabe.

stdWrap Eigenschaften

Da wir nun mit den "stdWrap” Eigenschaften experimentieren, können wir den Wert mit weiterem Ausgabetext versehen und in den unterschiedlichen Weisen verarbeiten etc.:

# Default PAGE object:
page = PAGE
page.typeNum = 0

# Content object outputting current page title:
page.10 = TEXT
page.10 {
  field = title
  crop = 8 | ...
  case = upper
  wrap = This is the truncated page title: <b> | </b>
}

(Beachten Sie bitte wie ich die Formatierung in TypoScript verändert habe,so dass die Eigenschaften in geschweifte Klammern gesetzt wurden. Diese Syntax von TypoScript macht es einfacher, viele Eigenschaften auf der gleichen Ebene zuzuweisen. Im Endergebnis macht es aber keinen Unterschied, alle Eigenschaften mit dem vollen Objektpfad "page.10” festzulegen.)

Ausgabe:

<body bgcolor="#FFFFFF">
This is the truncated page title: <b>LICENSIN...</b>
</body>

Beachten Sie auch, wie der Text den Seitentitel einschliesstund desweiteren in Großbuchstabenumgewandelt und auf acht Zeichen begrenzt wurde und wie das"...” angehängt wurde.

Die selbe Ausgabe hätten wir auch mit einem anderen cObject erreichen können, nämlich genannt"HTML” - der einzige Unterschied ist, dass alle stdWrap Eigenschaften zur "value” Eigenschaft des HTML cObjects gehören und nicht Eigenschaften des cObjects selbst sind:

# Default PAGE object:
page = PAGE
page.typeNum = 0

# Content object outputting current page title:
page.10 = HTML
page.10.value {
  field = title
  crop = 8 | ...
  case = upper
  wrap = This is the truncated page title: <b> | </b>
}

Es ist nur eine Frage der persönlichen Vorlieben und Ihres Stils ob Sie TEXT oder HTML cObjects einsetzen.

Inhalt ausPHP Skripten

Wenn Sie möchten können Sie den Inhalt auchsehr einfach überPHP Skripte einfügen. Dies ist eine sehr empfohlene Vorgehensweise, wenn Sie eine programmgesteuerte(bedingte)Ausgabenbenötigen, was TypoScript nicht kann, da die cObjects und ihre Eigenschaften keine prozedurale Programmierung erlauben. Sie erinnern sich, dass dies nur vorprogrammierte Objekte sind, die auf die gesetzten Eigenschaften reagieren, und nichts weiter.

Was Sie dazu brauchen ist das cObjectUSER.

Zuerst erstellen wir eine PHP -Datei in fileadmin/userfunctions.php :

<?php

class user_functions {

        /**
         * Multiplies the current page ID with $conf["factor"]
         */
        function multiplyTest($content,$conf)   {
                $currentPageUid = $GLOBALS['TSFE']->id;
                $factor = intval($conf['factor']);

                return $currentPageUid * $factor;
        }
}
?>

Dann konfigurieren wir ein cObject vom Typ USER , welchesdiese Funktion mit einem einfachen Parameter "factor” aufruft:

# Default PAGE object:
page = PAGE
page.typeNum = 0
page.includeLibs.some_random_id_string = fileadmin/userfunctions.php
page.config.admPanel = 1

# Content object outputting current page title:
page.10 = HTML
page.10.value = The page ID, {field:uid}, multiplied with 15 is:
page.10.value.insertData = 1
page.10.value.wrap = <b> |</b> <br />

page.20 = USER
page.20.userFunc = user_functions->multiplyTest
page.20.factor = 15

Und die Ausgabe sollte so aussehen:

img-22

Wie Sie sehen, haben wir einige "Metaeigenschaften” definiert, die nicht direkt mit der Inhaltsausgabe in Beziehung stehen:

page.includeLibs.some_random_id_string = fileadmin/userfunctions.php
page.config.admPanel = 1

"includeLibs” ist eine Eigenschaft, die es erlaubt, eine Liste von einzubindendenPHP-Dateien zusammenzustellen (Klassen- und Funktionsbibilotheken!), die eingebunden werden, bevor die Seite erzeugt wird. "config” erlaubt eine `Menge an Konfigurationsoptionen < http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm _pi1[tocEl]=338&cHash=6a7c6eecbb>`_ für das allgemeine Verhalten dieses PAGE Objekts. In diesem Falle wurde das "Admin Panel” am Seitenende eingefügt.

Für dieses Beispiel sollten Sie sich ein paar Minuten Zeit nehmen. Beachten Sie wie die Eigenschaft "factor” des ObjektsUSER in der PHP- Funktion verfügbar ist. Beachten Sie, wie sich diePHP-Funktion die Seiten-ID "holt“. Beachten Sie, wie das "Admin Panel” eingebunden wurde. Sie können eine Menge davon lernen, wenn Sie mit diesem kleinen Beispiel spielen. Lassen Sie ihrer Phantasie freien Lauf, da Sie dadurch ein gutes Gefühl der Steuerung bekommen.

Der Object Browser

Der Object Browser im Template Modul ist ein unentbehrliches Werkzeug zumÜberprüfen der hierarchischen Struktur IhrerTemplate Datensätze.

img-23

Wie Sie sehen können, werden die gelesenen TypoScript Werte in dieser wohl organisierten Baumstruktur ausgegeben. Somit können Sie überprüfen, ob jede Eigenschaft, die Sie eingestellt haben, sich an der jeweils korrekten Position befindet und es ist Ihnen sogar erlaubt, einen einzelnen Wert zu bearbeiten, wenn Sie sicherstellen, dass die Option "Enable object links” angewählt ist.

img-24

img-25

img-26

Wenn Sie zu "Info/Modify” zurückgehen sehen Sie, dass der Inhalt des FeldesTemplate Setup verändert wurde.

img-27

Der Object Browser ist nicht intelligent genug die Zeile mit "page.20.factor = 15” abzuändern. Er fügt einfach eine neue Zeileam Ende ein, die den Inhalt des vorher gesetzten Wertes überschreibt. Sie können dies manuell bereinigen. Daraus ergibt sich, dass der Object Browser eine sichereMöglichkeit für zurEinstellung dieserWerte bietet, da immer derrichtige Objektpfad genutzt wird.

Eine Bedingung ausprobieren

Wir könnten diese Situation tatsächlich nutzen, um die Anwendung von "Bedingungen” zu demonstrieren. Eine sehr einfacheBedingung soll soll überprüfen, welcher Webbrowser verwendet wird:

# Default PAGE object:
page = PAGE
page.typeNum = 0
page.includeLibs.some_random_id_string = fileadmin/userfunctions.php
page.config.admPanel = 1

# Content object outputting current page title:
page.10 = HTML
page.10.value = The page ID, {field:uid}, multiplied with 15 is:
page.10.value.insertData = 1
page.10.value.wrap = <b> |</b> <br />

page.20 = USER
page.20.userFunc = user_functions->multiplyTest
page.20.factor = 15

[browser = msie]

page.20.factor = 30
page.10.value = The page ID, {field:uid}, multiplied with 30 is:

[global]

Im Microsoft Internet Explorer sieht das dann so aus:

img-28

In allen anderen Browsern so:

img-29

Nochmals zu PAGE Objekten

OK, dies soll kein allgemeiner Kurs sein um Templates nur mit cObjects zu gestalten - in diesem Handbuch benutzen wir hauptsächlich TEMPLATE, USER und HMENU Objekte und kombinieren sie mit vordefiniertem TypoScript Code instatischen Templates um unsere Ziele zu erreichen. Die eigentliche Beschreibung von Objekten und ihren Eigenschaften finden Sie im TSref . Wenn Sie Beispiele für die Benutzung dieser Objekte suchen, schauen Sie bitte in TypoScript by Example .

Mit diesen zwei Punkten möchte ich dann im Übrigen zum Ende kommen:

Die Relevanz von "&type=”

Im folgenden Beispiel ist nichtnur ein PAGE Objekt definiert. Desweiteren istnoch das TLO "another_page” als PAGE Objekt definiert, aber "typeNum” ist auf "1” gesetzt. Das bedeutet, dass die PAGE "page” als Standardbearbeitung von Seitenanfragen definiert ist, während "another_page” jene Seiten betrifft, welchemit dem Parameter "&type=1” zusätzlich zumid-Parameter aufgerufen werden.

page = PAGE
page.typeNum = 0
page.10 = TEXT
page.10.value = HELLO WORLD!

another_page = PAGE
another_page.typeNum = 1
another_page.10 = TEXT
another_page.10.value = HELLO UNIVERSE

Die Ausgabe ist dann:

img-30

Hier der Objektbaum:

img-31

Kopieren von Objekten

Es kann schnell sehr praktisch werden, den TypoScript Konfigurationscode Ihres Templates in Einheiten verschiedener Bereiche/Funktionen aufzuteilen um diese dann am Ende des Templates zusammenzufügen, indem sie an die richtige Positionen kopiert werden. Dies schließt ggf. ein Aufspalten der Einheiten in eine Hierarchie von eingebundenen Template Datensätzen ein, die somit eine Wiederverwendung von TypoScript zulässt. Darüber erfahren Sie später mehr.

Die Haupteigenschaft von TypoScript, die dieses erlaubt, ist die Syntax zum Kopieren der Objekte von einem Zweig desObjektbaums in einen anderen. Dazu dieses Beispiel:

# Make temporary version of the first cObject:
temp.world = TEXT
temp.world.value = HELLO WORLD!


# Make temporary version of the second cObject:
temp.universe = TEXT
temp.universe.value = HELLO UNIVERSE!


# Default PAGE object:
page = PAGE
page.typeNum = 0

page.10 < temp.world
page.20 < temp.universe

Das Ergebnis ist - selbstverständlich - dieses:

<body bgcolor="#FFFFFF">
HELLO WORLD!HELLO UNIVERSE!
</body>

Wenn Sie in den ObjectBrowser schauen, werden Sie bemerken,dass die Objekte von "temp. ...” in die Pfade "page.10” und "page.20” kopiert wurden. Wir könnten natürlich erwarten, dass die TLOs von "temp” ebenfalls im Baum zu sehen wären, aber das ist nicht der Fall. Der Grund hierfür ist, dass die TLOs "temp.” und "styles.” gelöscht werden, da sie während des Parsens in einem temporären Objekt- Bereich verfügbar sind, danach aber nicht mehr erreichbar sind.

img-32

Wenn wir unsere Objekte innerhalb des Baums sehenmöchten, können wir ein anderes TLO benutzen:

# Make temporary version of the first cObject:
MY_TLO.world = TEXT
MY_TLO.world.value = HELLO WORLD!


# Make temporary version of the second cObject:
MY_TLO.universe = TEXT
MY_TLO.universe.value = HELLO UNIVERSE!


# Default PAGE object:
page = PAGE
page.typeNum = 0

page.10 < MY_TLO.world
page.20 < MY_TLO.universe

... und das TLO "MY_TLO" ist noch vorhanden

img-33

Referenzen - keine Kopien

Diesbedeutet auch, dass wir eine Referenz auf die Objekte in MY_TLO.* erstellenkönnen, da für Referenzen auf cObjects erforderlich ist, dass sie in der Struktur auch noch nach dem Parsen vorhanden sind (im Gegensatz zu den "temp” und "styles” TLOs). Das Skript kann dazu wie folgt umgeschrieben werden:

# Make temporary version of the first cObject:
MY_TLO.world = TEXT
MY_TLO.world.value = HELLO WORLD!


# Make temporary version of the second cObject:
MY_TLO.universe = TEXT
MY_TLO.universe.value = HELLO UNIVERSE!


# Default PAGE object:
page = PAGE
page.typeNum = 0

page.10 =< MY_TLO.world
page.20 =< MY_TLO.universe

Es sieht nur wie eine kleine Veränderung aus, hat aber eine immense Auswirkungen,da Objekte NICHT kopiert werden, sondern referenziert.

img-34

Aus dieser Methode ergeben sich für uns einige praktische Auswirkungen, aber auch Beeinträchtigungen. Das überzeugende Argument für Referenzen ist jedoch, dass ein cObject, welchesin einem Baum definiert wird, mehrfach innerhalb einerStruktur ohne weiteren Speicherverbrauch für Duplikate genutztwerden kann. Ebenfalls schwierig zu handhaben wäre auch das Überschreiben der Eigenschaften aller Duplikate in einem Baum. Ein Beispiel zu diesem Problem finden Sie am Ende von Teil 2 in diesem Tutorial.

Hinweis: Referenzen wie diese sind nicht Teil der eigentlichen TypoScript-Syntax. Es handelt sich hierbei um eine MöglichkeitEigenschaft, die intern von den cObjects bereitgestellt wird. Folglich können Referenzen nur bezogen auf cObjects genutzt werden; in Verbindung mit keinem anderen Objekttyp oder und keiner anderen Objekteigenschaft können Referenzen eingesetzt werden(es sei denn, dies wird ausdrücklich angemerkt).

Löschen des Cache (Zwischenspeichers)

Abschliessend sollten Sie noch wissen, dass wenn Sie Änderungen an einem Template Datensatz vorgenommen haben, der gesamte Zwischenspeicher (cache) gelöscht wird. Dies ist erforderlich da während des Parsens eines TypoScripts durch Typo3 die als Ergebnis zurückgelieferte Struktur im Cache gespeichert wird, so dass sie beim nächsten Seitenaufbau erneut "hervorgeholt“ werden kann. Jedoch bedeutet dies auch, dass Änderungen, die direkt im List-Modul an den Templates vorgenommen werden, den Cache nicht leeren - das müssen Sie manuell tun, über den Link unterhalb des Menüs im linken Frame.

Bevor Sie also ein merkwürdiges Verhalten als Bug melden, vergewissern Sie sich grundsätzlich, dass es nicht an immer noch zwischengespeicherten, inzwischen veränderten Templates oder Extensions liegt.

Teil 1: Integration einer HTML Vorlage

Implementierung eines CMS

Die Erstellung einer Website mit einem CMS erfordert die Einbeziehung von mehr Komponenten, als wenn die Site nur mit reinem statischem HTML erstellt würde. Die Idee hinter der Verwendung eines CMS ist den eigentlichen Inhalt getrennt von den Definitionen zu dessen Darstellung zu speichern. Einige CMS speichern den Inhalt in XML Dateien, andere nutzen relationale Datenbanken. Die Unterschiede haben verschiedene Für und Wider, aber die Idee dahinter ist die selbe: "Der Inhalt wird von den Farben getrennt”.

Wenn TYPO3 Webseiten generiert, wird unformatierter Inhalt aus einer Datenquelle (Datenbank) mit den Formatanweisungen aus einem HTML- Template kombiniert. In diesem Prozess dient das Template als Kontrollelement , das festlegt in welcher Form Typo3 diese Kombination durchführen soll.

In der nächsten Abbildung sehen Sie, wie der Template Datensatz als Steuerelement - also sozusagen als "Programm” hinter der Erstellung des Frontends fungiert: schrittweise wird der Inhalt in der Datenbank gefunden, das Template gelesen, der Inhalt an den dafür vorgesehenen Platzhaltern eingefügt und eine ansehnliche Webseite wird ausgegeben!

img-35

In den meisten Webagenturen arbeiten bei der Erstellung einer Website eine ganze Anzahl von Leuten zusammen. In dieser Gruppe finden wir einen Grafikdesigner, einen Programmierer und einen Texter (zumindest für den ursprünglichen Inhalt zum Beginn). Jede dieser Personen hat unterschiedliche Kenntnisse und arbeitet folglich bei der Produktion der Site in unterschiedlichen Bereichen:

img-36

Wie in obigen Abbildung wird jeder Person von den verschiedenen Komponenten der vom CMS erzeugten Wesite eine zugewiesen:

  • Mr. Raphael ist der Künstler. Er versteht viel von visueller Darstellung, er kennt Photoshop, Dreamweaver, CSS, HTML usw. Raphael jongliert mit Flashfilmen, hat aber keine Ahnung von PHP, TypoScript, SQL und anderen technischen Fragen. Also erstellt Raphael die HTML- Templatesfür uns!
  • Mr. Benoit ist ein Entwickler. Er liebt Bits und Bytes, er mag Compilerananweisungen, reguläre Ausdrücke, Logik, PHP, SQL - und bald wird er auch TypoScript lieben. Wie jeder andere gute Programmierer glaubt er mehr an gute Blue Jeans als an extravagantes Design. Farben und Benutzbarkeit zu kombinieren ist nicht in seine Wiege gelegt worden. Daher ist Benoit für die Konfiguration von TypoScript in den Templates verantwortlich.
  • Mr. Pic outo erstellt die Inhalte. Er versteht was von Marketing. Die Arbeit von Raphael und Benoit bewundert er, da sie in seinen Augen wahre Wunder vollbringen. Er selbst ist weder ein Designer noch ein Programmierer, aber er hat die Fähigkeit zu kommunizieren. Und mit dem Backend von TYPO3 kann er den Inhalt erstellen, ohne mehr Kenntnisse besitzen zu müssen als für die Bedienung einer Textverarbeitung.

So haben wir also drei Charaktere mit jeweils speziellen Fähigkeiten, ohnewelchedie Erstellung einer CMS basierten Website kein Spaziergang ist, es sei denn Sie besitzen alle diese Fähigkeiten: Darstellung, Technik und Marketing. Normalerweise ist dies nur in einem Team der Fall, bei einzelnen Personen ist es eher unüblich. Seien Sie also gewarnt (wenn Sie weniger qualifiziert sind, müssen Sie entweder viel dazulernen oder Sie benutzen einfach Standardtemplates mit einem vorgegebenen Design, welches Sie nur noch etwas anpassen müssen (das beschreibt diese Anleitung nicht).

In diesem Tutorialzeige ich Ihnen, wie Raphael, Benoit und Picouto zusammenarbeiten müssen um moderne Websites erstellen zu können. Jedes Teammitglied kann sich in seinem eigenen Bereich entfalten und Werkzeuge nutzen die es mag, um leicht zu pflegende Websites mit einem traumhaften Designerstellen zu können. Mit TYPO3.

Fachliche Voraussetzungen

Webdesigner mit HTML/CSS Wissen, nicht notwendigerweise Webentwickler.

Damit Sie diesen Abschnitt vollständig durcharbeiten können, sollten Sie über gute HTML- und CSS-Kenntnisse verfügen. Weiterhin brauchen Sie eine funktionierende TYPO3-Datenbank, wie wir sie bereits in einem früheren Abschnitt dieses Tutorials angelegt haben. Schließlich sollten Sie mit Konzepten der Programmierung vertraut sein, um alles vollständig verstehen zu können. Aber keine Angst, Ihnen wird alles erklärt was Sie wissen müssen - seien sie einfach aufmerksam und nehmen Sie sich die Zeit, die Beispiele zu nachzuvollziehen.

Das HTML Template

Das Webteam hat einen neuen Kunden: Main Dish& Son - und Raphael, der Künstler im Team, hat eine Vorlage in Form einer regulären HTML-Datei erstellt:

img-1

Diese HTML-Datei wird in dem Verzeichnis "fileadmin/template/main” relativ zur TYPO3-Installation (dummy package) gespeichert.

Um dieser Anleitung folgen zu können, sollten Sie jetzt den Inhalt des Ordners "part1/” von diesemTutorialin das Verzeichnis "fileadmin/template/main” kopieren. Falls Sie die Extension zu diesem Tutorial noch nicht importiert haben, sollten Sie dies jetzt nachholen.

Falls Sie den vorigen Abschnitt über TypoScript übersprungen haben, sollten Sie zumindest den Seitenbaum wie im Kapitel "Erstellen einer Seitenstruktur” und ggf. ein leeres Template erstellen .

img-37

Zurück zu Raphaels Arbeit: die Vorlage ist tatsächlich lediglich nur eine reguläre HTML-Seite. Wenn aber TYPO3 diese Datei als Template nutzen soll, müssen einige Teile daraus dynamisch werden. Dazu gehört das Menü auf der linken Seite und der Bereich mit dem Blindtext im rechten Bereich in der Mitte.

Wenn Sie sich den Quelltext des HTML-Templates anschauen, werden Sie bemerken, dass es sich um ein XHTML-Dokument handelt, welches ein Stylesheet als Formatvorlage verwendet und mittels einer Tabelle verschiedenen Elemente anordnet.

img-38

Hier einige Kommentare zu diesem HTML-Template und den Herausforderungen, die auf uns zukommen:

Der Abschnitt ab dem Header des Dokuments muss in unsere Webseite übernommen werden, da hier der Bezug zu dem Stylesheet eingetragen ist.Aufgabe: Wir müssen überprüfen, ob dieser Teil in die von TYPO3 generierte Seite übernommen wird.

Das Menü auf der linken Seite wurde mit einem <div> Abschnitt pro Menüpunkt erstellt. Jedes dieser <div> Elemente hat eine ihm zugewiesene Klasse. Über diesen Namen der Klasse wird das Aussehen mittels der CSS-Formatvorlage gesteuert.Dies ist ein äußerst vernünftiges Prinzip einer Menügestaltung, da jedes Element nur aus wenig HTML-Code besteht (gut für die TypoScript-Implementierung), es ist leicht reproduzierbar (notwendig für ein dynamisches Menü).Aufgabe: Der Platzhalter für das Menü muss durch ein dynamisch generiertes Menü ersetzt werden.

Den Blindtext im Inhaltsbereich hat Raphael eingesetzt um das Erscheinungsbild darzustellen. Beachten Sie, wie dieser formatiert ist: mit <h1> und <p> Tags (der Klasse "bodytext”, das ist ebenfalls klug gewählt, da auch TYPO3 diese Tags/Klassen bei der Erzeugung der Seite verwenden wird! Raphael hat wohl schon TYPO3-Erfahrung, oder?)Aufgabe: Austausch des Blindtextes gegen dynamisch erzeugten Seiteninhalt.

Dieser break-Tag für den Zeilenumbruch sorgt dafür, dass der Fußbereich nicht zu dicht am eigentlichen Text der Seite liegt.

Letztendlich sollten Sie noch beachten, wie die Zellen der Tabelle für das Menü und den Inhalt mit Tags mit id-Attributen versehen sind. Dies ist nicht nur für das Stylesheet von Bedeutung. Es gibt dafür noch einen anderen wichtigen Grund. Aber zuerst nochmal etwas Theorie zu HTML-Templates:

Grundlagen zum TEMPLATEcObject

Erstellen Siezuerst eine neue Datei (fileadmin/template/test.html) mit folgendem Inhalt:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>
<head>
        <title>Untitled</title>
</head>

<body>

<!-- ###DOCUMENT_BODY### -->
        <h1>
                <!-- ###INSIDE_HEADER### -->
                        Header of the page
                <!-- ###INSIDE_HEADER### -->

        </h1>
<!-- ###DOCUMENT_BODY### -->

</body>
</html>

(Diese Datei finden Sie in der Tutorial Extension als "misc/test.html”)

Dann fügen Sie bitte das folgende in das Setup-Feld Ihres Template Datensatzes:

# Template content object:
temp.mainTemplate = TEMPLATE
temp.mainTemplate {
  template = FILE
  template.file = fileadmin/template/test.html
}


# Default PAGE object:
page = PAGE
page.typeNum = 0

page.10 < temp.mainTemplate

Dies fügt ein cObject vom Typ "TEMPLATE” an Position "page.10” ein. Die "template”-Eigenschaft diesesTEMPLATEcObjects ist als weiteres cObject vom Typ "FILE” definiert, welches die soeben erstellte Datei "fileadmin/template/test.html” einliest. Die Eigenschaften des TEMPLATE cObject finden Sie hier .

Wenn Sie jetzt die Änderungen speichern und das Frontend aufrufen, sollten Sie folgende Ausgabe sehen:

img-39

Und wenn wir den Quellcode betrachten, sehen wir, dass das TEMPLATE cObject die Datei, so wie sie ist, liest und zurückliefert:

img-40

Nun zum wichtigsten Punkt des TEMPLATE cObjects: es liest nicht nur die HTML-Datei - es erlaubt uns auch, Teile daraus zu extrahieren und durch dynamischen Inhalt zu ersetzen!

Ein Teilabschnitt wird als Inhalt zwischen zwei gleichen Markierungen definiert, die von ### umschlossen sind und wiederum (optional) in HTML-Kommentaren enthalten sind. Die Datei "test.html” Datei hat zwei Teilabschnitte, den "DOCUMENT BODY” und den Abschnitt "INSIDE HEADER”. Wie Sie sehen können, werden die Markierungen dieser Teilabschnitte in HTML-Kommentaren eingeschlossen, so dass sie nicht sichtbar sind.

img-41

Nun ändern Sie bitte das Setup-Feld des Template Datensatzes wie folgt:

# Template content object:
temp.mainTemplate = TEMPLATE
temp.mainTemplate {
  template = FILE
  template.file = fileadmin/template/test.html
  workOnSubpart = DOCUMENT_BODY
  subparts.INSIDE_HEADER = TEXT
  subparts.INSIDE_HEADER.value = HELLO WORLD!
}


# Default PAGE object:
page = PAGE
page.typeNum = 0

page.10 < temp.mainTemplate

Im Frontend sollte der HTML-Quelltext dann wie folgt aussehen:

img-42

Die Veränderungen an den Eigenschaften des TEMPLATE cObjects haben folgendes bewirkt:

  • In erster Linie wurde das TEMPLATE cObject angewiesen, mit dem Teilabschnitt zu arbeiten, der mit "###DOCUMENT_BODY###” markiert ist - folglich wurde die überflüssige Überschrift und die Body- Markierungen entfernt.
  • Danach wurde der Teilabschnitt, der durch "###INSIDE_HEADER###” gekennzeichnet war, durch ein TEXT cObject ersetzt, das die Eigenschaften des "subparts.INSIDE_HEADER” des TEMPLATE cObjects definiert.

Das sollte leicht zu verstehen sein. Was wir jetzt noch tun müssen ist auf Raphaels Vorlage zu verweisen, nämlich "fileadmin/template/main/template_1.html, ähnliche Markierungen für die Teilabschnitte einzufügen und dann das Blindmenü und den Blindtext durch ein dynamisch erzeugtes Menü und den tatsächlichen Seiteninhalt zu ersetzen.

Die Template Auto-parser Erweiterung

Man könnte nun meinen, man müsse nur Raphaels Vorlage bearbeiten. Meiner Erfahrung nach können Sie nicht immer blind auf HTML- Autoren/Editoren vertrauen, d.h. es kann durchaus passieren, dass der HTML-Autor/Editor bei einer späteren Bearbeitung die Kommentar-Tags im Dokument verschiebt oder sogar entfernt. Stellen Sie sich vor Raphael nimmt einige Änderungen an der Vorlage mit Dreamweaver vor und die Markierungen der Teilabschnitte würden still und heimlich verschoben - das Template würde umgehend ausser Funktion gesetzt sein. Ferner ist der Pfad zu den Formatanweisungen des Stylesheets relativ zum Verzeichnis [domain]/fileadmin/template/main - nicht [domain]/, wo der HTML-Inhalt für das Frontend ausgegeben wird. Alle Pfadangabe müssten korrigiert werden.

Dies verlangt eine bessere Lösung. Dazu importieren Sie bitte die Template Auto-parser Erweiterung Extension - als Antwort auf alle Ihre Fragen...

Installation der Extension

Gehen Sie in den Extension Manager und importieren Sie die Erweiterung aus dem OnlineRepository.

img-43

Finden Sie die Erweiterung "automaketemplate” und klicken Sie auf das Importsymbol:

img-44

Dies sollte im Falle des Erfolges erscheinen:

img-45

Gehen Sie zurück, wählen Sie "Available Extensions to Install” und installieren Sie die Extension.

img-46

Nach dem Klicken auf die "Make updates” Schaltfläche gehen Sie zurück in das Template Modul und überprüfen Sie den ObjectBrowser:

img-47

Die Extension sollte ein USER cObject im Objektpfad "plugin.tx_automaketemplate_pi1” eingefügt haben, wie Sie oben sehen. Dieses cObject kann nun anstelle des FILE cObjects verwendet werden, um Raphaels Template einzulesen, die Markierungen automatisch einzufügen und die Pfade anzupassen.

Konfiguration des Template Auto-parsers

Wie für jede Extension, die wir nutzen möchten, können wir das Handbuch auf typo3.org zu Rate ziehen. Klicken Sie auf diesen Link und Sie erhalten um eine Tabelle mit den Eigenschaften dieses cObjects einzusehen .

Um Ihnen zu verdeutlichen, was der Template Auto-parser macht, füge ich hier die Ausgabe des Plugins als einzigenInhalt ein und werde danach das Plugin so konfigurieren, dass es den üblichen Kopf- und Fußbereich nicht ausgeben wird.

Hier das Setup-Feld des Template Datensatzes:

# Configuring the Auto-Parser:
plugin.tx_automaketemplate_pi1 {
    # Read the template file:
  content = FILE
  content.file = fileadmin/template/main/template_1.html

    # Here we define which elements in the HTML that
    # should be wrapped in subpart-comments:
  elements {
    BODY.all = 1
    BODY.all.subpartMarker = DOCUMENT_BODY

    HEAD.all = 1
    HEAD.all.subpartMarker = DOCUMENT_HEADER
    HEAD.rmTagSections = title

    TD.all = 1
  }

    # Prefix all relative paths with this value:
  relPathPrefix = fileadmin/template/main/
}


# Default PAGE object:
page = PAGE
page.typeNum = 0
page.config.disableAllHeaderCode=1

page.10 =< plugin.tx_automaketemplate_pi1

img-48 img-49 Sichern sie das Template und rufen Sie das Frontend auf. Sie sollten eine exakte Darstellung vonfileadmin/template/main/template_1.html sehen:"Na und...?”werden Sie denken. Aber das ist, wenn Sie mal in den Quellcode schauen, schon genial:

Zwei wichtige Dinge sehen Sie dort:

  • Eine Menge von Abschnitten des Template-Datensatzes wurden automatisch in Teilabschnitte gegliedert! ( 1u. 2)
  • Allen relativen Links/Verweisen wurde der Pfad "fileadmin/template/main/” vorangestellt.( 3)

Dies geschah weil der Auto-parser dazu angewiesen wurde "elements” wie folgt zu behandeln:

...
  elements {
    BODY.all = 1
    BODY.all.subpartMarker = DOCUMENT_BODY

    HEAD.all = 1
    HEAD.all.subpartMarker = DOCUMENT_HEADER
    HEAD.rmTagSections = title

    TD.all = 1
  }
...

("Elements” sind alle Tags, die von einem Start- und Endtag eingeschlossen sind, wie z.B. beim <td> Tag.Tags ohne Endtag, wie z.B. <img>), müssen mit der "single” Eigenschaft des Template Auto- parsersdefiniert sein.

Die Konfiguration dieser Elemente bedeutet also, dass

  • a) das Element <body> sollmit der Markierung "###DOCUMENT_BODY###” als Teilabschnitt gekennzeichnet werden.soll
  • b) das Element <head>sollmit der Teilabschnittsmarkierung "###DOCUMENT_HEADER###” umgeben werden. soll. Weiterhin sollen alle <title> Bereiche gelöscht werden. (Wir möchten nicht den Titel von Raphaels Vorlage auf allen unseren TYPO3-Seiten).
  • c) Alle <td> Elemente, die gefunden wurden sollen markiert werden, solange aber keine Unterabschnitte definiert sind, werden nur <td>-Tags mit einem "id”- oder "class”-Attribut bearbeitet und mit einer Unterabschnittsmarkierung versehen. So wird der Tag <td id ="menu_1">den Inhalt aufnehmen und von den Unterabschnittsmarkierunge n"<!--###menu_1###-->...<!--###menu_1###-->” umschlossen.

Was machen wir nun damit?

Die Antwort lautet, dass der Auto-parser es Raphael erlaubt, auf modernen CSS-Techniken basierte Templates mit bewussten Gebrauch von id- und class-Attributen zu erstellen. G leichzeitigdienen diese Attribute als "Markierungen” für TYPO3, um Teile der Vorlage des Templates durch dynamischen Inhalt zu ersetzen. Einfach für Raphael, den Designer, klarer für Benoit, den Entwickler, und gut für Picoutos Finanzen, da für die Umwandlung und manuelle Anpassung der Vorlagen weniger Zeit benötigt wird.

Alles zusammensetzen

Schauen Sie sich folgende Abbildung an. Das ist, was wir machen möchten:

img-50

Die Template-Datei wird vom Auto-parser gelesen, die Ausgabe wird an das TEMPLATE cObject weitergeleitet, welches die Unterabschnitte ersetzt und letztendlich werden die Body- und Headerabschnitte der TYPO3-Seite eingefügt.

Dies wird über das unten gezeigte TypoScript erledigt, das in das Setup-Feld des Template Datensatzes eingegeben wird. Es ist ein längeres Listing, aber nehmen Sie sich die Zeit es zu verstehen:

# Configuring the Auto-Parser for main template:
plugin.tx_automaketemplate_pi1 {
    # Read the template file:
  content = FILE
  content.file = fileadmin/template/main/template_1.html

    # Here we define which elements in the HTML that
    # should be wrapped in subpart-comments:
  elements {
    BODY.all = 1
    BODY.all.subpartMarker = DOCUMENT_BODY

    HEAD.all = 1
    HEAD.all.subpartMarker = DOCUMENT_HEADER
    HEAD.rmTagSections = title

    TD.all = 1
  }

    # Prefix all relative paths with this value:
  relPathPrefix = fileadmin/template/main/
}


# Main TEMPLATE cObject for the BODY
temp.mainTemplate = TEMPLATE
temp.mainTemplate {
    # Feeding the content from the Auto-parser to the TEMPLATE cObject:
  template =< plugin.tx_automaketemplate_pi1
    # Select only the content between the <body>-tags
  workOnSubpart = DOCUMENT_BODY

    # Substitute the ###menu_1### subpart with some example content:
  subparts.menu_1 = TEXT
  subparts.menu_1.value = HELLO WORLD - MENU

    # Substitute the ###content### subpart with some example content:
  subparts.content = TEXT
  subparts.content.value = HELLO WORLD - CONTENT
}


# Main TEMPLATE cObject for the HEAD
temp.headTemplate = TEMPLATE
temp.headTemplate {
    # Feeding the content from the Auto-parser to the TEMPLATE cObject:
  template =< plugin.tx_automaketemplate_pi1
    # Select only the content between the <head>-tags
  workOnSubpart = DOCUMENT_HEADER
}




# Default PAGE object:
page = PAGE
page.typeNum = 0

# Copying the content from TEMPLATE for <body>-section:
page.10 < temp.mainTemplate

# Copying the content from TEMPLATE for <head>-section:
page.headerData.10  < temp.headTemplate

img-51 Das führt dann zu dieser Baumstruktur.

hello world - Menü

Wie Sie sehen, werden die cObjects "temp.mainTemplate” und "temp.headTemplate” an Ihre jeweilige Position im Objektbaum kopiert, da jedes dieser cObjects eine Referenz auf das cObject USER des Template Auto-parser Plugins beinhaltet.

Beachten Sie bitte, dass der Objektpfad "page.headerData” eine numerische Liste der Content Objects ist, die den Inhalt für den <head>-Bereich der Seite definiert.

Ergebnis

Das Ergebnis sieht dann so aus:

img-52

Beachten Sie, dass die Bereiche des Menüs und des Inhaltes mit den Inhalten der cObjects TEXT ersetzt wurden, die nur zum Testen dienten.

Der HTML-Quellcode sieht jetzt folgendermaßen aus:

img-53

Der <head> Bereich ist ohne <title> Tag eingefügt worden.

Der <body> Bereich mit dem ersetzten Inhalt eingefügt.

Die Unterabschnitte ###header### und ###footer### wurden nicht ersetzt, da sie im TEMPLATE cObject "temp.mainTemplate” nicht definiert wurden!Das ist also kein Fehler.

Die Unterabschnitte ###menu_1### und ###content### wurden richtig ersetzt, da das TEMPLATE cObject "temp.mainTemplate” dafür konfiguriert war.

Zusammenfassung

TYPO3 hat aus Raphaels Vorlage automatisch den Inhalt für den <head> und <body> Bereich extrahiert, hat die relativen Pfade für die Grafiken, Links, Formulare und Formatvorlagen angepasst, hat den dynamischen Inhalt eingefügt, sowohl im <head> als auch im <body> Bereich der ausgegebenen Seite.

Der grundlegende Rahmenkonstrukt (Framework) ist jetzt betriebsbereit - wir müssen nur noch etwas dynamischen Inhalt hinzufügen, und zwar für das Menü und den Seiteninhalt! Dies geschieht am effektivsten mit TypoScript cObjects um die Menü- und Inhaltselemente zu generieren.

Das Menü erstellen

Das zweistufige Menü auf der linken Seite des Templates muss dynamisch erstellt werden um die Seitenstruktur des Backends wiederzugeben. Obwohl uns Raphael eine gute und klare Vorlage mit einfachen Bezeichnern für die Menüeinträge erstellt hat, ist es nicht die beste Lösung, einfach diese zu verwenden und diese Bereiche vom Auto- parser als Teilabschnitte extrahieren zu lassen. Stattdessen sollten wir dies explizit programmieren. Das bedeutet, dass Mr. Benoit Raphaels Vorlage manuell überprüfen muss. Dabei muss er sorgfältig herausfinden, was ein einzelner Menüeintrag enthält und dann diese Teile herausfiltern und dazu benutzen, das Objekt für die Generierung des Menüs einzurichten. Das bedeutet desweiteren, dass Raphael die zugrunde liegende Struktur nicht mehr verändern kann, ohne Benoit diese Änderungen mitzuteilen. Benoit muss dann diese Änderungen am Templatedatensatz entsprechend vornehmen. Aber wenn Raphael seine Arbeit ordentlich gemacht hat wird dies nicht nötig sein. Die CSS Formatvorlage sollte dann für alle Änderungen am Design genutzt werden.

Seiteninhalteeinfügen

Der beliebteste Weg, Seiteninhalte TYPO3 zu verwalten, ist Inhaltselemente in der Tabelle tt_content zu erstellen. Tatsächlich kenne ich Niemandem der dieses Konzept nicht verwendet,da es so flexibel, leistungsfähig und einfach einzubinden ist. Jedoch könnte dieses Konzept möglicherweise mit Ihren Vorstellungen von der Einbindung strukturierter Inhalte in HTML- Templates kollidieren.

Inhaltselemente haben zahlreiche vordefinierte Typen (Text, Text mit Bild, Listen, Eingabefeldern usw.) undein statisches Template mit vordefinierten TypoScript wird für gewöhnlich ohne weiteres Konfigurieren diese Elemente für Sie generieren. Das ist wirklich genial! Da Inhaltselemente einen bestimmten Typ haben und jeder Typ zusätzliche Optionen, ist es unmöglich Inhaltselemente mit dem festen Konzept einer HTML-Vorlage zu generieren. Das passt einfach nicht zusammen und Sie werden das erkennen, wenn Sie etwas mehr damit experimentiert haben. Folglich werden mit PHP-Funktionen kombinierte cObjects genutzt, um Inhalte mit komplexen Bedingungen zu generieren.

Da wir keine Inhaltselemente durch die Verwendung von HTML-Templates darstellen können, wie gehen wir also in diesem Fall vor? Indem Sie die neueste Herangehensweise zur Darstellung von Inhaltselementen nutzen, die Extension "css_styled_content”. Hiermit wird der gesamte Inhalt in einfachen HTML-Elementen eingebunden - und das Festlegen der Formatvorgaben bleibt Ihrer externen CSS-Formatvorlage überlassen.

Schauen wir, wie das geht. Zuerst erstellen wir ein Inhaltselement:

Ein Inhaltselement

Im Listenmodul klicken Sie bitte auf das Icon der Seite "License C”und wählen dann "Neu”. Im rechten Frameklicken Sie dann auf den Link des Assistenten fürden Seiteninhalt:

img-58

Wählen Sie "Text mit rechts liegendem Bild” und dann die Spalte"Normal":

img-59

Nachdem Sie den Inhalt eingegeben und gespeichert haben sollten Sie folgende Ausgabe sehen:

img-60

Jetzt haben wir auch ein Inhaltselement auf der Seite "LicenseC” verfügbar:

img-61

Einfügen eines statischen Templates

Um das Inhaltselement anzeigen zu lassen, müssen wir ein statisches Template einfügen, welches die vielen hundert Zeilen TypoScript-Code für die spätere Ausgabe erstellt. Dazu ist der gesamte Template- Datensatz zu bearbeiten.

Zuerst müssen Sie natürlich die Extension "css_styled_content” installieren.

img-62

Klicken Sie auf das Installationssymbol und bestätigen Sie die Änderungen auf der nächsten Seite.

Zurück zum Template: Im Template Modul klicken Sie auf diesen Link:

img-63

Dann sollte der "CSS Styled Content” als "static file” im Bereich "Include Static (from extensions)” verfügbar sein:

img-64

Klicken Sie darauf und sichern Sie das Template. Danach wechseln in den "Template Analyzer“ und betrachten dort das Template:

img-65

Der "TemplateAnalyzer” zeigt die Hierarchie der Template-Datensätze und statischen Templates, die im aktuellen "main template record” eingebunden sind. Durch Anwahl des statischen Templates wird dieses vor Generierung des TypoScript-codes im Template-Datensatz "NEW SITE“ eingebunden. Das bedeutet, dass jedes Objekt, das innerhalb von "EXT:css_styled_content/.....” definiert ist, im Template-Datensatz "NEW SITE” benutzt und dort hineinkopiert werden kann. Das werden wir jetzt auch tun, da die statische Vorlage ein Objekt "styles.content.get” enthält. Dabei handelt es sich um ein Inhaltselement, das alle Inhaltselemente aus der Spalte "Normal” der aktuellen Seite auswählt.

Ändern Sie also diesen Teil der Definition des "temp.mainTemplate” Objekts im Template-Datensatz:

...
# Main TEMPLATE cObject for the BODY
temp.mainTemplate = TEMPLATE
temp.mainTemplate {
    # Feeding the content from the Auto-parser to the TEMPLATE cObject:
  template =< plugin.tx_automaketemplate_pi1
    # Select only the content between the <body>-tags
  workOnSubpart = DOCUMENT_BODY

    # Substitute the ###menu_1### subpart with dynamic menu:
  subparts.menu_1 < temp.menu_1

    # Substitute the ###content### subpart with some example content:
  subparts.content < styles.content.get
...

Nach einem Aktualisieren des Frontends im Browsers sollte die Seite "LicenseC” anschließend so aussehen:

img-66

Und der HTML-Quelltext sieht dann so aus:

img-67

Anscheinend wurde die Überschrift des Inhaltselements in <h1> Tags eingeschlossen generiert. Wenn Sie einen anderen "Layout”-Typ wählen, kann dies auch <h2> (für Layout 2) sein.

Jede Zeile des Textes im Body wird in mit <p> Tags eingeschlossen und erhält die Zuweisung der Klasse "bodytext“. So können Sie die Darstellung von Seiteninhalten über Ihre Stylesheet-Formatvorlage steuern. Beachten Sie bitte wie Raphael bereits schon den Blindtext in der Template-Datei unter Verwendung von "<p class="bodytext">” Tags gestaltet hat!

Jedes eingefügte Inhaltselement erhält einen <a> Tag, welcher als Wert des Attributes name seine uid beinhaltet. Dieser Ankerpunkt kann zum direkten Aufruf einer bestimmten Position innerhalb der Seite genutzt werden.

Dies hat das HMENU Objekt beim Aufbau des zweistufigen Menüs eingefügt. Beachten Sie auch, wie der Link automatisch auf die richtige Seite verweist und wie eine zusätzliche "onFocus” Routineeingefügt ist.

Der Objektbaum?

Was haben wir jetzt durch das Kopieren von diesem angeblichen Inhaltselement "styles.content.get” wirklich in den Objektbaum eingefügt? Schauen wir im ObjectBrowser nach:

img-68

Hier sind zwei interessant Punkte:

Der Objektpfad "styles.content.get” beinhaltete offensichtlich ein cObject vom TypCONTENT.Wenn wir uns die Attribute anschauen, sieht es danach aus, dass dieses cObject Datensätze aus der Tabelle "tt_content” auswählt und sie nach dem Feldeintrag "sorting” geordnet ausgibt. Für weitere Informationen zum CONTENT cObject folgend sie diesem Link .

Desweiteren wurde ein komplett neues ToplevelObject(TLO) definiert-"tt_content”, Standardmäßig nutzt das cObject CONTENT dieses TLO (ebenfalls als cObject definiert) um die Ausgabe der gefundenen Datensätze zu generieren (1). Wie wir sehen, wird das "tt_content” TLO als USER cObject definiert, das eine PHP-Funktion der "css_styled_content” Extension aufruft - dafür haben wir ja auch diese Erweiterung installiert. Für weitere Einzelheiten schauen Sie bitte in die `Dokumentation zur "css\_styled\_content” Extension <http ://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=170&cHash=97866c2553 >`_ .

Die ganz Neugierigen können auch mal in die Klasse "tx_cssstyledcontent_pi1” schauen und die dahinter steckende Logik betrachten. Hier dazu ein Ausschnitt aus der Funktion main():

   function main($content,$conf)   {
                $this->conf = $conf;

                // This value is the Content Element Type - determines WHAT kind of element to render...
                $CTypeValue = (string)$this->cObj->data["CType"];
                $content="";
                switch($CTypeValue)     {
                        case "header":
                                $content = $this->getHeader().$this->render_subheader();
                        break;
                        case "bullets":
                                $content = $this->getHeader().$this->render_bullets();
                        break;
                        case "table":
                                $content = $this->getHeader().$this->render_table();
                        break;
                        case "text":
                                $content = $this->getHeader().$this->render_text();
                        break;
                        case "image":
                                $content = $this->getHeader().$this->render_image();
                        break;
                        case "textpic":
                                $content = $this->render_textpic();
                        break;
...

XHTML Konformität

Wenn Sie XHTML konforme Webseiten erstellen möchten, ist auch das mit TYPO3 möglich. Die Version 3.6.0 von TYPO3 zielt darauf ab, XHTML- Konformität so weit als möglich zu integrieren (Level: XHTML transitional).

In diesem Tutorial müssen wir sicherstellen, dass die HTML-Vorlage mit XHTML konform ist. Das ist der erste Schritt und darauf müssen Sie achten.

Der nächste Schritt ist dafür zu sorgen, dass TYPO3 den XHTML Dokumententyp ausgibt. Dies wird durch eine einfache Zeile im Setup- Feld des Haupttemplate-Datensatzes erreicht:

page.config.doctype = xhtml_trans

Die Menüs müssen natürlich auch entsprechend konform sein. Zum jetzigen Zeitpunkt werden Zeichen wie "&” auch als solche ausgegeben. Das sollte vermieden werden. In den TypoScript-Code für das Menü sollten diesevier Zeilen (in rot dargestellt) eingefügtwerden:

# Menu 1 cObject
temp.menu_1 = HMENU
  # First level menu-object, textual
temp.menu_1.1 = TMENU
temp.menu_1.1 {
    # Normal state properties
  NO.allWrap = <div class="menu1-level1-no"> | </div>
  NO.stdWrap.htmlSpecialChars = 1
    # Enable active state and set properties:
  ACT = 1
  ACT.stdWrap.htmlSpecialChars = 1
  ACT.allWrap = <div class="menu1-level1-act"> | </div>
}
  # Second level menu-object, textual
temp.menu_1.2 = TMENU
temp.menu_1.2 {
    # Normal state properties
  NO.allWrap = <div class="menu1-level2-no"> | </div>
  NO.stdWrap.htmlSpecialChars = 1
    # Enable active state and set properties:
  ACT = 1
  ACT.stdWrap.htmlSpecialChars = 1
  ACT.allWrap = <div class="menu1-level2-act"> | </div>
}

Dadurch wird gewährleistet, das die Bezeichnungen der Menüeinträge die PHP-Funktion htmlspecialchars() durchlaufen, die z.B. "&” in "&amp;” umwandelt.

Danach können Sie die Site z.B. mit Opera 7 testen. Opera besitzt eine angenehme Abkürzung zum Überprüfen der Formatkonformität der Seite.

Klicken Sie dazu mit der rechten Maustaste in die HTML-Seite, unter "Frame” finden Sie dann den Eintrag "Validate source”:

img-69

Opera sendet dann den Quelltext automatisch an die Seite "http://validator.w3.org/” und bei Erfolg sollten Sie folgendes Ergebnis sehen:

img-70

Aufräumarbeiten

Wir haben nun unsere Website fertiggestellt. Mr. Benoit und Mr. Raphael haben ihre Aufgaben erledigt und vielleicht hat Mr. Picouto bereits nun den gesamten Inhalt der einzelnen Unterseiten des Baumes eingefügt. Das wissen wir nicht. Aber die Grundlage der Website selbst ist fertig. Sie basiert auf einer regulären HTML-Datei im Verzeichnis "fileadmin/template/main” und nur das Menü und der Inhalt werden wie benötigt dynamisch ersetzt.

Bessere Struktur des Templates

Das letzte was wir noch tun müssen ist denTemplate-Datensatz etwas besser zu organisieren. Auch wenn nur wenig TypoScript genutzt wird, sehen wir doch, dass der Datensatz schnell groß und unübersichtlich wird. Die Lösung ist eine Reihe von Template-Datensätzen zu erstellen, um diese einzubinden.

Dazu sollten Sie zuerst eine komplett neue Seite auf der untersten Ebene (root level) erstellen. Wählen Sie den Typ "sysFolder” (das bedeutet "Speicherplatz für jedes gewünschte Datenbankelement”)..

Dann erstellen Sie drei Template-Datensätze wie in dieser Abbildung:

img-71

Kreuzen Sie nirgendwo die "Clear” -Anwahlfelder an! Kopieren Sie lediglich nur die passenden Objektdefinitionen "temp.xxxx” des Templates "NEW SITE“ in die drei neuerstellten Template-Datensätze. aus der "NEW SITE” in die neue Vorlage. Die Reihenfolge spielt dabei keine Rolle.

Der nächste Schritt ist diese drei Templates in das Haupt-Template der "NEW SITE” einzubinden. Also bearbeiten Sie das Template von "NEW SITE”.

img-72

Die Reihenfolge ist wichtig: das zuerst aufgeführte Template wird zuerst eingefügt und da der Vorlagensatz "ext: Main TEMPLATE cObject” Kopien von z.B. dem Objekt "temp.menu_1” erstellt, muss dieses dann als letztes eingefügt werden.

Speichern Sie den Template-Datensatz und betrachten Sie die neue Struktur im Template Analyzer:

img-73

Wie Sie sehen können wird erst das statische Template eingebunden, dann die drei "Basisvorlagen” aus unserem Ordner und zum Schluss der Haupttemplatesatz (main template record). Sie können den Titel jeder Vorlage anklicken und darunter deren Inhalt ansehen.

Weitere HTML-Design Betrachtungen

Wie Sie in diesem Abschnitt gesehen haben, können Sie sehr komfortabel das HTML-Template eines Webdesigners implementieren. Volle Rückwärtskompatibilität zur zum ursprünglichen Template ist dabei sichergestellt (da keine Markierungen von Hand in die Vorlage eingefügt werden müssen). Weiterhin werden nur vertraute Techniken wie HTML und CSS genutzt - es werden keine verwirrenden XSLT-Vorlagen benötigt (obwohl Mr. Benoit natürlich auch XSLT für die Ausgabe auf PHP-Ebene hätte nutzen können).

Auch wenn der Designer, Mr. Raphael, fast grenzenlose Freiheit hat, sollte er doch die Grundlagen von statischem und dynamischem Inhalt kennen.

Klarstellen welche Teile dynamisch und welche statisch sind

Mr. Raphael muss in erster Linie verstehen - vermutlich zusammen mit dem ganzen Team - welche Teile der Seite statisch und welche dynamisch sind. Statische Teile bleiben von TYPO3 unberührt. Die dynamischen Teile sollen jedoch mit dem Inhalt ersetzt werden, der aus den Datenquellen innerhalb von TYPO3 kommt.

Wenn dynamische Bereiche erkannt werden, muss Raphael folgendes unternehmen:

  • Dieser Bereich muss von einem einzelnen HTML-Element umschlossen sein, dabei kann es sich um <div>, <td> oder <span> Elemente handeln.
  • Das umschließende Element muss entweder ein id oder class Attribut besitzen, welches das Template Auto-parser plugin finden und in Unterabschnittmarkierungen einschließen muss, z.B. <td id="content"> für die Tabellenzelle, die den Inhalt aufnehmen soll.

img-74

Es ist völlig in Ordnung den Blindtext in der Vorlage zu belassen - dieser wird ohnehin schließlich durch die dynamischen Teile ersetzt.

Vereinfachen Sie die Darstellungsformatierung, nutzen Sie CSS Formatvorlagen

Wir schreiben das Jahr 2004 und es wird Zeit dem <font> Tag und den bgcolor-Attributen auf Wiedersehen zu sagen. Packen Sie das alles in eine externe Formatvorlage. Für den Einsatz eines CMS wird dadurch erreicht so viele externe Techniken wie irgend möglich nutzen zu können und nur soviel CMS-spezifische Technologien (wie TypoScript Template-Datensätze) wie wirklich benötigt zu verwenden.

In diesem Abschnitt dieses Tutorials war das beste Beispiel hierfür das zweistufige Menü:

<!-- Menu table cell: -->
     <td id="menu_1">
             <div class="menu1-level1-no"><a href="#">Menu item 1</a></div>
             <div class="menu1-level1-no"><a href="#">Menu item 2</a></div>
             <div class="menu1-level1-act"><a href="#">Menu item 3 (act)</a></div>
             <div class="menu1-level2-no"><a href="#">Level 2 item</a></div>
             <div class="menu1-level2-no"><a href="#">Level 2 item</a></div>
             <div class="menu1-level2-act"><a href="#">Level 2 item (act)</a></div>
             <div class="menu1-level1-no"><a href="#">Menu item 2</a></div>
     </td>

Schauen wir uns ein einzelnes Element an (oben rot dargestellt). Es hätte auch so oder ähnlich aussehen können:

<!-- Menu table cell: -->
     <td id="menu_1">
                     <!-- Menu item level 1, begin -->
             <table border="0" cellpadding="0" cellspacing="0" width="95%"><tr>
               <td bgcolor="#eeeeee"><font face="verdana" size="2">
                       <a href="#" class="menu1-items">Menu item 1</a>
               </font></td>
       </tr>
       <tr>
               <td><img src="gray_dotted_line.gif" width="180" height="1" alt=""/></td>
       </tr>
       </table>
                     <!-- Menu item level 1, end -->
             ...
     </td>

Jetzt denken Sie wieder zurück an unser TMENUITEM Object im Template- Datensatz. Es war so definiert, dass es Elemente ausschließlich mit diesem einfachen <div> Bereich umschließen sollte:

temp.menu_1.1 {
    # Normal state properties
  NO.allWrap = <div class="menu1-level1-no"> | </div>
...

... und ja, Sie haben es erraten: mit der oben genannten Implementierung würden wir die Elemente in etwa wie folgt eingeschlossen haben müssen:

temp.menu_1.1 {
    # Normal state properties
  NO.allWrap (
                  <table border="0" cellpadding="0" cellspacing="0" width="95%"><tr>
                            <td bgcolor="#eeeeee"><font face="verdana" size="2">
                                     |
                            </font></td>
                    </tr>
                    <tr>
                            <td><img src="gray_dotted_line.gif" width="180" height="1" alt=""/></td>
                    </tr>
                    </table>
)
...

Aber auch das reichte noch nicht. Sie müssten noch den Klassennamen für den <a> Tagum eine weitere Eigenschaft des "No“ Status Objektes sowie den Pfad der Grafik der grau gepunkteten Linie ergänzen- irgendwas mit"fileadmin/template/main/”.

Finger weg von row/colspans!

Das ist der Nummer Eins Killer für dynamischen Inhalt - colspans im dynamischen Inhalt zu benutzen! Das wird dadurch geradezu ausgeschlossen. Zum Verständnis schauen Sie sich diese Implementierung des Menüs an:

     <tr>

              <!-- Menu table cell: -->
              <td class="menu1-level1-no"><a href="#">Menu item 1</a></td>

              <!-- Page Content Area table cell: -->
              <td id="content" rowspan="7">
                      . . .
              </td>
      </tr>
      <tr>
        <td class="menu1-level1-no"><a href="#">Menu item 2</a></td>
</tr>
<tr>
        <td class="menu1-level1-act"><a href="#">Menu item 3 (act)</a></td>
</tr>
<tr>
        <td class="menu1-level2-no"><a href="#">Level 2 item</a></td>
</tr>
<tr>
        <td class="menu1-level2-no"><a href="#">Level 2 item</a></td>
</tr>
<tr>
        <td class="menu1-level2-act"><a href="#">Level 2 item (act)</a></td>
</tr>
<tr>
        <td class="menu1-level1-no"><a href="#">Menu item 2</a></td>
</tr>

Das ist nahezu unmöglich zu implementieren. Der erste Menüeintrag ist in einer Tabellenzeile zusammen mit der Zelle für den Inhalt. Die restlichen sechs Menüeinträge befinden sich in eigenen Zeilen. Weiterhin benötigt die Zelle mit dem Inhalt ein colspan="7", um alle Zeilen des Menüs zu umspannen!

Aus technischer Sicht ist dies ein sehr schlechtes Design, da:

die Beschreibung des Menüs auf verschiedene Bereiche des HTML-Codes verteilt ist

es eine Abhängigkeit zwischen dem colspan Attribut und der (dynamischen!) Anzahl der Menüeinträge gibt.

Designer sollten solches Design vermeiden. Stattdessen sollten Designer wie Mr. Raphael lernen, die Beschreibung für dynamische Elemente wie Menüs so zu erstellen, dass sie leicht reproduzierbar sind. Hier ein gutes Beispiel:

Von unserer aktuellen Vorlage:

<!-- Menu table cell: -->
     <td id="menu_1">
             <div class="menu1-level1-no"><a href="#">Menu item 1</a></div>
       <div class="menu1-level1-no"><a href="#">Menu item 2</a></div>
       <div class="menu1-level1-act"><a href="#">Menu item 3 (act)</a></div>
             ...
     </td>

Alternativ mit einer Tabelle:

<!-- Menu table cell: -->
     <td id="menu_1">
             <table border="0" cellspacing="0" cellpadding="0">
                     <tr><td class="menu1-level1-no"><a href="#">Menu item 1</a></td></tr>
               <tr><td class="menu1-level1-no"><a href="#">Menu item 2</a></td></tr>
               <tr><td class="menu1-level1-act"><a href="#">Menu item 3 (act)</a></td></tr>
                       ...
             </table>
     </td>

Die Beispiele könnten auch noch komplexer sein, ähnlich dem obigen, das jedes Elementineiner eigenen Tabelle einschloß. Entscheidend ist aber nicht die Menge an HTML pro Eintrag, entscheidend ist die Reproduzierbarkeit.

Mr. Raphael sollte diesen Umständen Rechnung tragen, damit Mr. Benoit nicht Stunden damit verbringen muss eine mangelhafte HTML-Struktur zu implementieren. Eine schnelle Umsetzung des Projektes als Ergebnis der symbiotischen Zusammenarbeit von Raphael und Benoit könnte auch Mr. Picouto glücklich machen - vielleicht lädt er sie ja zum Mittagessen ein!

Schlussbemerkung:

Zu dieser Anleitung gibt es noch einen Teil 2 und 3 in einem anderen Dokument . Diese Teile - besonders Teil 2 - sind eine Fortsetzung von diesem (Teil 1) und gehen ebenfalls von dem Team mit Raphael, Benoit und Picouto aus. Bevor Sie aber weitermachen bedenken Sie bitte, dass Sie dazu zusätzliche Voraussetzungen benötigen. In der Zwischenzeit wäre essicherlich nicht falsch, wenn Sie ihr jetziges Wissen anwenden, andere Anleitungen lesen und somit ein höheres Niveau erreichen, speziell in den technischen und die Entwicklung betreffenden Bereichen.

img-75 Moderne Templateerstellung, Teil 1 (MTB_de/1) - 50