Les générateurs des pages d'un site sont écrits par le ou les concepteurs de celui-ci. Ils tirent leur puissance de l'utilisation de composants communs, car ils ne doivent pas utiliser directement des instructions actives.
Quelle solution retenir pour leur écriture garantissant le cloisonnement des sites : contrôle préalable des fichiers source ou écriture de ceux-ci dans un langage spécifique ?

1. Problèmes

L'article Génération des pages présente succinctement le processus de présentation du contenu d'un site aux internautes et l'article Gestion des générateurs les évolutions prévues pour un développement intelligent des sites.

Les gabarits et les vues d'un site sont gérés par le ou les concepteurs de celui-ci. Il faut donc s'assurer qu'ils ne peuvent pas utiliser les données des autres sites et celles sur les utilisateurs autres que ce qui leur est nécessaire pour la gestion des leurs abonnés et de leurs membres. Il faut également garantir qu'ils ne peuvent pas menacer le bon fonctionnement de l'application.

Pour ce faire, le code d'un générateur de site doit être soit écrit dans un langage spécifique limitant les possibilités, soit contrôler par un module au moment de l'introduction ou de la modification du générateur. Tant que les contraintes sur le code ne sont pas trop grandes, la mise en place d'un contrôleur semble la plus simple à mettre en œuvre ; elle permet aussi une migration progressive des générateurs déjà écrits et donne un souplesse de gestion en autorisant des générateurs ne passant pas les contrôles sous la responsabilités des super-administrateurs.

Les vues seront écrites en HAML. Voir l'article Le langage de vues HAML.

Rappel : Dans la base de données, commune à tous les sites, toutes les tables enregistrant des données spécifiques à un site comportent une colonne qui identifie ce site ou qui reste vide pour les données communes (cas des composants communs).

2. 2. Analyse de l'existant

Le code source des générateurs de site actuels : projetA-Generateurs-0.8-120909.pdf (180 ko).

Les générateurs des premiers sites réalisés sur le projet ne sont pas tous au même niveau d'intégration, soit parce que ceux qui ont servis de référence ont été plus travaillés (sites DM, CM), soit parce que certains des besoins particuliers qui n'ont pas encore été intégrés dans les composants existants ou par des nouveaux (sites CEP, JG).

2.1. Générateurs vues

La plupart des générateurs vues d'espaces ou d'œuvres appellent par la fonction render un ou plusieurs composants génériques, avec ou sans paramètres, le plus souvent précédé de la déclaration d'un bloc div HTML identifié par une étiquette (#label) ou qualifié par une le nom d'une classe (.class) pour structurer la présentation de la page et pour fournir des ponts de spécification pour la feuille de styles CSS. Un générateur (cl_rubrique) est même vide, car il génère une page de navigation complètement produite par le gabarit.

Le code de plusieurs générateurs comportent des lignes .clear assurant une fonction de formatage (commande CSS clear:both;) qui pourrait sans doute plus logiquement être intégrée dans la feuille de styles.

Idem pour la ligne %hr qui génère une balise HTML <hr /> produisant une ligne horizontale et qui peut être remplacée par une bordure de bloc en CSS.

Les vues aio_home, aio_chapter, ptk_chapter, cep_accueil, cep_chapitre, cep_contact intègre des balises HTML et du texte statiques pour ajouter un titre de section.

Les vues cm_dessinscs_galerie2 pourraient utiliser un composant existant.

Les vues aio_chapterptk_chapter, ptk_home, cep_chapitre, jg_livre pourraient utiliser des composants à créer.

Les vues cm_accueil, cm_photo,  cs_tableau, jg_livre insère une image par une fonction d'assistance (image_tag ou site_image_tag), ce qui pourrait aussi être réalisé par un composant.

Les vues cep_documents, cep_repetitions appellent des partiels propres au site.

Les vues cm_dessinptk_home, jg_categorie comprennent des fonctions de navigation qu'il serait plus logique de reporter dans le gabarit.

Les vues cep_evenement, cep_rubrique, jg_contact comporte du code avant l'appel d'un composant, code qui pourrait être intégré au composant.

La vue dm_accueil2 déclare un bloc CSS injecté dans le gabarit par l'instruction content_for.

Les valeurs des paramètres des composants appelés sont définis par des constantes ou des variables globales.

2.2. Générateurs gabarits

Les générateurs gabarits sont légèrement plus complexes que les vues, car ils doivent gérer la présentation générale des pages et la navigation et ils doivent s'adapter aux différents contextes du site. Par rapport à une vue, un gabarit utilise :

  • les déclarations d'entête HTML ;
  • l'instruction yield précisant la place de l'insertion du code d'une vue ;
  • l'appel d'un autre gabarit (render :template).

Les gabarits sont actuellement tous spécifiques des sites, sauf pour les pages d'introduction, très simples, qui utilise un gabarit commun. On peut toutefois imaginer une évolution du projet A vers la mise en place de gabarits communs pour la réalisation rapide de sites, mais en conséquence d'une esthétique plus similaire.

3. Contrôle ou compilation des générateurs ?

Deux types de solutions sont possibles pour le codage des générateurs pour garantir la sécurité de cloisonnement des sites : soit contrôler les fichiers source HAML au moment de leur introduction dans le système, soit écrire les sources dans un langage spécifique conçu en fonction de l'objectif fixé puis leur compilation en HAML.

Obligatoire pour les générateurs de site, la solution retenue sera appliquée autant que possible aux composants communs, même si certains ont pour vocation l'accès contraint à des données sensibles de la base.

3.1. Contrôle des générateurs

Cette solution impose de filtrer le code source des générateurs pour éviter l'utilisation d'instructions dangereuses, d'autant le langage HAML permet l'intégration de code en Ruby par interpolation d'une chaine de caractères.

Instructions autorisées

  • commentaires Ruby '-#' et HTML '/'
  • texte statique, y compris le caractère d'échappement '\'
  • identifiants '#' et classes '.' CSS
  • balises HTML
  • appel sortant d'un composant, d'un partiel ou d'un gabarit
  • coupure des lignes '|'
  • valeurs par défaut des paramètres d'appel entrant

Implémentation

  • contrôle avant enregistrement du code et avant affichage
  • variables d'état generators.is_validated et generators.validated_at
  • enregistrement d'un générateur invalide réservé aux super-administrateurs

Avantages et inconvénients

  • (+) pas d'écriture de compilateur → a priori, moins de développement
  • (–) risque de laisser passer des trous de sécurité sur des syntaxes non connues, donc non filtrées

3.2. Compilation des générateurs

Instructions nécessaires

  • les mêmes que celles du chapitre précédent
  • échappement vers du code HAML (réservé aux super-administrateurs)

Implémentation

  • écriture d'un compilateur produisant des fichiers HAML intermédiaires, utilisés pour la production des pages servies
  • possibilité d'enregistrement d'un fichier HAML réservé aux super-administrateurs

Avantages et inconvénients

  • (+) contrôle précis des instructions autorisées
  • (+) évolution progessive des spécifications
  • (+) pas de gestion des versions des fichiers source
  • (–) définition d'un langage spécifique et développement d'un compilateur

3.3. Conclusion

La solution d'un compilateur est retenue. Même si elle semble de premier abord plus complexe à implémenter, elle permet un contrôle précis de la sécurité et un développement progressif par l'ajout décidé de fonctionalités.

La langage est appelé GAL pour generators of the A project language = langage pour les générateurs du projet A.

version 0.8.6-0240-121031
↑ Haut