This commit makes the site editable from WP admin (Gutenberg or Bricks "Edit with Bricks") and translatable via WPML Translation Editor by shifting page rendering away from Custom Templates and into post_content. Architecture change ------------------- Before: Custom Templates assigned to each page (page-solution-detail.php etc.) generated the page HTML at runtime by reading from inc/*-data.php arrays. WPML had nothing to translate, Bricks Builder had nothing to edit, the client could only modify content by editing PHP. After: - Pages now hold their full Gutenberg HTML inside post_content - The default page.php template renders the_content() — no Custom Templates assigned anymore - Bricks Builder picks up post_content and converts it to its element tree when "Edit with Bricks" is clicked - WPML Translation Editor exposes every block for translation - The client can edit pages directly in WP admin What this commit ships ---------------------- - inc/render-blocks.php: data array → Gutenberg HTML payload generator with helpers per section type (prose / cards / list / cta) and per page archetype (solution / industry / technology / editorial / form / overview hub). - inc/shortcodes.php: [av_form slug="request-demo"] for dynamic form blocks (forms can't live as static HTML — they need nonces and per-request state). - inc/i18n.php: av_lang() / av_t() helpers for inline string translation in header.php and footer.php (covers ~80 UI strings); switches based on WPML's wpml_current_language filter. - page.php: minimal default template — get_header() + the_content() + get_footer(). - header.php: real WPML language switcher driven by wpml_active_languages filter (replaces the placeholder EN · FR toggle); UI strings now route through av_t(). - footer.php: same UI string treatment. - Custom Templates retained but no longer assigned (pages were stripped by the migration mu-plugin); they remain available if a page wants to opt back into the data-file pattern. Operational migrations (one-shot mu-plugins, not versioned) ----------------------------------------------------------- 1. asterion-migrate-to-blocks.php walked all 26 PHP-templated pages, pre-rendered them via the new render-blocks helpers, wrote the result to post_content, and stripped _wp_page_template. 2. asterion-duplicate-fr.php cloned all 35 pages into French via WPML API, preserved parent/child hierarchy, linked translations through the trid table, marked them as duplicates pending refinement. 3. asterion-fix-fr-slugs.php aligned French slugs with English ones (WP's wp_unique_post_slug() had appended -2 suffixes; we bypass via $wpdb->update so /fr/solutions/ resolves correctly). Verified -------- - All 35 EN URLs return HTTP 200 - All 35 FR URLs return HTTP 200 under /fr/<slug>/ - Language switcher in header outputs correct hreflang links - WPML emits hreflang en / fr / x-default in <head> - Body class confirms wp-child-theme-asterion-bricks active - Bricks frontend CSS still enqueued - Inter Variable still preloaded Next steps ---------- - French content is currently the duplicated EN copy. Translate via WP admin → WPML → Translation Editor (per-block UI), or edit pages directly in /fr/<slug>/ via Gutenberg / Bricks - WPML String Translation can scan the theme to surface av_t() / __() strings for UI-level translation overrides Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
210 lines
10 KiB
PHP
210 lines
10 KiB
PHP
<?php
|
|
/**
|
|
* Asterion Bricks — Conversion form partial
|
|
*
|
|
* Renders one conversion page (Demo / T&E / Quote / Contact). Two-column
|
|
* hero (form left, promise right) + optional eligibility list + FAQ.
|
|
*
|
|
* Data passed via `set_query_var('av_form', $form_data)`.
|
|
*
|
|
* Form posts to admin-post.php with action=av_form_submit; the handler in
|
|
* inc/form-handler.php validates the nonce, sanitizes, and emails the lead
|
|
* to jerome.foucher@asterionvr.com.
|
|
*
|
|
* @package AsterionBricks
|
|
*/
|
|
defined('ABSPATH') || exit;
|
|
|
|
$form = get_query_var('av_form');
|
|
if (! is_array($form)) {
|
|
return;
|
|
}
|
|
|
|
$home_url = home_url('/');
|
|
$slug_override = get_query_var('av_form_slug_override');
|
|
$slug = $slug_override ?: get_post_field('post_name', get_queried_object_id());
|
|
|
|
// Surface success/error from query string (set by the handler on redirect).
|
|
$av_status = isset($_GET['av_status']) ? sanitize_key($_GET['av_status']) : '';
|
|
?>
|
|
|
|
<!-- HERO -->
|
|
<section class="av-hero" aria-labelledby="form-headline">
|
|
<div class="av-hero__media" aria-hidden="true">
|
|
<div style="width:100%;height:100%;background:
|
|
radial-gradient(ellipse at 50% 30%, rgba(201,164,90,0.12), transparent 60%),
|
|
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 echo esc_html($form['eyebrow']); ?></p>
|
|
<h1 id="form-headline" class="av-hero__headline" style="font-size:clamp(2.25rem,5vw,var(--text-display-lg));line-height:var(--leading-display-lg);"><?php echo esc_html($form['tagline']); ?></h1>
|
|
<p class="av-hero__sub"><?php echo esc_html($form['hero_lead']); ?></p>
|
|
|
|
<?php if (! empty($form['shortcuts'])) : ?>
|
|
<div class="av-hero__ctas">
|
|
<?php foreach ($form['shortcuts'] as $sc) :
|
|
$variant = ($sc['variant'] === 'primary') ? 'av-btn--primary' : 'av-btn--on-dark av-btn--secondary';
|
|
?>
|
|
<a href="<?php echo esc_url($home_url . ltrim($sc['href'], '/')); ?>" class="av-btn <?php echo esc_attr($variant); ?> av-btn--md">
|
|
<?php echo esc_html($sc['label']); ?>
|
|
</a>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- TWO-COLUMN: form (left) + promise (right) -->
|
|
<section class="av-section" aria-labelledby="form-title">
|
|
<div class="av-container">
|
|
|
|
<?php if ($av_status === 'success') : ?>
|
|
<div role="status" aria-live="polite" style="padding:var(--space-6);background:rgba(31,139,76,0.08);border-left:3px solid var(--color-success);border-radius:var(--radius-sm);margin-bottom:var(--space-8);">
|
|
<strong><?php esc_html_e('Thank you — your request was sent.', 'asterion-bricks'); ?></strong><br>
|
|
<?php esc_html_e('We will reply within the timeframe stated above. Check your inbox (and spam) for confirmation.', 'asterion-bricks'); ?>
|
|
</div>
|
|
<?php elseif ($av_status === 'error') : ?>
|
|
<div role="alert" style="padding:var(--space-6);background:rgba(200,16,46,0.06);border-left:3px solid var(--color-error);border-radius:var(--radius-sm);margin-bottom:var(--space-8);">
|
|
<strong><?php esc_html_e('Something went wrong.', 'asterion-bricks'); ?></strong>
|
|
<?php esc_html_e(' Please try again, or email us directly at hello@asterionvr.com.', 'asterion-bricks'); ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div style="display:grid;grid-template-columns:1fr;gap:var(--space-12);" class="av-form-grid">
|
|
|
|
<!-- FORM -->
|
|
<div>
|
|
<h2 id="form-title" class="av-section__title" style="font-size:var(--text-h2);"><?php esc_html_e('Tell us about your unit.', 'asterion-bricks'); ?></h2>
|
|
<p class="av-section__lead" style="margin-bottom:var(--space-6);"><?php echo esc_html($form['reassurance']); ?></p>
|
|
|
|
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" class="av-form">
|
|
<?php wp_nonce_field('av_form_submit', 'av_nonce'); ?>
|
|
<input type="hidden" name="action" value="av_form_submit">
|
|
<input type="hidden" name="form_slug" value="<?php echo esc_attr($slug); ?>">
|
|
<input type="hidden" name="redirect_to" value="<?php echo esc_attr(get_permalink()); ?>">
|
|
<input type="text" name="av_hp" value="" tabindex="-1" autocomplete="off" style="position:absolute;left:-9999px;" aria-hidden="true">
|
|
|
|
<div class="av-stack av-stack--lg">
|
|
<?php foreach ($form['fields'] as $field) :
|
|
$field_id = 'av-' . esc_attr($field['name']);
|
|
$required = ! empty($field['required']);
|
|
?>
|
|
<div>
|
|
<label for="<?php echo esc_attr($field_id); ?>" class="av-label">
|
|
<?php echo esc_html($field['label']); ?>
|
|
<?php if ($required) : ?><span class="av-label__required" aria-hidden="true">*</span><?php endif; ?>
|
|
</label>
|
|
|
|
<?php if ($field['type'] === 'textarea') : ?>
|
|
<textarea
|
|
id="<?php echo esc_attr($field_id); ?>"
|
|
name="<?php echo esc_attr($field['name']); ?>"
|
|
class="av-textarea"
|
|
rows="5"
|
|
<?php echo $required ? 'required aria-required="true"' : ''; ?>></textarea>
|
|
|
|
<?php elseif ($field['type'] === 'select') : ?>
|
|
<select
|
|
id="<?php echo esc_attr($field_id); ?>"
|
|
name="<?php echo esc_attr($field['name']); ?>"
|
|
class="av-select"
|
|
<?php echo $required ? 'required aria-required="true"' : ''; ?>>
|
|
<?php foreach ($field['options'] as $opt) : ?>
|
|
<option value="<?php echo esc_attr($opt); ?>"<?php echo $opt === '' ? ' disabled selected' : ''; ?>>
|
|
<?php echo $opt === '' ? esc_html__('— select —', 'asterion-bricks') : esc_html($opt); ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
|
|
<?php else : ?>
|
|
<input
|
|
type="<?php echo esc_attr($field['type']); ?>"
|
|
id="<?php echo esc_attr($field_id); ?>"
|
|
name="<?php echo esc_attr($field['name']); ?>"
|
|
class="av-input"
|
|
<?php echo $required ? 'required aria-required="true"' : ''; ?>
|
|
autocomplete="<?php echo $field['type'] === 'email' ? 'email' : 'on'; ?>">
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
|
|
<button type="submit" class="av-btn av-btn--primary av-btn--lg" style="width:auto;align-self:flex-start;">
|
|
<?php echo esc_html($form['submit_label'] ?? __('Send', 'asterion-bricks')); ?>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- PROMISE -->
|
|
<aside style="background:var(--color-bg-subtle);padding:var(--space-8);border-radius:var(--radius-md);align-self:start;">
|
|
<h2 style="font-family:var(--font-display);font-size:var(--text-h3);font-weight:var(--font-weight-semibold);margin-bottom:var(--space-4);">
|
|
<?php echo esc_html($form['promise_title']); ?>
|
|
</h2>
|
|
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:var(--space-3);font-size:var(--text-body-md);line-height:var(--leading-body-md);color:var(--color-text-secondary);">
|
|
<?php foreach ($form['promise_items'] as $item) : ?>
|
|
<li style="padding-left:var(--space-6);position:relative;">
|
|
<span aria-hidden="true" style="position:absolute;left:0;top:0.55em;width:8px;height:8px;background:var(--color-brand-gold);border-radius:50%;"></span>
|
|
<?php echo esc_html($item); ?>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
</aside>
|
|
|
|
</div>
|
|
|
|
<style>
|
|
@media (min-width: 1024px) {
|
|
.av-form-grid { grid-template-columns: 1.4fr 1fr !important; }
|
|
}
|
|
</style>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ELIGIBILITY (T&E only) -->
|
|
<?php if (! empty($form['eligibility'])) : ?>
|
|
<section class="av-section av-section--dark" data-av-reveal>
|
|
<div class="av-container">
|
|
<div class="av-section__head">
|
|
<span class="av-eyebrow av-eyebrow--gold"><?php esc_html_e('Eligibility', 'asterion-bricks'); ?></span>
|
|
<h2 class="av-section__title"><?php echo esc_html($form['eligibility']['title']); ?></h2>
|
|
<p class="av-section__lead"><?php echo esc_html($form['eligibility']['lead']); ?></p>
|
|
</div>
|
|
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:var(--space-3);max-width:72ch;color:var(--color-text-on-dark-muted);">
|
|
<?php foreach ($form['eligibility']['items'] as $item) : ?>
|
|
<li style="padding-left:var(--space-6);position:relative;">
|
|
<span aria-hidden="true" style="position:absolute;left:0;top:0.6em;width:8px;height:8px;background:var(--color-brand-gold);border-radius:50%;"></span>
|
|
<?php echo esc_html($item); ?>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
</div>
|
|
</section>
|
|
<?php endif; ?>
|
|
|
|
<!-- FAQ (Demo only) -->
|
|
<?php if (! empty($form['faq'])) : ?>
|
|
<section class="av-section" data-av-reveal>
|
|
<div class="av-container av-container--narrow">
|
|
<div class="av-section__head">
|
|
<span class="av-eyebrow"><?php esc_html_e('Frequently asked', 'asterion-bricks'); ?></span>
|
|
<h2 class="av-section__title"><?php esc_html_e('Quick answers.', 'asterion-bricks'); ?></h2>
|
|
</div>
|
|
<div class="av-stack av-stack--lg">
|
|
<?php foreach ($form['faq'] as $i => $qa) : ?>
|
|
<details style="border-bottom:1px solid var(--color-border-subtle);padding-block:var(--space-4);">
|
|
<summary style="font-family:var(--font-display);font-size:var(--text-h4);font-weight:var(--font-weight-semibold);cursor:pointer;list-style:none;display:flex;justify-content:space-between;align-items:center;">
|
|
<?php echo esc_html($qa['q']); ?>
|
|
<span aria-hidden="true">+</span>
|
|
</summary>
|
|
<p style="margin-top:var(--space-3);color:var(--color-text-secondary);font-size:var(--text-body-md);line-height:var(--leading-body-md);">
|
|
<?php echo esc_html($qa['a']); ?>
|
|
</p>
|
|
</details>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<?php endif; ?>
|