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.

Training voor Ontwikkelaars

Author:Kasper Skårhøj
Created:2002-11-01T00:32:00
Changed:2006-01-20T10:33:25
Author:Ing. Hans A. Olthoff
Email:hans@alternet.nl
Info 3:
Info 4:

Training voor Ontwikkelaars

Bewerkt door Ing.Hans A. Olthoff, <hans@alternet.nl>

Meer informatie:

Ing. Hans A. Olthoff

AlterNET Internet B.V.

Archimedesstraat 2

3316 AB Dordrecht

T (078) 635 1200

F (078) 635 2010

www.alternet.nl

This document is published under the Open Content License

available from http://www.opencontent.org/opl.shtml

The content of this document is related to TYPO3

- a GNU/GPL CMS/Framework available from www.typo3.com

Inhoudsopgave

Training voor Ontwikkelaars 1

Met dank aan: 2

Introductie 3

Waar gaat deze training over? 3

Deel 1: Integratie van een HTML template 4

Implementatie van een CMS 4

De HTML template 6

Basiskennis TEMPLATE cObject 10

Het template Auto-parser Extension 14

We combineren alles 22

Het menu aanmaken 25

Pagina content invoegen 30

Een XHTML compatibele website 39

Nu alles wat netter 41

Enkele HTML ontwerp overwegingen 42

Tenslotte 47

Met dank aan:

Dankbaar heb ik uitgebreid gebruik gemaakt van de volgende brondocumenten:

  • Getting Started, Engelstalige handleiding geschreven door Kasper Skårhøj
  • Handbuch für Redakteure, Duitstalige handleiding geschreven door Werner Altmann
  • MTB/1, Engelstalige handleiding geschreven door Kasper Skårhøj

Deze documenten zijn gepubliceerd onder de voorwaarden van de Open Content License.Meer informatie hierover is te vinden op http://www.opencontent.org/opl.shtml

De inhoud van deze training is gerelateerd aan TYPO3, een GNU/GPL gelicenseerd CMS/Framework,beschikbaar gesteld op www.typo3.com

De hoofdstukken uit de brondocumenten zijn opnieuw gerangschikt, zodat ze beter aansluiten bij de opleidingsbehoeften van mensen die aan de slag willen met TYPO3. Op basis van de brondocumenten is door AlterNET een drietal Nederlandstalige TYPO3 Trainingen beschikbaar gesteld om de kennis op het gebied van TYPO3 te vergroten.

Dit zijn:

  • TYPO3 Training voor Editors
  • TYPO3 Training voor Webmasters
  • TYPO3 Training voor Ontwikkelaars (dit document)

Veel leesplezier!

Ing. Hans A. Olthoff

hans@alternet.nl

Introductie

Waar gaat deze training over?

Deze training gaat over een software extensie met de naam doc_tut_templselect .Deze extensie beschrijft hoe je van nul af aan een website kan opbouwen met behulp van een HTML-template die gebaseerd is op het open source Content Management Systeem TYPO3.

Deze training is bedoeld voor ontwikkelaars op het niveau van de beginnende ontwikkelaar.

De website die je gaat bouwen komt er als volgt uit te zien:

img-1

De site bestaat uit een dynamsch opgebouwd menu (links) en dynamsch opgebouwd pagina’s met inhoud (rechts) - de rest is opgebouwd uit statisch design uit de HTML template.

Doel

Het doel van de training is het aanleren van de nieuwste technieken voor het bouwen van een website in TYPO3. Met behulp van deze training kun je snel ervaring opdoen met het systeem en komen alle facetten aan bod die je nodig hebt om een website met TYPO3 te bouwen.

In deze training proberen we een overzicht te geven van wat er mogelijk is, en zelfs dat is slechts een basis van wat er nog meer mogelijk is. TYPO3 is een compleet en complex systeem. Je moet dus enige tijd investeren om er mee overweg te kunnen.

Deel 1: Integratie van een HTML template

Implementatie van een CMS

Voor het maken van een website met een CMS zijn meer componenten nodig dan voor een website die volledig bestaat uit statische HTML bestanden. De structuur van een CMS zorgt ervoor dat de content en de HTML opmaak apart worden opgeslagen. Sommige CMSen slaan de content op in XML bestanden, andere CMSen gebruiken een relationele database. Elk heeft z'n technische voor- en nadelen, maar het principe blijft hetzelfde: "content en kleur apart".

Als TYPO3 webpagina's genereert, combineert de frontend engine de content van het bronbestand (database) zonder opmaak met een HTML template dat de opmaak volledig definieert. In dit proces is het template record het besturingselement dat instructies geeft aan de frontend engine over hoe de combinatie moet worden uitgevoerd.

Deze tekening illustreert hoe het template record functioneert als besturingselement - het “programma” - voor de frontend engine die vervolgens de content in de database vindt, het template leest en de content op de juiste plaatsen van het template invoegt met als output een mooie webpagina!

img-2

