'Secteurs', "Built for those who carry the weight." => "Conçu pour celles et ceux qui en portent le poids.", "Police, special forces, military, and emergency services share a hard truth: their craft is rehearsed in the worst conditions, and rarely enough. PROSERVE\u{2122} puts contemporary training within everyone's reach \u{2014} every shift, every budget, every operating context." => "Police, forces spéciales, armée et services d'urgence partagent une vérité dure : leur métier se répète dans les pires conditions, et trop rarement. PROSERVE\u{2122} met l'entraînement contemporain à la portée de tous \u{2014} chaque service, chaque budget, chaque contexte opérationnel.", "Four operating contexts. One platform." => "Quatre contextes opérationnels. Une seule plateforme.", // Card eyebrows + tile labels 'National & Municipal' => 'Nationale & Municipale', 'Police' => 'Police', "Police training, when the schedule won't bend." => "L'entraînement police, quand l'agenda ne fléchit pas.", 'Tactical units' => 'Unités tactiques', 'Special Forces' => 'Forces spéciales', "Special forces train differently. Their simulation should, too." => "Les forces spéciales s'entraînent autrement. Leur simulation devrait suivre.", 'Armed forces' => 'Forces armées', 'Military' => 'Armée', "Military VR training. Sovereign. Modular. Field-deployable." => "Entraînement VR pour l'armée. Souverain. Modulaire. Déployable sur le terrain.", 'Emergency services' => "Services d'urgence", 'Firefighters' => 'Sapeurs-pompiers', "Train the worst day. Safely. Repeatedly." => "Entraînez-vous au pire jour. En sécurité. Indéfiniment.", // Card body concatenations from hub builder "National & Municipal \u{2014} Police training, when the schedule won't bend." => "Nationale & Municipale \u{2014} L'entraînement police, quand l'agenda ne fléchit pas.", "Tactical units \u{2014} Special forces train differently. Their simulation should, too." => "Unités tactiques \u{2014} Les forces spéciales s'entraînent autrement. Leur simulation devrait suivre.", "Armed forces \u{2014} Military VR training. Sovereign. Modular. Field-deployable." => "Forces armées \u{2014} Entraînement VR pour l'armée. Souverain. Modulaire. Déployable sur le terrain.", "Emergency services \u{2014} Train the worst day. Safely. Repeatedly." => "Services d'urgence \u{2014} Entraînez-vous au pire jour. En sécurité. Indéfiniment.", // Hero / detail-page CTA labels specific to Industries 'Request a Demo for police use' => 'Demander une démo pour la police', 'Request a Demo for fire & emergency' => "Demander une démo pour pompiers & urgences", ]); }); /* ----------------------------------------------------------------- URL trigger — fires on template_redirect (NOT init) so Bricks's element controls are loaded (happens on 'wp' hook). Without loaded controls, Bricks's wpml_page_builder_register_strings handler skips every element silently and NO strings reach icl_strings → ATE empty. ----------------------------------------------------------------- */ add_action('template_redirect', function () { if (empty($_GET['av_generate_industries'])) return; if (! in_array($_SERVER['SERVER_NAME'] ?? '', ['localhost', '127.0.0.1'], true)) wp_die('localhost only'); $data_file = 'C:\\ASTERION\\GIT\\WP2026\\content-source\\industries-data.php'; if (! file_exists($data_file)) wp_die("data file not found: $data_file"); $industries = include $data_file; if (! is_array($industries)) wp_die('industries data not array'); $parent_id = av_ensure_hub_page('industries', 'Industries'); $report = ["Rebuilding /industries/ hub + child detail pages..."]; // Hub $hub_elements = av_build_industries_hub_elements($industries); $hub_write = av_write_bricks_page_elements($parent_id, $hub_elements); $report[] = " HUB → page #$parent_id (rebuilt) — " . count($hub_elements) . " elements (json={$hub_write['json_len']}, stored={$hub_write['stored_len']})"; // Detail pages foreach ($industries as $slug => $d) { $page = av_upsert_detail_page($slug, 'industries', $d); $report[] = " $slug → page #{$page['id']} ({$page['action']}) — {$page['element_count']} elements (json={$page['json_len']}, stored={$page['stored_len']})"; } header('Content-Type: text/plain; charset=utf-8'); echo implode("\n", $report); exit; }); /* ----------------------------------------------------------------- Industries hub builder : hero + 4-card grid + closer CTA ----------------------------------------------------------------- */ function av_build_industries_hub_elements($industries) { $els = []; // HERO $els = array_merge($els, av_build_hero('hub', [ 'eyebrow' => 'Industries', 'tagline' => "Built for those who carry the weight.", 'hero_lead' => "Police, special forces, military, and emergency services share a hard truth: their craft is rehearsed in the worst conditions, and rarely enough. PROSERVE\u{2122} puts contemporary training within everyone's reach \u{2014} every shift, every budget, every operating context.", 'ctas' => [ ['label' => 'Book a demo', 'href' => '/request-demo/', 'variant' => 'primary'], ['label' => 'Request a T&E Kit', 'href' => '/request-te-kit/', 'variant' => 'secondary'], ], ])); // 4-card grid — one card per industry $cards_section = [ 'eyebrow' => '', 'title' => 'Four operating contexts. One platform.', 'items' => [], ]; foreach ($industries as $slug => $d) { $cards_section['items'][] = [ 'title' => $d['title'], 'body' => ($d['eyebrow'] ?? '') . " \u{2014} " . ($d['tagline'] ?? ''), ]; } $els = array_merge($els, av_build_cards_section('hubgrid', 0, $cards_section, 'var(--color-bg-subtle)')); // Append "Learn more →" link in each card (post-build patch) $i = 0; foreach ($industries as $slug => $d) { $kid = "khubgridc0x{$i}"; $lid = "lnhubgridc0x{$i}"; $els[] = av_text_link($lid, $kid, "Learn more \u{2192}", "/industries/$slug/"); foreach ($els as &$el) { if (($el['id'] ?? '') === $kid) { $el['children'][] = $lid; } } unset($el); $i++; } // CLOSER CTA $els = array_merge($els, av_build_closer_cta('hub')); return $els; }