|
|
Dit document is beschikbaar in: English Castellano Deutsch Francais Italiano Nederlands Portugues Russian Turkce |
door Egon Willighagen <egonw/at/linuxfocus.org> Over de auteur: Hij studeert dit jaar af (Master's-diploma) en begint dan aan zijn PhD over chemometrie. Hij houdt nog steeds veel van basketbal, net als van LinuxFocus en Linux in het algemeen. Vertaald naar het Nederlands door: Floris Lambrechts <floris.lambrechts/at/linuxfocus.org> Inhoud: |
LinuxFocus.org(/Nederlands) maken met XML - XSLTKort:
Dit artikel bevat de presentatie zoals gegeven op de Libre
Software Meeting in Bordeaux in juli van dit jaar. Het legt uit hoe
de XML-database in elkaar zit die we gebruiken voor het
maken van onze website, LinuxFocus.org(/Nederlands).
|
Het oude systeem voor het onderhouden van de artikelen en vertalingen hier bij LinuxFocus, bestond uit verschillende tekstbestanden, onder meer resdb.txt, issuedb.txt en maindb.txt. Deze bestanden hadden een vast formaat en werden gebruikt voor het automatisch maken van webpagina's. Spijtig genoeg was het lastig om ze uit te breiden, en omdat het om meerdere bestanden ging was het moeilijk om alle info over één bepaald artikel te overzien.
Toen ik aan de database begon, werden er bij LinuxFocus nog niet veel pagina's automatisch gemaakt. Als redacteur van het Nederlandse team zag ik er wel wat in om de overzichten op de website automatisch te laten maken. Al die HTML's aanpassen, elke keer opnieuw als er een nieuwe vertaling uit was, was veel te veel werk en bovendien een bron van gebroken links. Daarom wilde ik een nieuw systeem dat gemakkelijk uit te breiden was en dat de overzichten automatisch zou kunnen maken. Ik begon eraan te werken ergens in de zomer van 2000.
De keuze voor XML was een beetje willekeurig. Er werd geopperd om een relationele database te gebruiken, maar ik had al ervaring met XML en ik voelde meer voor een tekst-gebaseerde oplossing. Al gauw bleek dat er een nieuw nummeringssysteem nodig was, zodat de database de nummers van de artikelen zou kunnen gebruiken als unieke ID. Voorheen werden er twee of zelfs drie nummeringen door elkaar gebruikt. Guido Socher deed al het werk voor die hernummering, wat niet gering was (bedankt Guido!).
Op dat punt was de Document Type Definition (DTD) van de database in ontwikkeling en hadden we ook al een beetje inhoud om te kunnen testen. Nu de nieuwe nummering klaar was, werd het tijd om de database te vullen met inhoud. Nadat ik zo'n twintig artikelen had ingevoerd, werd het duidelijk dat dit een enorm karwei zou worden. Ik had scripts kunnen schrijven die informatie haalden uit de oude bestanden, maar daar stond ook niet alles in en de informatie was veel te verspreid. Gelukkig begon Floris Lambrechts mee te werken, en ik moet hem bedanken voor het invoeren van het grootste deel van de database. Zonder zijn hulp zou het systeem nu niet zijn wat het is. (Noot van de vertaler: bedankt Egon, graag gedaan!)
Met het nieuwe formaat kregen we ook de mogelijkheid om nieuwe informatie toe te voegen. In het voorbije jaar zijn er dan ook verschillende soorten nieuwe gegevens ingevoegd in de database. Eerst maakten we een overzicht van auteurs, vertalers, redacteurs en andere mensen die meewerken aan LinuxFocus. Ook namen we de locaties van bestanden op. Deze laatste waren nodig omdat de plaats en de namen van de artikelen door de jaren heen meermaals veranderd waren. Na de hernummering bleven er nog twee systemen over. Sommige bestanden gebruiken server side includes (SSI) en hadden een .shtml-extensie, terwijl oudere artikelen op .html eindigden. Met de <file>-tag kunnen we nu een standaardwaarde overschijven. (Op dit moment is de standaard "article" + nummer van het artikel + ".shtml". Hier komt nog een eventuele ".meta" tussen in het geval dat het artikel in het door LinuxFocus gebruikte meta-formaat geschreven is.)
Nu de database gevuld werd, ging ik eindelijk de software testen die ik aan het schrijven was. De XSLT-stylesheets die we nu gebruiken waren namelijk niet de eerste implementatie. Ik had eerst Perl-code geschreven, maar naarmate de database groeide werd de snelheid daarvan onwerkbaar. Maar voordat we het over de software hebben, doe ik eerst het formaat van de database uit de doeken.
Om te beginnen is XML een syntax-specificatie voor markup-talen. XML bepaalt hoe markup eruit hoort te zien. Het zegt dat een document één root-element (hoofd-element) moet hebben en dat dit root-element bestaat uit een begin-tag, inhoud (tekst, sub-elementen, of beide), en een eind-tag. Deze tags bestaan op hun beurt uit het teken "<" gevolgd door een naam en aan het eind het teken ">". Een eind-tag moet een "/" hebben direct voor de naam. Een begin-tag mag attributen bevatten, deze hebben ook weer hun eigen syntax. Je kan dus stellen dat de syntax bepaalt welke opeenvolging van karakters een geldig XML-document vormt. Een simpel XML-document kan er zo uitzien:
<begroeting>Hello, world!</begroeting>
Een taal bestaat niet alleen uit syntax, er is ook nog zoiets als semantiek. De semantiek
van een taal beschrijft hoe de verschillende elementen met elkaar verbonden zijn. Om HTML als
voorbeeld te nemen: de semantiek bepaalt dat <body>
binnen het
<html>
-element moet staan en niet andersom.
De semantiek zegt ook dat het <img>
-element leeg is (het heeft wel
attributen), net als <br>
. Als de semantiek gegeven is in een formele
notatie, dan kan je documenten parsen en valideren volgens die semantiek.
Eén van die formele notaties heet Document Type Definition,
of korter DTD. Alleen wanneer een document gevalideerd is, kan je het
een geldig XML-document noemen.
Nu we weten wat een DTD is, gaan we de DTD voor de XML-database van LinuxFocus een keer bekijken. We geven bij de meeste elementen ook meteen een voorbeeld, waardoor je een goed idee krijgt over hoe de informatie er in de database uitziet.
Het root-element van onze XML-database, en ook van de uitbreidingen en vertalingen, is <database>.
<!ELEMENT database (themes?, persons?, issues?, articles?)>
Merk allereerst op dat de "?" betekent dat het sub-element ("child element") 0 of 1 keer mag voorkomen. Onze LinuxFocus-databank kan dus informatie bevatten over thema's, personen, nummers (issues) en artikelen. Aangezien dit vrij duidelijk is, gaan we over naar het volgende element.
De thema's staan in het element <themes>
, dat een child-element is
van <database>
. Elk thema heeft een eigen ID, een titel, en optioneel ook
een beschrijving (description) en een afbeelding (image).
<!ELEMENT themes (theme+)> <!ELEMENT theme (title*, desc?, img?)> <!ELEMENT title (#PCDATA)> <!ELEMENT desc (#PCDATA)> <!ELEMENT img (EMPTY)>
Sommige van deze sub-elementen hebben verplichte attributen. Ook dit
wordt aangegeven door de DTD. Tekstuele inhoud staat altijd in een element met
het attribuut xml:lang
. De waarde van dit attribuut moet overeenkomen
met een landcode conform ISO-standaard
3166. Voorbeelden zijn "en
", "fr
" en "nl
".
Zowel het id
- als het xml:lang
-attribuut zijn beschreven in de oospronkelijke
XML-specificatie en maken dus deel uit van de XML-syntax.
<!ATTLIST theme id ID #REQUIRED> <!ATTLIST title xml:lang NMTOKEN #REQUIRED> <!ATTLIST desc xml:lang NMTOKEN #REQUIRED> <!ATTLIST img src CDATA #REQUIRED>
Een voorbeeld-database ziet er zo uit:
<database> <themes> <theme id="hw"> <title xml:lang="en">Hardware</title> <img src="Hardware.jpg"/> <theme> <themes> </database>
De verschillende LF-nummers (issues) worden bijgehouden in het
<issues>-element. Net zoals bij de themes
heeft
elk issue
zijn eigen ID.
<!ELEMENT issues (issue+)> <!ELEMENT issue (title+, published?, file*)> <!ELEMENT title (#PCDATA)> <!ELEMENT published (EMPTY)> <!ELEMENT file (#PCDATA)>
Het element <published>
staat alleen bij gepubliceerde nummers.
Issues zoals 'het volgende nummer' en 'onvertaalde Franse artikelen' hebben
dit element dus niet. De <title>
heeft ook hier het attribuut
@xml:lang
. Bij <file>
wordt aangegeven in welke directory het element staat.
Dit is geen link naar de index.html, want het wordt gebruikt om de
bestandsnamen van de artikelen te genereren.
Een voorbeeld (merk op dat het attribuut @code
wordt gebruikt
om te kunnen sorteren):
<issue id="ToBeWritten" code="999996"> <title xml:lang="en">Not yet written articles</title> </issue> <issue id="September2001" code="200109"> <title xml:lang="en">September2001</title> <published/> <current/> </issue>
Hierin plaatsen we de informatie over auteurs en vertalers. Elke persoon heeft een uniek ID.
<!ELEMENT persons (person+)> <!ELEMENT person ((name|email)*,(homepage|nickname|desc|team)*)> <!ELEMENT email (#PCDATA)> <!ELEMENT name (#PCDATA)> <!ELEMENT homepage (#PCDATA)> <!ELEMENT nickname (#PCDATA)> <!ELEMENT desc (#PCDATA|%html-els;)*> <!ELEMENT team EMPTY>
De volgende soorten informatie zijn mogelijk: een naam, een e-mailadres
(of meerdere), homepagina('s) en roepnaam (nickname). Als de persoon ook
deel uitmaakt van een vertaalteam, krijgt zij ook een <team>
-element.
Om bijvoorbeeld aan te geven dat Floris lid is van het Nederlandse vertaalteam,
schrijven we het volgende in het element <person>
: <team
xml:lang="nl"/>
. Tenslotte kan elke persoon ook een beschrijving hebben,
waarin op zijn beurt ook weer hyperlinks kunnen staan.
Een voorbeeld:
<person id="nl-ew"> <name>Egon Willighagen</name> <email>[email protected]</email> <team xml:lang="nl"/> </person>
De artikelen vormen natuurlijk het hart van de databank.
<!ELEMENT articles (article+)> <!ELEMENT article (title+, (file|personref|abstract|issueref|themeref| nometa|nohtml|translation|proofread)*)> <!ELEMENT abstract (#PCDATA)> <!ELEMENT nohtml EMPTY> <!ELEMENT nometa EMPTY> <!ELEMENT translation (personref*, (reserved|finished|proofread)*)> <!ELEMENT reserved (#PCDATA)> <!ELEMENT finished (#PCDATA)> <!ELEMENT proofread (personref*, (reserved|finished)*)> <!ATTLIST article id ID #REQUIRED xml:lang NMTOKEN #IMPLIED type (article|coverpage) "article" next IDREF #IMPLIED prev IDREF #IMPLIED> <!ATTLIST file xml:lang NMTOKEN #REQUIRED type (target|meta) "target"> <!ATTLIST translation from NMTOKEN #REQUIRED to NMTOKEN #REQUIRED>
Elk artikel heeft op zijn minst één titel; één voor elke taal.
Het element <file>
wordt gebruikt om de locatie
van het bestand aan te geven, zowel voor de HTML- als voor de META-versie
(zie het voorbeeld hieronder).
Indien er geen META- of HTML-versie beschikbaar is, gebruiken we de optionele
<nometa/>
en <nohtml/>
.
Elk artikel kan zijn eigen abstract
hebben; deze tekst verschijnt
als beschrijving van het artikel in de automatisch aangemaakte pagina's.
Het element <article>
kent vijf attributen: de verplichte
ID
, optioneel een xml:lang
om aan te geven in welke
taal het oorspronkelijk geschreven was en een type
-attribuut voor
inleidingen van nummers (die voor de handigheid ook gezien worden als
artikelen). De laatste twee zijn dan next
en
prev
, die gebruikt worden om aan te duiden welke de eventuele
voorgaande en volgende artikelen in dezelfde serie zijn.
Een artikel wordt verbonden met zijn nummer en met een thema d.m.v.
issue
en theme
, die elk een
href
-attribuut hebben. De waarde van dit attribuut
is dan de ID
van het nummer of thema in kwestie.
Een voorbeeld:
<article id="article206" xml:lang="en"> <title xml:lang="en">Using XML and XSLT to build LinuxFocus.org(/Nederlands)</title> <personref href="nl-ew"/> <issueref href="ToBeWritten"/> <themeref href="appl"/> <abstract xml:lang="en"> This article shows you how parts of the Dutch web site of LinuxFocus are generated with XSLT tools from the XML database. It compares this with the (very) much slower DOM tools in Perl. </abstract> </article>
Een gelokaliseerd <article>
-element ziet er zo uit:
<article id="52"> <title xml:lang="nl">Enlightenment</title> <file xml:lang="nl">Nederlands/July1998/article52.html</file> <translation from="en" to="nl"> <personref href="nl-tu"/> <reserved>2000-09-06</reserved> <finished>2000-10-04</finished> <proofread> <personref href="nl-fl"/> <reserved>2000-10-04</reserved> <finished>2000-10-04</finished> </proofread> </translation> <abstract xml:lang="nl"> Enlightenment is een window manager voor Linux met uitgebreide mogelijkheden. Dit artikel bespreekt ze, samen met de installatie en de instelling van E. Dit alles is niet voor beginners daar E op het moment nog in bèta-stadium verkeert. </abstract> </article>
Merk op dat dit artikel gereserveerd is voor vertaling op een bepaalde datum,
dat de vertaling afgewerkt is, en ook nagelezen (proofread).
Telkens wordt de persoon die deze bepaalde taak gedaan heeft gelinkt met
<personref>
.
Voor alle elementen kun je waarschijnlijk het meeste leren in de database zelf:
Zoals eerder gezegd, wilden we de database vooral gebruiken om er automatisch webpagina's mee te maken. Nu we het formaat van de database goed begrijpen (?) kunnen we dieper ingaan op het gebruik ervan.
Eerst een stukje geschiedenis. De eerste implementatie gebruikte Perl-modules om de data uit de database te halen. Alhoewel het een zeer elegante interface was, werkte het programma veel te traag. De informatie werd immers voorgesteld volgens het Document Object Model (DOM), en de meeste DOM-implementaties zijn nu eenmaal enorm traag. Veel trager in ieder geval dan hun alternatief, de Simple API for XML (SAX).
Maar als je enkel webpagina's gaat maken, blijkt een derde alternatief nog meer geschikt: XSLT. Dit is een transformatietaal, uitgedrukt in XML-syntax. Er bestaan al veel XSLT-processors en de meeste programmeertalen kunnen er ook mee overweg. Een tijdje terug hadden we hier in LinuxFocus een artikel over: Een introductie tot de Perl-module XML::XSLT. Sinds die tijd zijn er een paar nieuwe implementaties verschenen, waarvan ik de volgende kan aanbevelen:
Voor de rest van dit artikel gebruiken we Sablotron als voorbeeld.Een XSLT-processor krijgt twee bestanden als invoer. Het ene is de XML-code die getransformeerd moet worden, het andere is de XSLT-stylesheet die de transformatie beschrijft. Voor het maken van de LinuxFocus-webpagina's hebben we de volgende stylesheets:
Om bijvoorbeeld de mainindex.html te maken, draaien wij (het /Nederlands-team):
sabcmd stylesheets/mainindex.xslt db/lfdb.nl.xml > ../mainindex.html
De stylesheets weten zelf waar de Engelse hoofd-database is, dus we geven enkel de gelokaliseerde database mee als invoer. Sommige stylesheets hebben nog een extra parameter nodig, bijvoorbeeld:
sabcmd stylesheets/theme.xslt db/lfdb.nl.xml '$theme=appl' > ../Themes/appl.html
De Nederlandse hoofdpagina, index.shtml, maken we ook uit de database, maar hier verloopt alles wat ingewikkelder. De index.html wordt eigenlijk gemaakt met Guido Socher's lfpagecomposer uit een reeks op voorhand bewerkte bestanden. Die bestanden worden gemaakt op basis van .pre-bestanden. Een paar voorbeelden? Een overzicht van alle nummers van LinuxFocus:
<H2>Vorige nummers</H2> <ul> <!-- macro xslt previssues --> </ul>Een lijst van de tien meest recent vertaalde artikelen:
<H2>Recent vertaalde artikelen</H2> <!-- macro xslt recently_translated -->Met andere woorden, de .pre-bestanden zijn gewoon stukjes HTML met een macro erin die een stylesheet toepast op de gelokaliseerde database. Het verwerken van de .pre-bestanden (en dus het uitvoeren van de macro's) gebeurt met een programma genaamd apply_stylesheets.pl. Dit programma zoekt naar <!-- macro xslt [stylesheet] -->-opdrachten en past dan die stylesheet toe op de database. Merk op dat de extensie .xslt weggelaten is. Onze Makefile bevat:
%.shtml: %.pre @echo "Making $*..." @../../xml/bin/apply_stylesheets.pl $*.pre
Het resultaat van deze bewerking is een reeks *.shtml-bestanden, waaruit lfpagecomposer dan de index.html maakt.
Om dit systeem ook voor andere LinuxFocus-talen te gebruiken, moet je twee dingen doen:
Eigenlijk is het een beetje spijtig dat de tweede stap nodig is. In principe moet je enkel de tekst in de uitvoer veranderen, maar de stylesheets hebben daar op dit moment nog geen handige faciliteiten voor. Het is zeker mogelijk om deze alsnog in te bouwen, en dat zou ik dan ook graag zien gebeuren.
Ik raad je aan om gebruik te maken van een XML-editor die om kan met DTD's. Bijvoorbeeld: in Emacs is er de psgml major mode waarmee je documenten kunt valideren (met nsgmls). Zeer handig om fouten te voorkomen. In Emacs kan je dan ook klikken met de rechtermuisknop om een lijst te zien van alle elementen en attributen die je op dat punt kunt invoegen. (Dank gaat uit naar Jaime Villate voor zijn uitstekende presentatie op de LSM-conferentie in Bordeaux dit jaar.)
Een laatste hulpmiddel is de Nederlandse lokalisatie van de XML-database. Als je problemen tegenkomt, kun je altijd dat bestand raadplegen. Je kan erin zien hoe de verschillende elementen georganiseerd zijn. En als dat niet helpt, kun je me nog altijd e-mailen.
Het lokaliseren van de stylesheets is waarschijnlijk een beetje lastig. De tekst staat midden tussen XSLT-commando's. Die laatste moet je laten staan tenzij je goed weet wat je doet (anders krijg je problemen met de funcionaliteit). Ik ben van plan om in de toekomst een systeem te maken zodat je voor een lokalisatie slechts één bestand met vertalingen moet bewerken. Dan zouden alle stylesheets werken met deze vertalingen. Het klinkt mooi, maar het is verre van afgewerkt...
Oké, dit zou je op weg moeten helpen. De meeste dingen kun je gewoon kopiëren uit de Nederlandse bestanden. Ze hebben allemaal FDL- en GPL-licentie. Voor het volgend jaar zijn dit mijn plannen voor het systeem:
|
Site onderhouden door het LinuxFocus editors team
© Egon Willighagen, FDL LinuxFocus.org |
Vertaling info:
|
2004-03-04, generated by lfparser version 2.43