Op de meeste websitebureaus werkt een aantal mensen samen in een groep om een website te maken. Een dergelijke groep bestaat uit een grafisch ontwerper, een ontwikkelaar en een inhoudelijke deskundige (die in ieder geval in eerste instantie de content verzorgt). Ieder van hun beschikt over verschillende vaardigheden en zal aan andere aspecten van de productie van de site werken:

img-3

In het bovenstaande diagram worden de verschillende componenten van een door CMS aangestuurde website aan een lid van het webteam toegewezen:

  • Dhr. Raphaël is de kunstenaar. Raphaël is erg bedreven in grafische vormgeving, hij kent Photoshop, hij weet alles van Dreamweaver, CSS stylesheets, HTML etc. Raphaël kan toveren met flash- filmpjes. Maar dat kan Raphaël niet met PHP, TypoScript, SQL en andere technische kwesties. Raphaël maakt dus de HTML templates voor ons!
  • Dhr. Benoit is een ontwikkelaar. Hij houdt van bits en bytes, hij houdt van compiler directives, regular expressions, logica, PHP, SQL en binnenkort kan TypoScript aan dit lijstje worden toegevoegd. Hoezeer dhr. Benoit ook vertrouwt op zijn lekker zittende jeans, net als voor iedere programmeur sinds ontwerpen “in” is, is het verzorgen van de typografie, het combineren van kleuren en bruikbaarheid niet zijn métier. Daarom zorgt Benoit voor de TypoScript configuratie in de template bestanden.
  • Dhr. Picouto verzorgt de content. Hij doet de marketing en hij is diep onder de indruk van het werk van zowel Raphaël als Benoit, die in zijn ogen wonderen verrichten door ideeën van papier naar het beeldscherm over te brengen. Picouto zelf is noch een programmeur noch een ontwerper, maar hij wil een boodschap overbrengen. En dankzij het TYPO3 backend kan hij zijn eigen content laten weergeven terwijl zijn technische kennis beperkt kan blijven tot een tekstverwerker.

Aangezien we dus te maken hebben met drie individuen met unieke vaardigheden, kunnen we concluderen dat het produceren van een CMS geen eitje is, tenzij je op alle drie de bovengenoemde gebieden deskundig bent: zowel Grafisch, als Technisch als op het gebied van Marketing. Binnen een webteam is dit gewoonlijk wel het geval, maar voor individuen geldt dit meestal niet. Je bent dus gewaarschuwd. (Als je kennis hiervoor ontoereikend is, zul je ofwel heel veel moeten leren, of gewoon Standaard Templates gebruiken. Het ontwerp hiervan ligt vast, maar met wat beperkte configuratie aanpassingen kun je ze geschikt maken. Hier wordt in deze training verder niet op ingegaan.)

In dezetrainingzal ik je laten zien hoe Raphaël, Benoit en Picouto samen aan een moderne website kunnen werken, terwijl ieder teamlid binnen zijn eigen domein met zijn favoriete programma’s kan doen en laten wat hij wil, met als resultaat een gemakkelijk te onderhouden website waarin elk mogelijk gewenst ontwerp kan worden gerealiseerd. Dankzij TYPO3.

Kennisniveau

Gemiddelde webdesigner met HTML/CSS achtergrond, niet noodzakelijkerwijs een webprogrammeur.

Om dit onderdeel van detrainingte kunnen voltooien, moet je goed kunnen werken met HTML en CSS. Je moet bovendien een werkende TYPO3-database hebben met het boomdiagram dat in een eerder hoofdstuk van dezetrainingis aangemaakt. Tenslotte kan het noodzakelijk zijn programmeerconcepten te beheersen voor een volledig begrip. Maar maak je geen zorgen - alles wat je moet doen, wordt je duidelijk verteld- bestudeer het materiaal aandachtig, en neem de tijd om de voorbeelden te begrijpen.

De HTML template

Het webteam heeft net een nieuwe klant - Main Dish & Son - en Raphaël, de kunstenaar, heeft het website template aangemaakt als een gewoon HTML bestand:

img-1

Dit HTML bestand wordt geplaatst onder "fileadmin/template/main/", dat volgt op de het TYPO3 installatiepad (het oefenpakket).

Om de opdrachten van deze training te kunnen maken, moet je nu de inhoud van de map "part1/" van de extension van deze training naar "fileadmin/template/main/" kopieren. Als je de training extension "doc_tut_templselect" nog niet hebt geïmporteerd van TER, dan moet je dat nu doen!

Bovendien, als je het vorige deel over TypoScript hebt overgeslagen, zorg dan dat je tenminste het in het hoofdstuk “Een paginastructuur maken” beschreven boomdiagram hebt aangemaakt en wellicht een blanco template record .

img-4

Zo, nu terug naar het werk van Raphaël; hettemplateHTML bestand is eigenlijk niets meer dan een gewone HTML pagina. Maar als TYPO3 dit bestand als eentemplateimporteert, gaat het erom bepaalde onderdelen dynamisch te maken, zoals het menu aan de linkerkant en het gedeelte met voorbeeld content in het midden/rechts.

