*/ private $cache = array(); /** * Cache spécifique pour le template principal de la requête. * * @var array{id:string, tpl_exists:bool, wp_id:int, css:string, js:string}|null */ private $main_cache = null; /** * Cache des assets de tous les template parts customisés (global). * * @var array|null */ private $all_parts_cache = null; /** * Amorçage unique. */ public static function boot() { if (self::$booted) { return; } self::$booted = true; try { new self(); } catch (\Throwable $e) { // Silencieux : mieux vaut ne rien injecter que casser le site. } } public function __construct() { // Ne tourner que sur un rendu front classique. if (is_admin()) { return; } if (defined('DOING_AJAX') && DOING_AJAX) { return; } if (defined('DOING_CRON') && DOING_CRON) { return; } if (defined('REST_REQUEST') && REST_REQUEST) { return; } // On injecte tout via wp_head / wp_footer plutôt que render_block // pour rester robuste quand le template parent inline directement // le contenu du header/footer et ne référence plus le template-part // en tant que bloc. add_action('wp_head', array($this, 'inject_main_template_css'), 100); add_action('wp_footer', array($this, 'inject_main_template_js'), 100); } /** * Pour chaque bloc core/template-part rendu, on préfixe le contenu * par un '; } $suffix = ''; if ($lookup['js'] !== '') { $suffix .= ''; } return $prefix . $block_content . $suffix; } catch (\Throwable $e) { return $block_content; } } /** * Émet un commentaire HTML sûr (pas de "--" qui pourrait fermer * prématurément un commentaire, pas de retour chariot). */ private function debug_comment($line) { $line = (string) $line; $line = str_replace(array("\r", "\n"), ' ', $line); $line = str_replace('--', '- -', $line); return "\n\n"; } /** * CSS du template principal + CSS de tous les template parts customisés * par l'utilisateur, émis dans . * * On injecte tous les template parts sans dépendre du filtre * render_block parce que certains thèmes / customisations inlineent * directement le contenu du header/footer et ne conservent plus de * bloc core/template-part dans le template parent. */ public function inject_main_template_css() { try { $info = $this->get_main_template_info(); echo $this->debug_comment( 'ai-builder main template (head): id=' . ($info['id'] !== '' ? $info['id'] : '(empty)') . ' tpl_exists=' . ($info['tpl_exists'] ? 1 : 0) . ' wp_id=' . (int) $info['wp_id'] . ' css_len=' . strlen($info['css']) . ' js_len=' . strlen($info['js']) ); if ($info['css'] !== '') { echo ''; } $parts = $this->get_all_template_parts_assets(); echo $this->debug_comment( 'ai-builder template parts (head): count=' . count($parts) . ' ids=' . $this->summarize_part_ids($parts) ); foreach ($parts as $part) { if ($part['css'] === '') { continue; } $id_suffix = $this->sanitize_html_id($part['id']); echo ''; } } catch (\Throwable $e) { // silencieux } } /** * JS du template principal + JS de tous les template parts customisés, * émis dans