|
|
Dit artikel is beschikbaar in: English Castellano Deutsch Francais Nederlands Portugues Russian Turkce |
door Over de auteur: Hij studeert dit jaar af (masters 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. Inhoud:
|
Kort:
Dit artikel bevat de presentatie zoals gegeven op de Libre Software Meeting in Bordeaux in juli van dit jaar. Het legt uit hoe de LinuxFocus XML database in elkaar zit die we gebruiken voor het maken van de LinuxFocus.org(/Nederlands) web site.
Het oude systeem voor het onderhouden van de artikelen en de vertalingen hier bij LinuxFocus, bestond uit verschillende tekst-bestanden, ondermeer resdb.txt, issuedb.txt en maindb.txt. Deze bestanden hadden een vast formaat en werden gebruikt voor het automatisch maken van web-pagina's. Spijtig genoeg was het moeilijk om ze uit te breiden, en omdat het om meerder bestanden ging was het moeilijk om alle info over 1 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.
The choice for XML was a bit arbitrary. 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 nummering systeem nodig was, omdat de database dan 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 her-nummering, wat niet min 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 20 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 help 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 doorheen de jaren meermaals veranderd waren. Na de her-nummering 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 standaard-waarde te 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 LinuxFocus 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.
XML, om te beginnen, is 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 start tag, inhoud (tekst, sub-elementen, of beide), en een eind-tag. Deze tags op hun beurt bestaan uit een "<" teken gevolgd door een naam en aan het eind een ">" teken. Een eind-tag moet een "/" hebben net voor de naam. Een begin-tag mag attributen bevatten, deze hebben ook weer hun eigen syntax. Je kan dus tellen 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>
Naast syntax, bestaat een taal ook uit semantiek. Die beschrijft hoe de verschillende elementen met elkaar verbonden zijn. Om HTML als voorbeeld te nemen: de semantiek bepaalt dat <body>
in het <html>
element moet staan, en niet omgekeerd. 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. Enkel wanneer een document gevalideerd is, kan je het een geldig XML document noemen.
Nu we weten wat een DTD is, gaan we de LinuxFocus XML Database DTD 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 de LinuxFocus 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 databank kan dus informatie bevatten over LinuxFocus' 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 <themes>
element, 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 xml:lang
attribuut. De waarde van dit attribuut is een waarde die overeenkomt met een land-code uit de ISO 3166 standaard. Voorbeelden zijn "en
", "fr
" en "nl
". Zowel het id
als het xml:lang
attribuut zijn beschreven in de originele XML specificatie en zijn dus een deel 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 <published>
element staat enkel bij gepubliceerde nummers. Issues zoals 'het volgende nummer' en 'onvertaalde Franse artikelen' hebben dit element dus niet. De <title>
heeft ook hier het @xml:lang
attribuut. <file>
geeft aan 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 @code
attribuut 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 email adres (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 <person>
element: <team xml:lang="nl"/>
. Tenslotte kan elke persoon ook een beschrijving hebben, waarin op zijn beurt ook weer web-links kunnen staan.
Een voorbeeld:
<person id="nl-ew"> <name>Egon Willighagen</name> <email>egonw@linuxfocus.org</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; 1 voor elke taal. Het <file>
element 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 artikels in de automatisch gemaakte pagina's.
Het <article>
element 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 laaste twee zijn dan next
en prev
, die gebruikt worden om aan te duiden welk de eventuele voorgaande en volgende artikelen in dezeflde serie zijn.
Een artikel wordt verbonden met zijn nummer en 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 is 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 Linux window-manager 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 beta-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 die 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 beetje 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 enorm traag. Veel trager in ieder geval dan hun alternatief, de "Simple API for XML" (SAX).
Maar als je enkel weg-pagina's gaat maken, blijkt een derde alternatief nog meer geschikt: XSLT. Dit is een transformatie-taal 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:
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 LinuxFocusFor 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.html, 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 files. Een paar voorbeelden? Een overzicht van alle LinuxFocus nummers:
<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 -->De .pre bestanden zijn met andere woorden 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 .xslt extenstie 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. Die laat toe om je document te valideren (met nsgmls). Zeer handig om fouten te voorkomen. In Emacs kan je dan ook klikken met de rechter muisknop 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 laaste 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
Het lokaliseren an de stylesheets is waarschijnlijk een beetje lastig. De text 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 Klik hier om een fout te melden of commentaar te geven |
Vertaling info:
|
2001-09-02, generated by lfparser version 2.17