Als je de broncode van het HTML template bekijkt, dan zie je een eenvoudig XHTML compatibel bestand dat verwijst naar een stylesheet, en dat slechts één tabel gebruikt om de verschillende elementen op de pagina te positioneren:

img-5

We zullen nu wat opmerkingen over dit HTML template maken, en de uitdagingen waar we voor staan:

  • Dit deel van de header van het document moet in onze webpagina worden opgenomen omdat het gebruikte stylesheet hier wordt benoemd.Uitdaging: Wij moeten er voor zorgen dat dit deel van het document eruit wordt gehaald, en in het header deel wordt geplaatst, dat door de frontend engine wordt aangemaakt!
  • Elk menu bestanddeel aan de linkerkant bestaat uit een <div> deel. Aan elk van deze <div> elementen wordt een "class" toegekend. Met behulp van de class naam bepaalt het CSS stylesheet de opmaak van het element.Dit is een hele slimme opzet voor een menu, omdat elk element uit een minimum aantal HTML codes bestaat (goed voor TypoScript implementatie) en gemakkelijk kan worden herhaald (noodzakelijk wanneer het menu dynamisch wordt).Uitdaging: We moeten het hier geleverde voorbeeldmenu vervangen door één dat dynamisch gegenereerd wordt!
  • Dit is wat voorbeeldtekst van Raphaël voor in het template bestand, om een juiste visuele indruk te krijgen. Zie je hoe er in de opmaak <h1> en <p> tags worden gebruikt (gebruikmakend van de class "bodytext")? - Dit is slim, omdat de later door TYPO3 ingevoegde dynamische content deze tags / classen ook voor de opmaak zal gebruiken! (Raphaël moet stiekem toch van te voren wat TYPO3 ervaring hebben opgedaan, hè?)Uitdaging: Wij moeten de voorbeeld content vervangen door een dynamisch gegenereerde pagina content.
  • Deze break tag zorgt voor een beetje extra ruimte onder de content, zodat de footer niet te dicht bij de body van de pagina staat.

Tenslotte willen we je er op wijzen dat de tabelcellen met de positie van het menu en van de content, een id attribuut als tag hebben. Deze worden niet alleen door het stylesheet gebruikt! Er zit een slimmigheidje achter dezeid attributen! Maar eerst wat HTML templates theorie:

Basiskennis TEMPLATE cObject

Maak eerst een nieuw bestand aan, fileadmin/template/test.html, met de volgende content:

<!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>

(Dit kun je vinden in de training extension map onder "misc/test.html")

Plaats dit vervolgens in het Setup veld van je template record:

# 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

Hierdoor wordt een cObject van het type "TEMPLATE" op de positie "page.10" gezet. De "template" eigenschap van het template cObject wordt gedefinieerd als een ander cObject van het type "FILE" dat het nieuwe bestand, "fileadmin/template/test.html", leest.:underline:``Hier vindt je eigenschappen van het TEMPLATE cObject **e <http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=2 70&tx_extrepmgm_pi1[tocEl]=373&cHash=109a171b1e>`_` .

Als je nu de veranderingen in het Setup veld opslaat en op frontend drukt, zou je het volgende moeten zien:

img-6

Door in de broncode te kijken, zien we dat in feite het TEMPLATE cObject net het bestand heeft gelezen, en er een ruwe versie van heeft aangemaakt:

img-7

Nu komt het mooie van het template cObject; het leest niet alleen een HTML bestand - het maakt het ons ook mogelijk “subparts” er uit te selecteren en ze te vervangen door dynamische content!

Een subpart wordt gedefinieerd als de content tussen twee soortgelijke marker strings, omgeven door ### en ingesloten door HTML commentaar (dit is optioneel). Het "test.html" bestand heeft twee subparts, het "DOCUMENT_BODY" subpart en het "INSIDE_HEADER" subpart. Zoals je kunt zien zijn de subpart markers ingesloten door HTML commentaar tags en dus niet zichtbaar.

img-8

Probeer nu het Setup veld van het template record als volgt te veranderen:

# 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

Druk op frontend en de HTML broncode zou er als volgt uit moeten zien:

img-9

Dit komt door onze veranderingen in de eigenschappen van het TEMPLATE cObject;

  • De eerste en belangrijkste was dat het TEMPLATE cObject de opdracht kreeg alleen aan het subpart dat door "###DOCUMENT_BODY###" werd gemarkeerd te werken - dus de overbodige header en body tags zijn er uit gehaald!
  • Vervolgens werd het subpart gemarkeerd "###INSIDE_HEADER###" vervangen door de content zoals gegeven door het TEXT cObject, gedefinieerd voor de eigenschap "subparts.INSIDE_HEADER" van het TEMPLATE cObject.

Dit zou vrij gemakkelijk te volgen moeten zijn. Vanaf dit punt hoeven we alleen nog maar het bronbestand naar het template van Raphaël te verwijzen, fileadmin/template/main/template_1.html, soortgelijke subpart markers in te voegen en dan het voorbeeldmenu en de voorbeeld content te vervangen door de dynamisch gegenereerde menu’s en de content elementen van de werkelijke pagina.

