original in en Egon Willighagen
en to fr Iznogood
Il terminera sa maîtrise cette année et commencera son doctorat en chimiométrie. Il aime toujours beaucoup le basket-ball, ainsi que LinuxFocus et Linux en général.
Le système le plus utilisé pour la gestion des documents et traductions dans le projet LinuxFocus consiste en plusieurs fichiers ASCII, parmi lesquels on peut trouver resdb.txt, issuedb.txt et maindb.txt. Le format des fichiers est fixe et il est utilisé pour générer des pages web. Il est néanmoins difficile à étendre et la nature hétérogène des données rend difficile la vue d'ensemble des informations qui sont disponibles pour un article.
La génération automatique du contenu du site n'était pas beaucoup utilisée dans le projet LinuxFocus lorsque j'ai commencé la nouvelle base de données. En tant qu'éditeur de l'équipe Hollandaise, je souhaitais que les index du site soient générés automatiquement. Editer plusieurs fichiers HTML à chaque fois qu'un nouvel article était traduit réclamait pas mal de travail et était la cause de nombreux liens non résolus. C'est pourquoi je souhaitais avoir un nouveau système avec lequel je puisse ajouter sans peine des informations et à partir duquel je pouvais générer automatiquement des pages d'index pour le site. J'ai commencé à y travailler vers l'été 2000.
Le choix du XML était un peu arbitraire. Des suggestions avaient été faites pour l'utilisation d'une base de données relationnelle mais j'avais l'expérience du XML et je préférais un système basé sur des fichiers textes. Il s'est rapidement avéré qu'une nouvelle numérotation était nécessaire puisque la base pouvait alors utiliser un seul type d'ID, à la place des deux ou trois utilisés jusqu'alors. Guido Socher a refait toute la numérotation, ce qui était un énorme travail (un grand merci !).
La Définition du Document Type (DTD) était déjà en cours de développement et une petite partie du contenu était dans la base de données dans le but de tester. Avec la nouvelle forme de numérotation uniforme, le moment était venu de remplir la base avec du contenu. Après avoir ajouté environ 20 articles, il est devenu clair qu'il s'agissait d'un énorme projet. Ecrire des scripts utilisant les anciens fichiers était possible mais toutes les informations qu'aurait pu contenir la base n'étaient pas disponibles, et comme déjà expliqué, les informations disponibles étaient réparties sur plusieurs fichiers. Heureusement, Floris Lambrechts m'a rejoint et je dois le remercier sincèrement d'avoir ajouté la plupart du contenu dans la base de données. Sans son aide, le système ne serait pas ce qu'il est aujourd'hui.
Avec le nouveau format, il a été possible d'inclure de nouvelles informations. Et dans le courant de l'année dernière, de nouveaux types de données ont été ajoutés à la base. Les premières extensions ont été une table des auteurs, traducteurs, éditeurs et autres personnes impliquées dans LinuxFocus et la localisation des fichiers. La raison d'ajouter cette dernière est qu'il existait plusieurs schémas de nommage des fichiers depuis les débuts de LinuxFocus. La renumérotation l'a réduit à deux schémas. Quelques fichiers utilisaient les Server Side Includes et l'extension .shtml, et les anciens articles utilisaient l'extension .html. Le tag <file> peut être utilisé pour écraser celui par défaut. (Le format par défaut actuel utilise "article" + numéro de l'article + ".shtml". Cela peut inclure un ".meta" optionnel au cas où le fichier est au format meta de LinuxFocus.)
Puisque la base de données avait atteint un minimum acceptable, j'ai testé les performances du logiciel en cours d'écriture. Les feuilles de style XSLT utilisées alors n'étaient pas la première mouture. Elle ont été précédées par du code Perl, mais avec la taille croissante de la base, les performances sont devenues importantes et le premier prototype n'était tout simplement pas assez performant. Mais avant de détailler les outils, je vais d'abord expliquer le format de la base de données.
Avant tout, XML est une spécification de syntaxe pour les langages à balise. XML définit ce à quoi doivent ressembler les balises. Il stipule qu'un document doit avoir un élément racine et qu'un élément est constitué par une balise de départ, un contenu (texte, éléments fils, ou les deux) et une balise de fin. Ces balises, à leur tour, consistent en un caractère "<" suivi d'un nom, et à la fin, d'un caractère ">". Une balise de fin doit avoir un "/" juste avant le nom. Et la balise de départ peut contenir des attributs possédant aussi une syntaxe spécifique. Ainsi, la syntaxe décrit quelle séquence de caractères est permise pour avoir un document XML bien formé. Un exemple de document XML peut ressembler à ceci:
<greeting>Hello, world!</greeting>
En plus de la syntaxe, les langages contiennent aussi une sémantique. Elle décrit comment certains éléments sont relatifs les uns aux autres. Pour prendre l'exemple du HTML, la sémantique détermine que <body> doit être contenu dans un élément <html> et pas l'inverse. Elle décrit aussi que l'élément <img> est vide tout comme <br>. Si cette sémantique est présentée en notation formelle, elle peut être traitée par un programme et utilisée pour valider le document correspondant à cette sémantique. Une de ces notations formelle est appelée Definition de Document Type , ou DTD. Si un document passe le processus de validation, il est appelé document XML valide.
Maintenant que nous savons ce qu'est un DTD, regardons la Base de Données XML de LinuxFocus. Pour plusieurs des spécifications, un exemple est présenté. En examinant ces exemples, vous aurez une idée sur la manière dont l'information est gérée dans la base de données XML de LinuxFocus.
L'élément racine dans la base de données XML de LinuxFocus ou l'une de ses extensions ou localisation en tant qu'élément <database>.
<!ELEMENT database (themes?, persons?, issues?, articles?)>
Notez d'abord que "?" signifie que l'élément fils peut exister une fois ou aucune. Ainsi la base de données peut contenir des informations sur les thèmes, les personnes, les numéros et les articles de LinuxFocus. Comme c'est assez évident, je vais passer à un exemple un peu plus intéressant.
Les thèmes sont contenus dans l'élément <themes> qui est un élément fils de <database>. Chaque thème possède une ID unique, un titre et éventuellement un résumé et une image.
<!ELEMENT themes (theme+)> <!ELEMENT theme (title*, desc?, img?)> <!ELEMENT title (#PCDATA)> <!ELEMENT desc (#PCDATA)> <!ELEMENT img (EMPTY)>
Quelques uns de ces éléments doivent avoir des attributs. Ils sont aussi définis dans la DTD. Tout contenu texte est inclus dans un élément possédant l'attribut xml:lang. La valeur de cet attribut peut être tout jeton conforme au standard ISO 3166 pour les codes de pays. Les exemples sont "en", "fr" et "nl". Les attributs id et xml:lang sont précisés dans les spécifications originales XML et font partie de la syntaxe XML.
<!ATTLIST theme id ID #REQUIRED> <!ATTLIST title xml:lang NMTOKEN #REQUIRED> <!ATTLIST desc xml:lang NMTOKEN #REQUIRED> <!ATTLIST img src CDATA #REQUIRED>
Un exemple de base de données peut ressembler à ceci:
<database> <themes> <theme id="hw"> <title xml:lang="en">Hardware</title> <img src="Hardware.jpg"/> <theme> <themes> </database>
Les numéros sont contenus dans l'élément <issues>. Comme pour les thèmes, chaque numéro possède une ID unique.
<!ELEMENT issues (issue+)> <!ELEMENT issue (title+, published?, file*)> <!ELEMENT title (#PCDATA)> <!ELEMENT published (EMPTY)> <!ELEMENT file (#PCDATA)>
L'élément <published> indique les numéros publiés. Le prochain numéro et le pseudo numéro "TelleLangue2Eng" n'ont pas cet élément. L'élément <title> possède l'attribut @xml:lang. L'élément <file> indique le répertoire dans lequel le numéro est situé. Il ne doit pas pointer vers index.html, car il est utilisé pour indiquer l'emplacement des fichiers.
Un exemple (notez que l'attribut @code est utilisé pour le tri):
<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> </issue>
Les informations sur les auteurs et les traducteurs sont stockées dans l'élément <person>. Chaque personne doit avoir une ID unique.
<!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>
Chaque personne peut avoir les informations suivantes: un nom, une adresse de courrier électronique (ou plusieurs), une (des) page(s) d'accueil et un (des) surnom(s). Si la personne fait aussi partie d'une équipe de traducteurs, un élément <team> est ajouté. Pour indiquer, par exemple, que Floris est membre de l'équipe Hollandaise, la ligne suivante est ajoutée à l'élément <person>: <team xml:lang="nl"/>. Enfin, chaque personne peut avoir une description, qui peut contenir des liens supplémentaires.
Un exemple:
<person id="nl-ew"> <name>Egon Willighagen</name> <email>egonw@linuxfocus.org</email> <team xml:lang="nl"/> </person>
Les articles sont bien sûr la partie la plus intéressante de la base de données.
<!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>
Chaque article possède au moins un titre; un pour chaque langue. L'élément <file> peut être utilisé pour situer le fichier de l'article, qu'il s'agisse du format META ou de la version HTML (voir l'exemple ci-dessous). Dans les cas où aucune version META ou HTML n'est disponible, les éléments optionnels <nohtml/> et <nometa/> peuvent être utilisés. Chaque article peut posséder un résumé, ce qui permet à la base de données de l'utiliser pour les pages d'index.
L'élément <article> possède cinq attributs: l'@ID obligatoire, l'attribut optionnel xml:lang pour préciser la langue dans laquelle il a été écrit, l'attribut @type utilisé pour les pages de couverture, qui, pour des raisons de traduction sont aussi traitées comme des articles. Enfin, deux autres attributs optionnels, @next et @prev, sont utilisés pour relier les articles d'une série.
Un article est associé à un numéro et à un thème avec les éléments <issueref> et <themeref>, les deux ayant un attribut @href. La valeur de cet attribut doit être une ID unique, l'ID du numéro ou du thème associé.
Un exemple:
<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>
Un élément localisé d'<article> ressemble à:
<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>
Notez que cette traduction est réservée à une certaine date, effectuée et relue. Dans tous les cas, la personne qui a fait le travail est liée aux éléments <personref>.
Pour tous ces éléments, la meilleure manière d'apprendre c'est la base de données proprement dite :
Une des raisons de lancer ce nouveau format était d'en récupérer automatiquement des index . Maintenant que nous comprenons (?) le format de la base, voyons comment lui faire générer des pages.
D'abord un peu d'histoire. La première mouture utilisait des modules Perl pour s'interfacer avec la base de données. Bien que l'interface ait été très propre, l'exécution était très lente. L'information était incluse dans un conteneur XML, appelé Document Object Model (DOM). La plupart des implémentations pour DOM sont néanmoins très lentes, au moins par rapport à l'alternative "Simple Application interface for XML" (SAX).
Mais si la tâche consiste simplement en la génération de pages web, une troisième possibilité semble meilleure : XSLT. C'est un langage de transformation basé sur XML. Plusieurs processeurs XSLT existent actuellement et la plupart des langages de programmation sont supportés. Voici quelque temps, LinuxFocus a publié un article sur XML::XSLT, une des implémentations XSLT en Perl. Depuis la publication de cet article, de nouvelles possibilités sont apparues et je peux en recommander quelque unes:
Les exemples dans le reste de cet article utiliseront Sablotron.Un processeur XSLT réclame deux fichiers en entrée. Le premier est la source XML à transformer. L'autre est la feuille de style XSLT qui définit la transformation. Pour la génération des pages web de LinuxFocus, les feuilles de styles XSLT suivantes sont disponibles:
Pour générer mainindex.html, par exemple, l'équipe Hollandaise lance:
sabcmd stylesheets/mainindex.xslt db/lfdb.nl.xml > ../mainindex.html
Les feuilles de style savent où trouver la base racine en Anglais et n'ont besoin que de la base localisée comme entrée XML. Quelques feuilles réclament un paramètre additionnel:
sabcmd stylesheets/theme.xslt db/lfdb.nl.xml '$theme=appl' > ../Themes/appl.html
L'index.html en Hollandais est aussi généré à partir de la base mais il utilise une initialisation un peu plus complexe. Le fichier index.html est créé avec lfpagecomposer de Guido Socher à partir d'un ensemble de fichiers d'entrée pré-traités. Ils sont générés à partir de fichiers .pre. En voici quelques exemples. Une liste des numéros précédents:
<H2>Vorige nummers</H2> <p>Dit zijn de uitgaven van LinuxFocus in het Nederlands: <ul> <!-- macro xslt previssues --> </ul>Une liste des dix articles les plus récemment traduits:
<H2>Recent vertaalde artikelen</H2>Ces fichiers sont simplement des fragments de HTML avec une macro qui applique une feuille de style à votre base localisée. Le traitement est réalisé par un programme appelé apply_stylesheets.pl qui cherche les commandes <!-- macro xslt [stylesheet] --> et analyse la base avec cette commande. Notez que l'extension .xslt est omise. Notre Makefile contient:
%.shtml: %.pre @echo "Making $*..." @../../xml/bin/apply_stylesheets.pl $*.pre
Les fichiers *.shtml créés sont utilisés par le script lfpagecomposer. Les feuilles de style utilisées pour générer index.html sont: issuetoc.xslt, previssues.xslt et recently_translated.xslt.
Pour utiliser ce système pour d'autres langues, vous devez faire ce qui suit:
La seconde étape est un peu moins élégante. En principe seul le texte en sortie doit être localisé mais les feuilles de style n'ont pas encore de propriétés de localisation. C'est pourtant réalisable et j'aimerais bien que cette fonctionnalité soit ajoutée.
Je peux recommander d'utiliser un éditeur XML compatible DTD. Avec Emacs vous pouvez par exemple utiliser le mode majeur psgml. Ceci vous donnera la possibilité de valider le document (avec nsgmls). Ceci aide beaucoup à éviter les erreurs. Dans Emacs, vous pouvez aussi faire un clic droit pour visualiser les éléments et les attributs à insérer à un endroit spécifique d'un fichier XML. (Merci à Jaime Villate pour son excellente intervention à la conférence LSM à Bordeaux cette année.)
Une autre aide intéressante est fournie par la localisation Hollandaise de la base de données XML. Si vous avez des problèmes, vous pouvez consulter ce fichier. Bien que le contenu soit principalement en Hollandais, vous pouvez voir l'organisation des éléments de la base de données. Si cela ne vous aide pas, vous pouvez toujours m'écrire
Localiser les feuilles de style est probablement un peu plus difficile. Le texte se confond avec les commandes XSLT. Ce dernier ne doit pas être modifié (à moins de savoir ce que vous faites), de manière à préserver ses fonctionnalités. J'envisage de localiser les feuilles de style à l'avenir ce qui signifie que vous n'aurez plus qu'à éditer le fichier qui contient les traductions et pas les commandes XSLT, mais ce n'est pas encore fait.
Bien, ceci devrait vous permettre de démarrer. Vous pouvez copier/coller à partir de la plupart des fichiers Hollandais. Tous les fichiers sont FDL et GPL. Pour l'année prochaine, voici mes projets concernant ce système: