feat(en-pages): build remaining 14 pages (Editorial / Forms / Hubs / Legal)

Brings the EN site to 34 live pages, completing the original sitemap
from PDF Strategie & Contenu Partie C.1.

Editorial section (5 pages, page-editorial-detail.php template)
- /why-asterion/, /about/, /customers/, /trust/, /partners/
- inc/editorial-data.php centralizes the copy from D.18-D.21, D.28
- Reuses the industry-detail partial (same section schema)

Conversion section (4 pages, page-conversion-form.php template)
- /request-demo/, /request-te-kit/, /request-quote/, /contact/
- inc/forms-data.php declares fields per page (text/email/select/textarea)
- template-parts/conversion-form.php renders two-column layout
  (form left, promise right), eligibility list (T&E), FAQ (Demo)
- inc/form-handler.php: nonce-protected POST handler with honeypot,
  per-field sanitizer, wp_mail to AV_LEADS_RECIPIENT (defaults to
  jerome.foucher@asterionvr.com, override via wp-config.php define),
  redirect-back-with-status pattern.

Insights & Resources (page-insights-hub.php, page-resources.php)
- /insights/ queries `post`, falls back to placeholder when empty
- /resources/ lists 4 resource groups (datasheets, whitepapers,
  videos, brochures) per D.23

Legal (page-legal.php template, parent + 4 children)
- /legal/, /legal/privacy/, /legal/terms/, /legal/cookies/, /legal/notice/
- Renders page content if filled, falls back to slug-driven section
  skeleton (per D.29) for counsel to draft against.

All 16 new URLs verified HTTP 200, sizes 49-66 KB each. Mu-plugin
asterion-seed-rest.php in LocalWP self-deleted after seeding.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-09 12:41:36 +02:00
parent 45b0b95232
commit 70864129ed
10 changed files with 1066 additions and 2 deletions

View File

@@ -0,0 +1,27 @@
<?php
/**
* Template Name: Conversion Form
*
* Custom page template for /request-demo/, /request-te-kit/, /request-quote/, /contact/.
*
* @package AsterionBricks
*/
defined('ABSPATH') || exit;
$slug = get_post_field('post_name', get_queried_object_id());
$data = include AV_THEME_DIR . '/inc/forms-data.php';
if (! isset($data[$slug])) {
get_header();
echo '<section class="av-section"><div class="av-container">';
echo '<h1>' . esc_html(get_the_title()) . '</h1>';
echo '<p>' . esc_html__('Form data not found for slug:', 'asterion-bricks') . ' ' . esc_html($slug) . '</p>';
echo '</div></section>';
get_footer();
return;
}
get_header();
set_query_var('av_form', $data[$slug]);
get_template_part('template-parts/conversion-form');
get_footer();

View File

@@ -0,0 +1,28 @@
<?php
/**
* Template Name: Editorial Detail
*
* Custom page template for editorial pages (Why Asterion, About, Customers
* hub, Trust, Partners). Reuses the industry-detail partial.
*
* @package AsterionBricks
*/
defined('ABSPATH') || exit;
$slug = get_post_field('post_name', get_queried_object_id());
$data = include AV_THEME_DIR . '/inc/editorial-data.php';
if (! isset($data[$slug])) {
get_header();
echo '<section class="av-section"><div class="av-container">';
echo '<h1>' . esc_html(get_the_title()) . '</h1>';
echo '<p>' . esc_html__('Editorial data not found for slug:', 'asterion-bricks') . ' ' . esc_html($slug) . '</p>';
echo '</div></section>';
get_footer();
return;
}
get_header();
set_query_var('av_industry', $data[$slug]);
get_template_part('template-parts/industry-detail');
get_footer();

View File