Het template Auto-parser Extension

De meest voor de hand liggende keuze is wellicht het template van Raphaël te bewerken. Ik heb echter geleerd dat je er in het algemeen niet op kunt vertrouwen dat een HTML editor HTML commentaar in het document niet verwijdert of verplaatst, als Raphaël het template bestand later verandert. Stel je voor dat Raphaël een paar veranderingen in het template aanbrengt met DreamWeaver en de subpart markers worden onopgemerkt verwijdert - dan werkt het template gelijk niet meer! Bovendien zijn de paden die verwijzen naar het stylesheet en de afbeeldingen in het template van Raphaël relatieve paden ten opzichte van [domain]/fileadmin/template/main/ - not [domain]/, de HTML content zal hier worden geplaatst door de frontend engine van TYPO3! Hierdoor zouden er prefixes nodig voor alle paden!

Dit vraagt om een betere oplossing. Importeer en installeer nu de template Auto-parser extension - het maakt al je dromen waar...

Installatie van de extension

Ga naar de Extension Manager, en importeer de extension vanuit de online repository:

img-10

Zoek de extension "automaketemplate", klik op het import icoon:

img-11

Als het gelukt is, is dit het resultaat:

img-12

Ga terug, selecteer "Available Extensions to Install" en installeer de extension:

img-13

Nadat je op de "Make updates" knop hebt gedrukt, ga je terug naar het template module en controleer je de Object Browser:

img-14

Deze extension zou een USER cObject moeten hebben toegevoegd aan het objectpad "plugin.tx_automaketemplate_pi1", zoals je hierboven kunt zien. Dit cObject kan nu door ons worden gebruikt in plaats van de FILE cObject om het template bestand van Raphaël te lezen en de HTML opmaak automatisch aan te passen en subpaden te corrigeren!

Configuratie van het Template Auto-parser

Net zoals voor elke extension waarover we iets willen weten, moeten we de handleiding voor de extension op typo3.org raadplegen.:underline:``Klik op deze link om de tabel met eigenschappen voor het cObject op te roepen **t <http://typo3.org/do c.0.html?&tx_extrepmgm_pi1[extUid]=154&tx_extrepmgm_pi1[tocEl]=501&cHa sh=2bbdf1c6ca>`_` .

Om heel duidelijk voor je te maken wat het Template Auto-parser doet, zal ik de output van de plugin invoegen als de enige content op de pagina, en zal ik ook het PAGE object "page" configureren om niet de gebruikelijke header en footer content als output te leveren.

Dit is het Setup veld template record content:

# 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

Sla het template op en druk op frontend. Je zou precies moeten zien hoe de fileadmin/template/main/template_1.html er uit ziet:

img-15

img-16 Ja, en...? - denk je. Maar dit is al heel wat en als je naar de broncode kijkt, zul je zien waarom:

Zoals je ziet, zijn er hoofdzakelijk twee dingen gebeurd:

  • Een groot aantal blokken in het template zijn automatisch omgeven door subparts! (1+2)
  • Alle relatieve links/referenties worden voorafgegaan door de prefix "fileadmin/template/main/" (3)

Dit is omdat het template Auto-parser geconfigureerd is om met zulke “elementen” te werken:

...

elements {

BODY.all = 1

BODY.all.subpartMarker = DOCUMENT_BODY

HEAD.all = 1

HEAD.all.subpartMarker = DOCUMENT_HEADER

HEAD.rmTagSections = title

TD.all = 1

}

...

("Elementen” zijn allemaal tags met een aparte tag aan het begin en aan het einde, bijv. de <td> tag. Tags zonder eind tag, bijv. <img>, moeten worden gedefinieerd door de "single property" van het template Auto-parser)

De configuratie van de elementen zegt dus dat

  • a) het element <body> moet worden omgeven door de subpart marker "###DOCUMENT_BODY###"
  • b) het element <head> moet worden omgeven door de subpart marker "###DOCUMENT_HEADER###". Verder dienen <title> bestanddelen te worden verwijderd. (We willen niet dat de <title> tag van het template van Raphaël wordt herhaald op onze TYPO3 pagina’s...)
  • c) Alle gevonden <td> elementen moeten worden omgeven door markers - maar omdat er geen subpart marker waarde is gedefinieerd, worden alleen <td> tags met een "id" of "class" attribuut omgeven door markers en wel door een subpart marker die overeenkomt met de id/class waarde. Daarom zal de content binnenin de tag <td id="menu_1"> worden omgeven door de subpart markers "<!--###menu_1###-->...<!--###menu_1###-->".

Wat hebben we hier nu aan?

Het antwoord hierop is dat Raphaël met de Auto-parser templates kan maken die gebaseerd zijn op moderne CSS stijltechnieken met een bewust gebruik van id en class attributen in de HTML elementen, en tegelijkertijd functioneren die attributen als de “markers” die door TYPO3 worden gebruikt om delen van het template te vervangen door dynamische content! Gemakkelijk voor Raphaël (de ontwerper), minder gedoe voor Benoit (de ontwikkelaar) en goed voor de financiën van Picouto want er wordt minder tijd besteed aan conversies en handmatige codering van templates met subpart markers!

