Carnet Wiki

ccmStructureTableauBoucle

comment ça marche : le tableau des boucles

Il s’agit de la structure de données construite par le ccmPhraseur, et lue par ccmCompilateurDeSquelettes pour en déduire le code d’un squelette compilé.

Cette structure est donc le pivot entre deux phases et à l’intéret d’isoler fortement les deux phases.
C’est à dire que si on veut écrire le phraseur autrement, utiliser une autre grammaire de squelettes, ou compiler le résultat différemment, il suffit de modifier l’un des 2 maillons en respectant cette structure intermédiaire.

En fait, il y a deux éléments importants, renvoyés par la fonction phraser : le tableau $boucles listant les boucles, et le tableau $racine listant les éléments de premier niveau du squelette.

Ces tableaux contiennent des objets correspondant aux blocs successifs du squelette. Chaque objet contient éventuellement des objets représentant les éléments de ce bloc (partie avant/après/milieu/sinon d’une boucle ou d’un champ).
ces objets sont du type Boucle, Champ, Idiome, Polyglotte ou Texte.

On va prendre un exemple concret, histoire de s’y retrouver, un squelette article.html simpliste (téléchargeable ici) :

<html><body>
	DEBUT<br/>
	<B_principale>
		avant<br/>
	<BOUCLE_principale(ARTICLES){id_article}{doublons}{par titre}{inverse}>
		#ID_ARTICLE : [ avant (#TITRE|strtr{'e', 'E'}) apres ]<br/>
	</BOUCLE_principale>
		apres<br/>
	</B_principale>
		sinon<br/>
	<//B_principale>
	FIN

	<BOUCLE_racine(RUBRIQUES){racine}>
		<br/>#ID_RUBRIQUE : #TITRE
		<B_arbo><UL>
		<BOUCLE_arbo(RUBRIQUES){id_parent}{par id_rubrique}{tous}>
			<LI>#ID_RUBRIQUE : #TITRE
			<BOUCLE_rec(boucle_arbo)>gni ?</BOUCLE_rec>.<br/><//B_rec>
		</BOUCLE_arbo>
		</UL></B_arbo>
	</BOUCLE_racine>
	<multi>un[en]one[de]eins</multi>
</body></html>

On y trouve successivement du texte (tag html/body), la boucle « principale », du texte, la boucle « racine », du texte.
La variable $racine contient donc 5 éléments : 3 objets de la classe Texte et 2 de la classe Boucle.
Un dump de son contenu est ici

Le tableau $boucles contient 4 objets de la classe Boucle représentant les 4 boucles du squelette
Un dump de son contenu est ici

Les types d’objets

toutes ces classes ont un champ « type » pour les différencier (l’opérateur instanceOf c’est trop facile ;-) et un champ « ligne » qui contient le numéro de ligne correspondant dans le squelette (pour le debug).

