Réflexions sur une DTD pour plugin.xml

, par _Eric_

Cet article est une version préliminaire de Des DTD pour décrire et archiver les plugins et ne reste publié que pour des raisons historiques.

Le fichier décrivant un Plugin SPIP se nomme plugin.xml, mais n’est pas toujours tout à fait conforme à XML. Sa spécification conduit souvent à des fichiers inutilement verbeux, et n’utilisant pas toutes les possibilités de ce formalisme permettant de prévenir d’éventuelles erreurs par simple application d’un validateur XML.

On propose ici une nouvelle spécification de ce fichier essayant d’éviter ces problèmes.

Pour ceux qui ne sont pas familiers avec le formalisme des DTD, rappelons que la directive ELEMENT déclare le nom d’une balise et de quoi elle est composée (éventuellement de rien, avec le mot-clé EMPTY : seuls les attributs en justifient l’existence). La directive ATTLIST déclare les attributs de cette balise sous forme de trio nom, type, présence. La directive ENTITY déclare juste une abréviation (mais son nom est souvent porteur d’informations informelles). Pour plus de précisions se reporter à la
définition officielle de XML.

Le but du fichier plugin.xml est d’indiquer le nom du plugin, de décrire son intention et de donner des informations techniques sur ses différentes réalisations. Un même fichier plugin.xml peut décrire plusieurs réalisations, afin que les développeurs puissent maintenir un seul jeu de fichiers pour différentes réalisations, seul les points d’entrées décrits dans ce fichier étant changés. Cela conduit à avoir une balise racine spip-plugin englobant une suite non vide de balises plugin contenant elles-mêmes chacune des balises de description. En revanche un niveau supplémentaire d’emboîtement n’est pas nécessaire, les informations à fournir n’étant pas structurées. Par ailleurs, il est préférable d’employer autant que possible des attributs afin d’avoir des balises auto-fermantes, plus concises à écrire. Enfin, on a utilisé les entités XML pour typer implicitement les attributs, qui pourront facillement être analysés par des RegExp appropriés.

On a repris les noms des balises actuellement utilisées dans plugin.xml pour SPIP <= 2.1, mais lorsque le niveau d’emboîtement apparaissait superflu, cette balise est devenue un nom d’attribut de sa balise mère. Toutefois le nom ID n’a pas pas été repris quand ça n’était pas compatible avec son statut particulier en XML exigeant la non répétition de sa valeur dans un même document.

Voici donc cette proposition :

<!ENTITY % MAIL "CDATA"> <!-- adresse mail -->
<!ENTITY % NAME "CDATA"> <!-- identificateur (notamment nom de fonction) -->
<!ENTITY % NUMBER "CDATA"> <!-- nombre entier naturel -->
<!ENTITY % PATH "CDATA"> <!-- chemin d'acces a un fichier ou repertoire -->
<!ENTITY % QUERY_STRING "CDATA"> <!-- couples x=y separes par esperluete -->
<!ENTITY % URI "CDATA"> <!-- lien sur le Web -->
<!ENTITY % VNUM "CDATA"> <!-- 3 entiers naturels separes par un point: x.y.z -->

<!ELEMENT spip-plugin (description plugin+) >
<!ATTLIST spip-plugin
          id ID #REQUIRED
>

<!ELEMENT description (#PCDATA)>

<!ELEMENT plugin (auteur|bouton|chemin|necessite|onglet|pipeline|utilise)* >
<!ATTLIST plugin
          prefix %NAME #REQUIRED
          categorie %NAME #IMPLIED
          etat (experimental|dev|test|stable) #REQUIRED
          licence #CDATA #REQUIRED
          lien %URI #IMPLIED
          logo %PATH #IMPLIED
          version %VNUM #REQUIRED
          version_base %NUMBER #IMPLIED
          install %PATH #IMPLIED
          options %PATH #IMPLIED
          fonctions %PATH #IMPLIED
          meta %NAME #IMPLIED
>

<!ELEMENT auteur (#PCDATA)>
<!ATTLIST auteur
          mail %MAIL #IMPLIED
>

<!ELEMENT chemin EMPTY>
<!ATTLIST chemin
          path %PATH #REQUIRED
          type %NAME #IMPLIED
>

<!ELEMENT pipeline EMPTY>
<!ATTLIST pipeline
          nom %NAME #REQUIRED
          action %NAME #REQUIRED
          path %PATH #IMPLIED
>

<!ELEMENT necessite EMPTY>
<!ATTLIST necessite
          nom %NAME #REQUIRED
          version %VNUM #REQUIRED
>

<!ELEMENT utilise EMPTY>
<!ATTLIST utilise
          nom %NAME #REQUIRED
          version %VNUM #REQUIRED
>

<!ELEMENT bouton EMPTY>
<!ATTLIST bouton
          nom %NAME #REQUIRED
          parent %NAME #REQUIRED
          action %NAME  #REQUIRED
          args %QUERY_STRING #REQUIRED
          icone %PATH #IMPLIED
>

<!ELEMENT onglet EMPTY>
<!ATTLIST onglet
          nom %NAME #REQUIRED
          parent %NAME #REQUIRED
          action %NAME  #REQUIRED
          args %QUERY_STRING #REQUIRED
          icone %PATH #IMPLIED
>