We combineren alles

Bestudeer de onderstaande illustratie. Dit is wat we willen bereiken:

img-17

Het template bestand wordt door de Auto-parser gelezen, de output gaat naar het template cObjecten dat subparts vervangt en wordt uiteindelijk ingevoegd in de body en header bestanddelen van de TYPO3 pagina.

Dit wordt gedaan door het onderstaande TypoScript dat in het Setup veld van jouw template record is ingevoerd. Het is een hele reeks, maar probeer er wat tijd voor uit te trekken om het te begrijpen:

# 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-18 Dit leidt allemaal tot de bovenstaande boomstructuur.

Zoals je ziet zijn de "temp.mainTemplate" en "temp.headTemplate" cObjecten gekopieerd naar hun respectievelijke posities in de objectboom. Voor elk geldt dat er een referentie naar het USER cObject van het template Auto-parser plugin in zit.

Je ziet dat het objectpad "page.headerData" een numerieke serie is van content objecten die de content voor het <head> bestanddeel van de pagina definiëren. Dit is hoe er content wordt ingevoegd tussen de <head> tags van de door TYPO3 gegenereerde pagina’s.

Resultaat

Het resultaat ziet er zo uit:

img-19

Je ziet dat de menu en content gedeeltes zijn vervangen door content van de TEXT cObjecten, die er alleen maar waren als voorbeeld!

De HTML broncode ziet er zo uit:

img-20

Het <head> bestanddeel is ingevoegd, zonder de <title> tag

Het <body> bestanddeel is ingevoegd, content vervanging is uitgevoerd

De ###header_1### en ###footer### subparts werden niet vervangen omdat ze helemaal niet waren gedefinieerd in het "temp.mainTemplate" TEMPLATE cObject! Dit is dus geen fout.

De ###menu_1### en ###content### subparts werden goed vervangen, zoals we hadden verwacht omdat in feite het "temp.mainTemplate" TEMPLATE cObject geconfigureerd was om dit te doen.

Samenvatting

TYPO3 haalt dus automatisch de <head> en <body> content uit het template van Raphaël, corrigeert relatieve paden naar afbeeldingen, links, formulieren en stylesheets, zorgt voor vervanging voor dynamische content en voegt ieder deel in het <head> en<body> bestanddeel van de output page van TYPO3 in.

We hebben nu een functionerende hoofdstructuur - we hoeven alleen nog maar wat dynamische content aan de menu en content delen toe te voegen! TypoScript cObjecten voor menu's en content elementen is het meest efficiënt hiervoor.

Het menu aanmaken

Het “level2” menu aan de linkerkant van het template moet dynamisch gegenereerd worden om de paginastructuur van het backend te weerspiegelen. Alhoewel Raphaël een mooie, schone template voor ons heeft ontworpen met heel eenvoudige HTML opmaak voor de menubestanddelen, is het niet de beste benadering om te proberen deze delen door Auto-parser subparts te laten selecteren; nee, we moeten hier harde codering invoegen! Dit betekent dat dhr. Benoit handmatig in het template van Raphaël moet kijken, zorgvuldig identificeren waar een enkelvoudig menu bestanddeel uit bestaat, dan deze bestanddelen moet selecteren en ze in het template record gebruiken om het object te construeren voor het genereren van het menu. Het betekent ook dat Raphaël de basisstructuur van het menu niet kan veranderen zonder dat Benoit dezelfde veranderingen in het template record doorvoert! Maar als Raphaël het echt slim heeft aangepakt, hoeft dat ook niet; CSS stijlen moeten voor alle visuele effecten worden gebruikt.

Pagina content invoegen

De meest populaire manier om pagina content in TYPO3 te beheersen, is door content elementen aan te maken op een pagina in de tabel tt_content . In feite ken ik niemand die deze benadering niet gebruikt omdat deze zo flexibel, krachtig en gemakkelijk te implementeren is. Maar het kan een tikkeltje botsen met je huidige opvattingen over het gebruik van HTML templates rondom gestructureerde content.

Content elementen hebben talloze vooraf gedefinieerde types (Text, Text w/image, Bulletlist, Table, Login box, etc), en een statisch template met vooraf gedefinieerd TypoScript zal gewoonlijk de elementen “out-of-the-box” voor je verzorgen. Dit is echt geweldig! Omdat content elementen een type hebben en voor elk type vele extra opties, is het onmogelijk om de content elementen te verkrijgen door een vaststaand HTML template per element-type. Het werkt gewoon niet en dat zul je zelf ook ontdekken als je hier een beetje mee gespeelt hebt. Daarom worden er cObjecten in combinatie met PHP-functies gebruikt voor content met complexe condities.