@@ -0,0 +1,87 @@
<?php
/**
* Template Name: Insights Hub
*
* /insights/ — blog hub. Lists native `post` items as blog cards.
*
* @package AsterionBricks
*/
defined('ABSPATH') || exit;
get_header();
$home_url = home_url('/');
?>
<section class="av-hero" aria-labelledby="insights-headline">
<div class="av-hero__media" aria-hidden="true">
<div style="width:100%;height:100%;background:
radial-gradient(ellipse at 60% 40%, rgba(201,164,90,0.12), transparent 60%),
linear-gradient(135deg, #081427 0%, #0B1F3A 70%, #13294B 100%);"></div>
</div>
<div class="av-container">
<div class="av-hero__inner">
<p class="av-hero__eyebrow"><?php esc_html_e('Insights', 'asterion-bricks'); ?></p>
<h1 id="insights-headline" class="av-hero__headline">Notes from the front of immersive training.</h1>
<p class="av-hero__sub">
Doctrine. Training science. Instructor stories. AAR data. Comparisons of VR vs live training. Found something useful? It probably came from a customer conversation. We publish what we learn.
</p>
</div>
</div>
</section>
<section class="av-section" data-av-reveal>
<div class="av-container">
<?php
// Categories filter chips (placeholders — wired to native `category` taxonomy if used).
$categories = ['Doctrine', 'Technology', 'Case Studies', 'Industry News', "Founder's Notes"];
?>
<div style="display:flex;flex-wrap:wrap;gap:var(--space-3);margin-bottom:var(--space-10);">
<?php foreach ($categories as $cat) : ?>
<span class="av-btn av-btn--ghost av-btn--sm" style="border:1px solid var(--color-border-default);"><?php echo esc_html($cat); ?></span>
<?php endforeach; ?>
</div>
<?php $posts = get_posts(['numberposts' => 12, 'post_status' => 'publish']); ?>
<?php if (! empty($posts)) : ?>
<div class="av-grid-3">
<?php foreach ($posts as $post) : setup_postdata($post); ?>
<article class="av-card av-card--blog">
<a href="<?php the_permalink(); ?>" class="av-card__media" aria-hidden="true" tabindex="-1" style="background:linear-gradient(135deg,#CCD3DC,#E5E9EE);"></a>
<div class="av-card__body">
<span class="av-card__eyebrow"><?php echo esc_html(get_the_date('M j, Y')); ?></span>
<h2 class="av-card__title"><a href="<?php the_permalink(); ?>" style="color:inherit;text-decoration:none;"><?php the_title(); ?></a></h2>
<p class="av-card__excerpt"><?php echo esc_html(wp_trim_words(get_the_excerpt(), 22)); ?></p>
<div class="av-card__cta"><a href="<?php the_permalink(); ?>" class="av-link av-link--with-arrow"><?php esc_html_e('Read more', 'asterion-bricks'); ?></a></div>
</div>
</article>
<?php endforeach; wp_reset_postdata(); ?>
</div>
<?php else : ?>
<p style="color:var(--color-text-muted);max-width:64ch;">
<?php esc_html_e('Editorial blog launches with the site go-live. The 12-month content calendar is in the Strategy & Content brief, section B.4. New articles will appear here as soon as they ship.', 'asterion-bricks'); ?>
</p>
<?php endif; ?>
</div>
</section>
<section class="av-section av-section--dark" data-av-reveal>
<div class="av-container">
<div style="display:grid;grid-template-columns:1fr;gap:var(--space-8);align-items:center;" class="av-newsletter-row">
<div>
<span class="av-eyebrow av-eyebrow--gold"><?php esc_html_e('Newsletter', 'asterion-bricks'); ?></span>
<h2 style="font-family:var(--font-display);font-size:var(--text-h1);line-height:var(--leading-h1);color:var(--color-text-on-dark);margin:var(--space-3) 0;">Subscribe — one article per month.</h2>
<p style="color:var(--color-text-on-dark-muted);max-width:60ch;">
Insights from the front of immersive training. One email per month. No spam. Unsubscribe in one click.
</p>
</div>
<form method="post" action="#" style="display:flex;gap:var(--space-3);flex-wrap:wrap;align-items:flex-start;" aria-label="<?php esc_attr_e('Newsletter signup', 'asterion-bricks'); ?>">
<label for="av-insights-newsletter" class="av-sr-only"><?php esc_html_e('Your email', 'asterion-bricks'); ?></label>
<input type="email" id="av-insights-newsletter" name="email" class="av-input" placeholder="<?php esc_attr_e('your@email.com', 'asterion-bricks'); ?>" required style="flex:1;min-width:200px;">
<button type="submit" class="av-btn av-btn--primary av-btn--md"><?php esc_html_e('Subscribe', 'asterion-bricks'); ?></button>
</form>
</div>
<style>@media (min-width: 768px) { .av-newsletter-row { grid-template-columns: 2fr 1.5fr !important; } }</style>
</div>
</section>
<?php get_footer(); ?>

View File

@@ -0,0 +1,92 @@
<?php
/**
* Template Name: Legal
*
* /legal/privacy/, /legal/terms/, /legal/cookies/, /legal/notice/.
* Renders the WP page content (filled in by counsel) inside the standard
* narrow container with a clean editorial hero.
*
* @package AsterionBricks
*/
defined('ABSPATH') || exit;
get_header();
?>
<section class="av-section">
<div class="av-container av-container--narrow">
<header class="av-section__head">
<span class="av-eyebrow"><?php esc_html_e('Legal', 'asterion-bricks'); ?></span>
<h1 class="av-section__title"><?php the_title(); ?></h1>
<p class="av-section__lead">
<?php esc_html_e('Last updated:', 'asterion-bricks'); ?>
<?php echo esc_html(get_the_modified_date()); ?>
</p>
</header>
<div class="av-prose" style="font-size:var(--text-body-md);line-height:var(--leading-body-md);color:var(--color-text-secondary);">
<?php
if (have_posts()) :
while (have_posts()) : the_post();
the_content();
endwhile;
endif;
// Default skeleton when the page content is empty — populated by counsel later.
$content = get_post_field('post_content', get_queried_object_id());
if (trim($content) === '') :
?>
<p style="padding:var(--space-6);background:var(--color-bg-subtle);border-left:3px solid var(--color-warning);border-radius:var(--radius-sm);">
<strong><?php esc_html_e('Placeholder.', 'asterion-bricks'); ?></strong>
<?php esc_html_e('This page is to be drafted with legal counsel. The structure below outlines the sections expected.', 'asterion-bricks'); ?>
</p>
<?php
// Slug-driven placeholder sections.
$slug = get_post_field('post_name', get_queried_object_id());
$skeletons = [
'privacy' => [
'Data controller (Asterion VR), contact, DPO if relevant',
'Data collected (form submissions, cookie identifiers, IP, etc.)',
'Purpose of processing (sales follow-up, newsletter, analytics)',
'Legal basis (consent, contract, legitimate interest)',
'Retention periods',
'Data sharing (subcontractors, hosts)',
'Data subject rights (access, rectification, deletion, portability, objection)',
'Complaint procedure (CNIL link)',
],
'terms' => [
'Site usage conditions',
'Intellectual property',
'Liability limitations',
'Applicable law and jurisdiction',
],
'cookies' => [
'List of cookies (functional, analytics, marketing)',
'Cookie purpose, retention, third parties',
'Consent management procedure',
],
'notice' => [
'Asterion VR — RCS 821 520 970 Rennes — NAF 6201Z — SIRET 821 520 970 00012',
'Adresse, téléphone, e-mail, directeur de la publication',
'Hébergeur',
],
];
if (isset($skeletons[$slug])) :
?>
<h2 style="font-family:var(--font-display);font-size:var(--text-h3);margin-top:var(--space-10);margin-bottom:var(--space-4);"><?php esc_html_e('Sections to include', 'asterion-bricks'); ?></h2>
<ul style="display:flex;flex-direction:column;gap:var(--space-2);padding-left:var(--space-6);">
<?php foreach ($skeletons[$slug] as $line) : ?>
<li style="list-style:disc;"><?php echo esc_html($line); ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php endif; ?>
</div>
</div>
</section>
<?php get_footer(); ?>

View File

@@ -0,0 +1,100 @@
<?php
/**
* Template Name: Resources
*
* /resources/ — datasheets, whitepapers, videos, brochures.
*
* @package AsterionBricks
*/
defined('ABSPATH') || exit;
get_header();
$home_url = home_url('/');
$groups = [
[
'eyebrow' => 'Datasheets',
'title' => 'Technical specifications.',
'items' => [
['title' => 'PROSERVE — full datasheet', 'note' => 'Hardware specifications, software capabilities, scenarios. Gated, light form.'],
['title' => 'MY PROSERVE — quick datasheet', 'note' => '4-page summary.'],
['title' => 'PROSERVE FLEX — quick datasheet', 'note' => '4-page summary.'],
['title' => 'PROSERVE ACADEMY — quick datasheet', 'note' => '4-page summary.'],
['title' => 'PROSERVE+ — customization brochure', 'note' => 'Hardware add-ons, custom scenarios, process.'],
],
],
[
'eyebrow' => 'Whitepapers',
'title' => 'Long-form analyses.',
'items' => [
['title' => 'VR vs Live Fire: the 2026 cost-benefit comparison', 'note' => 'Quantified comparison across cost, fidelity, scalability, environmental.'],
['title' => "The Instructor's Guide to VR Training Programs", 'note' => "Methodology, drill design, AAR debriefing, assessment frameworks."],
['title' => 'Use of Force Training: how immersive simulation reduces tactical errors', 'note' => 'Reviews academic literature and Asterion deployment data.'],
['title' => 'Sovereignty in security simulation: why your training data must never leave your network', 'note' => 'For procurement and IT teams.'],
],
],
[
'eyebrow' => 'Videos',
'title' => 'Show, not tell.',
'items' => [
['title' => 'PROSERVE — 90-second product film', 'note' => 'Cinematic overview.'],
['title' => 'Instructor Cockpit walkthrough (3 minutes)', 'note' => 'Inside the instructor PC.'],
['title' => 'AAR replay — annotated example (4 minutes)', 'note' => 'A drill replayed with overlays.'],
['title' => 'MY PROSERVE — unboxing & first deployment (6 min)', 'note' => 'From mini-case to first scenario in real time.'],
['title' => 'Customer story — [name redacted unit] (8 min)', 'note' => 'Operational deployment, instructor interview, AAR excerpts.'],
],
],
[
'eyebrow' => 'Brochures',
'title' => 'For procurement and end-user briefs.',
'items' => [
['title' => 'PROSERVE general brochure', 'note' => '8 pages, EN/FR.'],
['title' => 'Industry-specific brochures', 'note' => 'Police, Special Forces, Military, Firefighters — one PDF each.'],
],
],
];
?>
<section class="av-hero" aria-labelledby="resources-headline">
<div class="av-hero__media" aria-hidden="true">
<div style="width:100%;height:100%;background:linear-gradient(135deg, #081427 0%, #0B1F3A 50%, #13294B 100%);"></div>
</div>
<div class="av-container">
<div class="av-hero__inner">
<p class="av-hero__eyebrow"><?php esc_html_e('Resources', 'asterion-bricks'); ?></p>
<h1 id="resources-headline" class="av-hero__headline">Everything to evaluate, justify, and procure.</h1>
<p class="av-hero__sub">
Whether you are building an internal pitch, drafting a procurement specification, or briefing your team — these resources are designed to help.
</p>
</div>
</div>
</section>
<?php foreach ($groups as $idx => $group) :
$is_dark = ($idx % 2 === 1);
$section_class = 'av-section' . ($is_dark ? ' av-section--dark' : '');
?>
<section class="<?php echo esc_attr($section_class); ?>" data-av-reveal>
<div class="av-container">
<div class="av-section__head">
<span class="av-eyebrow<?php echo $is_dark ? ' av-eyebrow--gold' : ''; ?>"><?php echo esc_html($group['eyebrow']); ?></span>
<h2 class="av-section__title"><?php echo esc_html($group['title']); ?></h2>
</div>
<div class="av-grid-3">
<?php foreach ($group['items'] as $item) : ?>
<article class="av-card<?php echo $is_dark ? ' is-on-dark' : ''; ?>">
<div class="av-card__body">
<h3 class="av-card__title" style="font-size:var(--text-h4);"><?php echo esc_html($item['title']); ?></h3>
<p class="av-card__excerpt"><?php echo esc_html($item['note']); ?></p>
<div class="av-card__cta">
<a href="<?php echo esc_url($home_url . 'contact/'); ?>" class="av-link<?php echo $is_dark ? ' av-link--on-dark' : ''; ?> av-link--with-arrow"><?php esc_html_e('Request access', 'asterion-bricks'); ?></a>
</div>
</div>
</article>
<?php endforeach; ?>
</div>
</div>
</section>
<?php endforeach; ?>
<?php get_footer(); ?>