Prévisualisation dans un iframe

Le système de prévisualisation en temps réel de l'extension TODD repose sur une architecture bac-à-sable (Sandbox) stricte. Son but est d'afficher le rendu exact de la vue publique d'un module, en temps réel, sans que les styles CSS de l'administration (MMI / Limitless) n'interfèrent avec ceux du contenu, et inversement.

Cet article détaille les 3 mécanismes qui régissent ce système et dont l'implémentation a été mis en place grâce à l'IA.


1. La construction de l'Iframe (Le Bac-à-sable)

L'Iframe n'est pas construit pour charger une page web classique (via une URL). Il est conçu comme un réceptacle vide attendant qu'on lui injecte du code HTML brut correspondant à une page complète.

Dans le fichier plugins/todd/templates/preview_iframe.php, 0on met en place les concepts suivants :

  • Le conteneur absolu : L'Iframe est généré avec des dimensions fixes "idéales" (souvent 1920x1080 pixels pour simuler un écran complet).
  • La propriété srcdoc : Contrairement à l'attribut classique src="url", la balise utilise srcdoc="". Cela indique au navigateur que le contenu du cadre sera une chaîne de caractères HTML fournie dynamiquement, et non un fichier distant à télécharger.
  • L'isolation visuelle et interactive : Pour simuler la responsivité dans un espace réduit (la colonne de droite de l'éditeur), le script JavaScript applique un transform: scale() sur l'Iframe via un ResizeObserver. De plus, un calque transparent (.todd-preview-overlay) est superposé par-dessus l'Iframe avec pointer-events: auto pour empêcher l'utilisateur de cliquer sur les boutons ou les liens à l'intérieur de l'aperçu.

2. Le rendu de la Preview (Le Moteur Backend)

Lorsqu'une mise à jour de l'aperçu est demandée, le serveur (PHP) doit fabriquer le code HTML complet du module en simulant les données du formulaire, sans enregistrer ces données dans la base.

Daqns le fichier plugins/todd/controllers/ToddPreviewRenderer.php, on implémente les actions ci-dessous :

  1. Interception de la requête : Le serveur reçoit une requête AJAX POST contenant toutes les valeurs actuelles du formulaire (le payload brut).
  2. Instanciation factice (Mock) : Le script instancie la classe PHP correspondant au module (ex: ToddEvent) en utilisant son code (ex: todd_event). Si le contenu n'est pas encore sauvegardé, il utilise l'ID 0.
  3. L'injection par Réflexion (ReflectionClass) : Comme l'instance vient d'être créée, ses données proviennent de la base de données (ou sont vides). Le serveur utilise l'API de Réflexion de PHP (ReflectionClass) pour forcer le remplacement de la propriété protégée $payload de l'objet par les données reçues via AJAX.
  4. Simulation d'état : Si l'utilisateur a utilisé la barre d'outils pour "forcer" un état visuel (ex: Teasing, Terminé), le moteur déclare une variable globale (ou un flag) que la méthode getState() du module lira en priorité pour contourner la vraie logique de dates.
  5. Génération du document (Buffer) : Le moteur appelle la méthode d'affichage du module ($moduleInstance->display()) et capture le HTML généré grâce à ob_start() et ob_get_clean().
  6. Assemblage final : Le HTML du module est emballé dans une structure web complète (<html>, <head>, <body>). On y injecte la balise <base href="..."> pour que les chemins relatifs (images, CSS) fonctionnent, ainsi que les fichiers CSS et JS propres au module.
  7. Réponse JSON : Le document complet est renvoyé au navigateur sous forme de chaîne de caractères encapsulée dans un objet JSON ({"status": 1, "html": "<!DOCTYPE html>..."}).

3. L'injection et la Synchronisation (Le Chef d'Orchestre JS)

C'est le navigateur (JavaScript) qui fait le lien entre les frappes au clavier de l'utilisateur et le rendu serveur.

Dans le fichier plugins/todd/assets/js/core_admin_livepreview.js on met en place tout le code destiné à écouter, à collecter, à interroger et à injecter.

  1. Les écouteurs d'événements : Le script place des "oreilles" (Event Listeners) sur le formulaire d'édition. Il réagit aux événements input (frappe clavier), change (sélection, case à cocher) et keyup.
  2. La fonction Anti-Rebond (Debounce) : Pour éviter de bombarder le serveur de requêtes AJAX à chaque lettre tapée, le système utilise un minuteur (setTimeout). Si le délai est de 800ms, le système attend que l'utilisateur arrête de taper pendant 800 millisecondes consécutives avant de déclencher la mise à jour.
  3. La collecte des données (FormData) : Quand le minuteur arrive à zéro, le script aspire toutes les valeurs du formulaire (new FormData(this.formElement)). Il y ajoute les paramètres de la barre de simulation (ratio, mode, état forcé).
  4. La requête AJAX : Les données sont envoyées au serveur.
  5. L'injection finale (srcdoc) : Lorsque le serveur répond avec le document HTML complet validé (voir Étape 2), le script Javascript cible l'Iframe et écrase sa propriété srcdoc ($iframe.prop('srcdoc', parsed.html)).
  6. Rendu navigateur : Le navigateur détecte que le srcdoc a changé, détruit l'ancien document virtuel, et peint le nouveau HTML instantanément, garantissant une synchronisation parfaite avec le formulaire.