Als we dus de content elementen niet met HTML templates kunnen ontwerpen, hoe dan wel? Als je nu terug gaat naar de laatste benadering voor het verkrijgen van content elementen- dat is de extension "css_styled_content" - dan zal alle content worden omgeven door primitieve HTML elementen - en daarmee worden de ontwerpbeslissingen lekker aan je externe CSS stylesheet overgelaten!

Laten we eens kijken hoe dat werkt. Laten we allereerst een content element aanmaken.

Een content element

In de "List module", klik op het pagina-icoon van de pagina "License C", selecteer vervolgens "New" en klik dan, in het rechter frame, op de content wizard link:

img-25

Selecteer "Text with image to the right" en vervolgens de kolom "Normal":

img-26

Nadat je de content in het element hebt ingevoerd en opgeslagen, zou je ongeveer het volgende moeten zien:

img-27

We hebben nu dus een content element geplaatst op de pagina "License C":

img-28

Een statische template opnemen

Om het content element weer te geven, moeten we een statische template opnemen, dat alle honderden regels TypoScript code levert, die alles voor ons zullen doen. Dit wordt gedaan door het hele template record te bewerken.

Het eerste wat je echter moet doen is de extension "css_styled_content" installeren:

img-29

Je hoeft alleen maar op de "Install" knop te drukken, en op de "accept" knop op de volgende pagina.

(NB: Op het tijdstip van schrijven (januari 2004) is de "CSS styled content" plugin nog NIET af! Het staat in de topdrie van de prioriteitenlijst van Kasper, en de ontwikkeling ervan volgt onmiddellijk op de snowboard tour.)

Terug naar het template: Druk op deze link in de Template module:

img-30

Je zou dan moeten zien dat het "CSS Styled Content" statische bestand beschikbaar wordt in de box "Include Static (from extensions)":

img-31

Klik het aan, sla het template op en ga naar de Template Analyzer:

img-32

In de "Template Analyzer" zie je de hiërarchie van template records en statische templates die kunnen worden toegevoegd aan de huidige "main template record". Door de statische template mee te nemen in de selectie zal het gewoon worden meegenomen voordat de TypoScript code in de template record "NEW SITE" wordt aangemaakt. Dit betekent dat elk object dat binnen het "EXT:css_styled_content/....." statische template gedefinieerd is, gekopieerd kan worden en in het NEW SITE template record kan worden gebruikt. Dit zullen we nu doen omdat het opgenomen statische template een object, "styles.content.get", heeft dat een content object is dat alle content elementen van de "Normal" kolom van de huidige pagina selecteert:

Verander dus dit deel van de definitie van het "temp.mainTemplate" object in het template record:

...

# 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

...

Als je de frontend voor de pagina “Licence C” vernieuwt, zou je het volgende moeten zien:

img-33

In de HTML broncode zien we dit:

img-34

Zoals je ziet was de header van het content element opgemaakt in <h1> tags. Als je andere "Layout" types voor de header selecteert, wordt de weergave bijv. <h2> (voor Layout 2).

Elke regel bodytext is omgeven door <p> tags waarbij de class is ingesteld op "bodytext". Op deze manier kun je de stijl van de pagina content of content elementen in je stylesheet specifiek bepalen! Je ziet hoe slim Raphaël geweest is door de proef content in het template bestand zo te ontwerpen dat er <p class="bodytext"> tags worden gebruikt!

Ieder ingevoegd van element zal een <a> tag hebben waarvan de waarde van de naam is ingesteld op de "uid" van het content element. Dit zijn ankerpunten die in de URL kunnen worden gebruikt om direct naar een bepaalde positie op een pagina te gaan.

Dit is hoe het HMenuobject het level2 menu aanmaakt. Je ziet hoe de link automatisch naar de juiste pagina verwijst en dat er zelfs een extra onFocus handler is ingesteld.

De Objectboom?

Nu dan, door dit zogenaamde content element, "styles.content.get", te kopiëren, wat zijn we eigenlijk aan het toevoegen aan de objectboom? Laten we eens kijken met de Object Browser:

img-35

We zien twee interessante zaken:

Het objectpad "styles.content.get" had kennelijk een cObject van het type CONTENT. Afgaande op de attributen lijkt het een redelijke conclusie dat het records van de tabel "tt_content" selecteert, en dat deze per veld worden geordend, "sorting". Voor meer informatie:underline:``bekijk hier het CONTENT cObject **e <http://t ypo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[toc El]=356&cHash=9f3b5c6ba2>`_` .