-  le type Boucle
Il correspond à l’ensemmble d’une boucle, et c’est le cas le plus complexe. Il contient les champs suivants (à chacun, je note la valeur q’uil a dans le cas de la boucle arbo de l’exemple) :

  • id_boucle : le nom de la boucle (ce qui est après <BOUCLE) (_arbo : notez que le ’_’ est inclus)
  • id_parent : le nom de la boucle englobante (s’il y a lieu) (_racine)
  • avant, milieu, apres, altern : des tableaux d’objets contenant le détail des parties avant, pendant, après, sinon
    (avant:tableau d’un élément, un objet du type Texte, contenant <UL>), apres=idem avec le </UL>,
    milieu=tableau de 7 éléments (texte <LI>, champ ID_RUBRIQUE, texte :,
    champ TITRE, texte « retour à la ligne », boucle _rec et texte « retour à la ligne »),
    altern=tableau vide)
  • lang_select : ?? (null)
  • type_requete : le type de donnée concerné (en gros, la table sql à intéroger) (rubriques)
  • sql_serveur : ?? (null)
  • jointures : les jointures à effectuer (tableau vide)
  • param : les paramètres de la boucle (tableau de 3 objets Texte contenant le texte de chacun des critères de la boucle)
  • criteres : les critères de la boucle sous fome de tableaux d’objets de la classe Critere (tableau de 2 objets Critere. Un à l’opérateur
    id_parent, l’autre à l’opérateur par et le champ param contenant un tableau d’un élément,
    lui même tableau d’un objet Texte contenant id_rubrique (on adore les toroirs ;-))
  • separateur : le contenu de l’éventuel critère séparateur (tableau vide)
  • doublons : vrai s’il y a un critère doublons (null)
  • partie, total_parties, mode_partie : ?? (null tous les 3)
  • externe : ?? (commentaire = appel a partir d’une autre boucle (recursion)) (chaine vide)
  • tout : critere tout (true)
  • plat : critere plat (false)
  • select : les colonnes à sélectionner
  • from : les tables à attaquer
  • where : les conditions
  • join : les tables annexes ?
  • having : clause having (?)
  • limit : la ’tranche’ de lignes à sélectionner
  • group : clause group by
  • order : clause order by
  • default_order : clause order by par défaut ?
  • date : l’éventuelle colonne de type date, pour les critère annee and co ??? (date)
  • hash : ?? (chaine vide)
  • lien : ?? (false)
  • sous_requete : ?? (false)
  • hierarchie : si c’est une boucle hiérarchie ? (chaine vide)
  • statut : ?? (false)
  • id_table : la table principale à attaquer (null)
  • primary : sa clé primaire (ce qu’il faut au moins mettre dans le select) (null)
  • return : le code généré correspondant (null)
  • numrows : ?? (false)
  • fonctions (présent dans mon dump de structure, mais pas déclaré dans le code (tableau contenant les critères)

Les champs select, from ... sont peuplés par la génération de code elle même et non par le parsing, c’est pourquoi ils sont vides
à la sortie du phraseur.

-  le type Champ
Il correspond à une balise seule ou conditionnelle du genre [avant(#machin*|filtre1{params})apres] et contient les champs suivants (à chacun, je note la valeur qu’il a dans le cas de la balise #TITRE de l’exemple) :

  • nom_champ : le nom de la balise (TITRE)
  • nom_boucle : la boucle dans laquelle il est. Il s’agit de la boucle dans laquelle il faut aller chercher la donnée, c’est à dire la boucle
    courante (dans ce cas, nom_boucle est nul), ou une englobante si elle est spécifiée explicitement ou si on l’a déterminé
    automatiquement.
  • avant, apres : des tableaux d’objets contenant le détail des parties avant et après (tableaux d’objets Texte)
  • etoile : vrai si c’est une balise brute (marquée par un *) (false)
  • param : les filtres appliqués (tableau de tableaux, un par filtre, avec premier élément = nom du filtre (ici strtr) et
    suivants = paramètres du filtre, sous forme de tableau d’objets (ici, le premier avec un Texte ’e’ et le second avec un Texte ’E’))
  • fonctions : le source de ces filtres (pour compatibilité d’après un commentaire, mais compatibilité avec quoi ?)
    (tableau d’un tableau contenant deux chaînes : strtr et {'e', 'E'})
  • id_boucle, boucles, type_requete, code, statut, descr : champs pour la production de code, identiques à ceux du type Boucle (tous vides).

-  le type Idiome
Il correspond à un tag <:machin:truc|monFiltre:> et contient les champs :

  • nom_champ : la chaine a traduire
  • module : son module de definition
  • param : les filtres a appliquer au resultat (comme pour un champ)
  • fonctions : source des filtres (comme pour un champ)
  • id_boucle, boucles, type_requete, code, statut, descr : champs pour la production de code, identiques à ceux du type Boucle.

-  le type Polyglotte
Il correspond à un tag <multi> et contient uniquement le champ « traductions » dont les clés sont des langues et les valeurs les traductions associées.

-  le type Texte
C’est le plus simple : il correspond à un extrait de texte brut et contient les champs « texte », ainsi que « avant » et « apres » qui sont inutilisés (à mon avis ?)

- Mise à jour :18 novembre 2007 à 17h25min