Ten tweede werd er een geheel nieuw TLO (Toplevel Object) gedefinieerd- "tt_content". Het CONTENT cObject dat records selecteert van "tt_content" (#1) zal dit TLO (tevens gedefinieerd als een cObject) gebruiken als een defaultwaarde om elk gevonden record mee aan te maken!Zoals we zien is "tt_content" TLO gedefinieerd als een USER cObject waarbij een PHP functie van de "css_styled_content" extension wordt benut-wat me juist lijkt omdat dat de extension is die we hiervoor hebben geïnstalleerd! Om meer hierover te weten te komen moet je:underline:``de documentatie voor de "css_styled_content" extension <http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=170&c Hash=97866c2553>`_` raadplegen**.

Als je heel erg nieuwsgierig bent kun je ook in de class "tx_cssstyledcontent_pi1" kijken en de logica ervan bestuderen. Hier is een stukje van de functie "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;

...

Een XHTML compatibele website

Als je XHTML compatibele websites wilt maken, kun je dat ook met TYPO3. Versie 3.6.0 van TYPO3 voldoet, voor zover mogelijk, aan XHTML compatibiliteit (niveau: XHTML transitional).

Voor deze training moet je er zeker van zijn dat de gebruikte HTML templates XHTML compatibel zijn. Dit is natuurlijk de eerste stap, en iets waar je jezelf van verzekerd moet hebben.

De volgende stap is ervoor te zorgen dat TYPO3 een XHTML doctype in de output genereert. Dit is gemakkelijk te doen door gewoon de volgende TypoScript regel in het Setup veld van het main template record te op te nemen:

page.config.doctype = xhtml_trans

Bovendien dienen de menu's ook compatibel te zijn. Vooralsnog worden bijzondere tekens, zoals “&”, precies zo weergegeven. Dit moet je vermijden. De TypoScript code van het menu moet worden veranderd door vier extra regels (hier weergegeven in rood) toe te voegen:

# 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>

}

Hierdoor worden de menu labels door de PHP functie htmlspecialchars() geleid, die bijv. “&” naar “&amp" omzet;

Nadat je dit gedaan hebt, kun je de site testen met bijv. Opera 7, dat een hele handige shortcut heeft voor compatibiliteitstesten:

Je hoeft alleen maar rechts te klikken op de HTML pagina, kies “Frame” en vervolgens “Validate source”:

img-36

Opera stuurt dan automatisch de broncode van de pagina voor je naar “http://validator.w3.org/” en, als het goed gaat, zou je het volgende op je beeldscherm moeten zien:

img-37

Nu alles wat netter

We hebben onze website nu af. Dhr. Benoit en dhr. Raphaël hebben hun taken afgerond en misschien heeft ondertussen dhr. Picouto zelfs alle content elementen voor elke pagina in de boom hebben geleverd. We weten het niet, maar de basisstructuur van de website is er, gebaseerd op een heel gewoon HTML bestand dat in de map "fileadmin/template/main/" is geplaatst, waarbij, indien nodig, alleen de menu en content gedeeltes dynamisch worden vervangen.

Betere template structuur

Het enige wat we nog moeten doen, is het template record wat beter organiseren. Alhoewel we de gebruikte hoeveelheid TypoScript tot een minimum hebben beperkt, is het makkelijk te zien dat een dergelijk template record heel snel groot en onhandig wordt. Dit kan worden opgelost door het te vervangen door een serie template records die worden opgenomen:

Ten eerste zou je een hele nieuwe pagina kunnen maken in de "root- level" van de paginaboom. Selecteer het type "sysFolder" (als in "opslagruimte voor elk database element dat je maar wilt") en noem het Template Storage.

Dan maak je als volgt drie template records aan:

img-38

Vink "Clear" nergens aan! Kopieer alleen de juiste "temp.xxxx" object definities van de "NEW SITE" template hierheen. In deze lijst is de volgorde onbelangrijk.

De volgende stap is om deze drie templates in de "NEW SITE" main template op te nemen. Bewerk dus de "NEW SITE" template:

img-39

De volgorde is nu wel belangrijk: het eerstgenoemde template wordt het eerste opgenomen en omdat het template record "ext: Main TEMPLATE cObject" kopieën maakt van bijv. het "temp.menu_1" object, moet het als laatste worden opgenomen.

Sla het template record op en bekijk de nieuwe structuur met de Template Analyzer:

img-40

Je ziet dat het statische template als eerste is opgenomen, dan de drie "basis templates" uit onze opslagmap en tenslotte het main template record. Je kunt van elk de titel aanklikken en er onder naar de content kijken.

Enkele HTML ontwerp overwegingen

Je zult in dit deel van de training gemerkt hebben, dat het mogelijk is om op een hele gemakkelijke wijze een HTML template van een grafische vormgever te implementeren, terwijl je zeker bent van compatibiliteit met zijn oorspronkelijke werk in de omgekeerde richting (omdat het handmatig invoegen van markers in zijn HTML template onnodig is). Bovendien komt er alleen maar bekende technologie zoals HTML en CSS bij kijken -er hoeven geen verwarrende XLST stylesheets te worden gemaakt (hoewel dhr. Benoit XSLT kan gebruiken op PHP-niveau, als hij dat zou willen).

Maar alhoewel dhr. Raphaël, de ontwerper, vrijwel volledig vrij is in zijn ontwerp moet hij toch nog steeds de grondbeginselen van dynamische en statische content begrijpen.

Geef duidelijk aan welke delen dynamisch en welke statisch zijn

Dhr. Raphaël moet vooral begrijpen -waarschijnlijk met het hele webteam-welke delen van de pagina statische delen zijn en welke dynamisch. Statische delen zijn alle delen waar TYPO3 NIETS mee doet. Het is echter de bedoeling dat de dynamische delen wel worden vervangen door content afkomstig uit de databronnen van TYPO3.

Bij de identificatie van dynamische delen moet Raphaël op twee dingen letten:

  • Het deel moet worden ingesloten door een enkelvoudig HTML element. Dit kan een <div> element, een <td> element of een <span> element zijn.
  • Het insluitende element moet of een id- of een class attribuut bevatten, dat door de configuratie van de Template Auto-parser plugin kan worden gevonden en omgeven door subpart markers. Bijv. <td id="content"> voor de tabelcel waarin de content moet worden geplaatst.

img-41

Het geeft helemaal niet als er proef content in het template bestand blijft - dit wordt immers toch vervangen door dynamische content.

Vereenvoudig de HTML opmaak, gebruik CSS stylesheets

We bevinden ons nu in het jaar 2004 en het is echt tijd om afscheid te nemen van de <font> tag en bgcolor attributen en alles in een extern stylesheet te plaatsen. Met het oog op een CMS implementatie zorgt dit ervoor dat zo veel mogelijk externe technologie wordt gebruikt en CMS specifieke technologie (zoals TypoScript template records) slechts waar strikt noodzakelijk.

In dit onderdeel van de training is het level2 menu het beste voorbeeld:

<!-- 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>

Laten we een enkelvoudig element bekijken (hierboven in rood). Een andere manier om dit te implementeren zou zijn:

<!-- 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>

Bedenk dat de definitie van het TMENUITEM object in het template record inhield dat de elementen door dit eenvoudige <div> bestanddeel worden omgeven:

temp.menu_1.1 {

# Normal state properties

NO.allWrap = <div class="menu1-level1-no"> | </div>

...

... en ja hoor, je raadt het al, het bovenstaande betekent dat de elementen ongeveer door het volgende moeten worden omgeven:

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>

)

...

En zelfs dat zou niet genoeg zijn: Je zou ook de class naam van de A tag met behulp van een andere eigenschap van het NO status object moeten toevoegen, en het "gray_dotted_line.gif" bestand zou als prefix het correcte bestandspad moeten krijgen - zoals bijvoorbeeld "fileadmin/template/main/".

Geen row/colspans!

Dit is waarschijnlijk de grootste bedreiging voor dynamische content - het gebruik van colspan als je een dynamisch object maakt! Dit is dus uitgesloten. Bestudeer bijvoorbeeld de volgende menu opzet:

<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>

Het is vrijwel onmogelijk dit in te voeren! Het eerste menu bestanddeel is in dezelfde tabelrij als de contentcel, de andere zes menu bestanddelen hebben aparte tabelrijen. Bovendien heeft de tabelcel met de content een colspan="7" attribuut nodig voor de verdeling over alle rijen van het menu!

Ontwerptechnisch gezien is dit duidelijk een heel slechte keuze:

de menu opmaak bevindt zich op verschillende punten in de HTML code

er is een afhankelijkheid tussen het colspan attribuut en het aantal menu bestanddelen (dat dynamisch is!)

Ontwerpers moeten zich dus verre houden van dit soort ontwerpen. In plaats daarvan moeten ontwerpers zoals dhr. Raphaël gemakkelijk te herhalen opmaak voor dynamische elementen leren. Dit zijn goede voorbeelden:

Bijvoorbeeld zoals in onze huidige template:

<!-- Menu table cell: -->

<td id="menu _1">

<div class="menu 1-level1-no"><a href="#">Menu item 1</a></div>

<div class="menu 1-level1-no"><a href="#">Menu item 2</a></div>

<div class="menu 1-level1-act"><a href="#">Menu item 3 (act)</a></div>

...

</td>

Alternatief met een tabel:

<!-- 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>

We zouden nog ingewikkelder voorbeelden kunnen geven, zoals het eerdere voorbeeld waarbij elk element in een tabel werd bewerkt! Het gaat niet om de hoeveelheid HTML per bestanddeel -het gaat om de herhaalbaarheid van de opmaak !

Dhr. Raphaël moet dit soort zaken begrijpen, zodat dhr. Benoit geen uren kwijt is vanwege een gebrekkige HTML structuur - en uiteindelijk zou dhr. Picouto zelfs zo blij kunnen zijn met de snelheid van de ontwikkeling die wordt bereikt door de symbiotische samenwerking tussen Raphaël en Benoit, dat hij ze trakteert op lunch!

Tenslotte

Ben je na het volgen van deze training geïnteresseerd in andere trainingen in TYPO3, ga dan verder met de twee andere beschikbare trainingen: TYPO3 Training voor Editors en TYPO3 Training voor Ontwikkelaars.

Vragen? Neem dan contact op via mijn e-mail adres:underline:``hans@alternet.nl <mailto:hans@alternet.nl>`_` of op het telefoonnummer (078) 635 1200.

Hartelijk dank voor het volgen van deze training!

Ing. Hans A. Olthoff

AlterNET Internet B.V.

img-42 Training voor Ontwikkelaars - 47