chore: session 2 snapshot — archive before Bricks-first restart
Snapshots the project at the end of session 2, just before resetting to a Bricks-first orthodox architecture. RESTART-PLAN.md at the root explains why this approach is being abandoned and what the next session will look like. Why we restart - Three architectures got stacked: Custom PHP Templates → Gutenberg blocks in post_content → Bricks data in post meta. Each layer fights the next. - Bricks Builder UI does not load because our header.php / footer.php / page.php emit chrome that conflicts with Bricks' own template-parts. - CSS overrides multiplied (Gutenberg + Bricks variants) and still don't pixel-match the original PHP-rendered visual. - 8+ one-shot mu-plugins live in LocalWP to patch over inconsistencies. What survives the restart (preserved here on main) - BRIEF, both PDFs, .txt extracts (sources of truth) - assets/css/tokens.css (full design system, untouched) - assets/fonts/Inter-Variable*.woff2 (RGPD self-hosted) - inc/<section>-data.php files (text copy from PDF strategie, will become /content-source/ on next session for reuse as translation dictionary and as input to programmatic page generation) - The Git repo, remote, branch main - LocalWP site, Bricks v2.3.4, WPML 4.9.3 with active licenses - WPML EN + FR setup with directory URL strategy What gets wiped at the start of next session - wp-content/themes/asterion-bricks/header.php / footer.php / page.php / index.php / front-page.php / template-parts/ / templates/ - inc/render-blocks.php, inc/render-blocks-native.php, inc/render-bricks.php - inc/shortcodes.php, inc/i18n.php, inc/form-handler.php - 35+ WP pages created over the session - All one-shot mu-plugins in LocalWP/wp-content/mu-plugins/ Restart approach (detailed in RESTART-PLAN.md) - Minimalist child theme: style.css, functions.php, theme.json, tokens.css, trimmed utilities.css, fonts, inc/cpt.php — that's it. - No header.php / footer.php / page.php in child theme — Bricks Templates (Header / Footer / Single — Page) take over via Bricks' Conditions. - User builds 5-7 archetype Bricks templates visually (~1-2h each) then programmatic generation fills the variants from inc/*-data.php sources. - WPML duplication after EN is validated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
258
wp-content/themes/asterion-bricks/inc/render-bricks.php
Normal file
258
wp-content/themes/asterion-bricks/inc/render-bricks.php
Normal file
@@ -0,0 +1,258 @@
|
||||
<?php
|
||||
/**
|
||||
* Asterion Bricks — Bricks Builder native data renderer (POC: Industries)
|
||||
*
|
||||
* Generates the array of element descriptors that Bricks Builder expects in
|
||||
* the post meta `_bricks_page_content_2` (constant `BRICKS_DB_PAGE_CONTENT`).
|
||||
*
|
||||
* Schema, confirmed by reading Bricks parent theme source
|
||||
* (`includes/password-protection.php` and `includes/elements/base.php`):
|
||||
*
|
||||
* [
|
||||
* [
|
||||
* 'id' => string, // unique, via Bricks\Helpers::generate_random_id(false)
|
||||
* 'name' => 'section' | 'container' | 'block' | 'heading' | 'text-basic' | 'button' | …,
|
||||
* 'parent' => 0 | string, // 0 = page root, else parent's id
|
||||
* 'children' => [string, …], // optional, for nestable elements
|
||||
* 'settings' => [
|
||||
* 'text' => 'Hello',
|
||||
* 'tag' => 'h1' | 'h2' | …,
|
||||
* 'link' => ['type' => 'external', 'url' => 'https://…'],
|
||||
* '_cssClasses' => 'av-hero',
|
||||
* …
|
||||
* ],
|
||||
* ],
|
||||
* …
|
||||
* ]
|
||||
*
|
||||
* Once stored, opening the page in WP admin and clicking "Edit with Bricks"
|
||||
* surfaces every element in the Bricks builder canvas, fully editable.
|
||||
*
|
||||
* Frontend rendering is handled by Bricks itself — our `page.php` simply
|
||||
* lets Bricks take over via its `template_include` filter.
|
||||
*
|
||||
* @package AsterionBricks
|
||||
*/
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/**
|
||||
* Generate a Bricks-compatible random element ID.
|
||||
* Falls back to a local md5 prefix if the Bricks namespace isn't loaded yet.
|
||||
*/
|
||||
function av_brx_id() {
|
||||
if (class_exists('\\Bricks\\Helpers') && method_exists('\\Bricks\\Helpers', 'generate_random_id')) {
|
||||
return \Bricks\Helpers::generate_random_id(false);
|
||||
}
|
||||
return substr(md5(uniqid((string) mt_rand(), true)), 0, 6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tiny element factory.
|
||||
*/
|
||||
function av_brx_el($name, $parent, $settings = [], $children = null) {
|
||||
$el = [
|
||||
'id' => av_brx_id(),
|
||||
'name' => $name,
|
||||
'parent' => $parent,
|
||||
'settings' => $settings,
|
||||
];
|
||||
if ($children !== null) {
|
||||
$el['children'] = $children;
|
||||
}
|
||||
return $el;
|
||||
}
|
||||
|
||||
/* =================================================================== */
|
||||
/* Industries overview — proof of concept */
|
||||
/* =================================================================== */
|
||||
|
||||
function av_brx_render_industries_overview() {
|
||||
$home_url = home_url('/');
|
||||
|
||||
/* ---- pre-allocate IDs so we can hand them to parents/children ---- */
|
||||
$hero_section_id = av_brx_id();
|
||||
$hero_container_id = av_brx_id();
|
||||
$hero_eyebrow_id = av_brx_id();
|
||||
$hero_h1_id = av_brx_id();
|
||||
$hero_sub_id = av_brx_id();
|
||||
|
||||
$cards_section_id = av_brx_id();
|
||||
$cards_container_id = av_brx_id();
|
||||
$cards_grid_id = av_brx_id();
|
||||
|
||||
$industries = [
|
||||
[
|
||||
'eyebrow' => 'National & Municipal',
|
||||
'title' => 'Police',
|
||||
'excerpt' => 'Vehicle stops, identity checks, urban CQB, de-escalation, riot containment. Built for the realities of contemporary policing.',
|
||||
'href' => '/industries/police/',
|
||||
'cta' => 'Police training',
|
||||
],
|
||||
[
|
||||
'eyebrow' => 'Tactical units',
|
||||
'title' => 'Special Forces',
|
||||
'excerpt' => 'Hostage rescue, dynamic entries, hostile crowd extraction, sniper-spotter coordination. Built for the units where every error has a name.',
|
||||
'href' => '/industries/special-forces/',
|
||||
'cta' => 'Special forces training',
|
||||
],
|
||||
[
|
||||
'eyebrow' => 'Armed forces',
|
||||
'title' => 'Military',
|
||||
'excerpt' => 'MOUT, convoy escort, FOB defense, IED awareness, joint operation drills. Built for armed forces that deploy fast and adapt faster.',
|
||||
'href' => '/industries/military/',
|
||||
'cta' => 'Military training',
|
||||
],
|
||||
[
|
||||
'eyebrow' => 'Emergency services',
|
||||
'title' => 'Firefighters',
|
||||
'excerpt' => "Structure fires, hazmat, multi-casualty triage, confined-space rescue, industrial accidents. Built for first responders who can't rehearse the worst day at full scale.",
|
||||
'href' => '/industries/firefighters/',
|
||||
'cta' => 'Firefighter training',
|
||||
],
|
||||
];
|
||||
|
||||
$card_ids = [];
|
||||
foreach ($industries as $i => $_) {
|
||||
$card_ids[$i] = [
|
||||
'card' => av_brx_id(),
|
||||
'eyebrow' => av_brx_id(),
|
||||
'title' => av_brx_id(),
|
||||
'excerpt' => av_brx_id(),
|
||||
'btn' => av_brx_id(),
|
||||
];
|
||||
}
|
||||
$cards_children = array_map(fn($ids) => $ids['card'], $card_ids);
|
||||
|
||||
/* ---- assemble flat element array ---- */
|
||||
$elements = [];
|
||||
|
||||
// 1. Hero section ----------------------------------------------------
|
||||
$elements[] = [
|
||||
'id' => $hero_section_id,
|
||||
'name' => 'section',
|
||||
'parent' => 0,
|
||||
'children' => [$hero_container_id],
|
||||
'settings' => ['_cssClasses' => 'av-hero'],
|
||||
'label' => 'Hero',
|
||||
];
|
||||
$elements[] = [
|
||||
'id' => $hero_container_id,
|
||||
'name' => 'container',
|
||||
'parent' => $hero_section_id,
|
||||
'children' => [$hero_eyebrow_id, $hero_h1_id, $hero_sub_id],
|
||||
'settings' => ['_cssClasses' => 'av-container av-hero__inner'],
|
||||
];
|
||||
$elements[] = [
|
||||
'id' => $hero_eyebrow_id,
|
||||
'name' => 'text-basic',
|
||||
'parent' => $hero_container_id,
|
||||
'settings' => [
|
||||
'text' => 'Industries',
|
||||
'tag' => 'p',
|
||||
'_cssClasses' => 'av-hero__eyebrow',
|
||||
],
|
||||
];
|
||||
$elements[] = [
|
||||
'id' => $hero_h1_id,
|
||||
'name' => 'heading',
|
||||
'parent' => $hero_container_id,
|
||||
'settings' => [
|
||||
'tag' => 'h1',
|
||||
'text' => 'Built with operators, for operators.',
|
||||
'_cssClasses' => 'av-hero__headline',
|
||||
],
|
||||
];
|
||||
$elements[] = [
|
||||
'id' => $hero_sub_id,
|
||||
'name' => 'text-basic',
|
||||
'parent' => $hero_container_id,
|
||||
'settings' => [
|
||||
'text' => 'PROSERVE™ is not a generic VR platform repackaged for the public sector. Every scenario, every weapon profile, every instructor metric was specified by serving and former operators in close partnership with our engineering team.',
|
||||
'tag' => 'p',
|
||||
'_cssClasses' => 'av-hero__sub',
|
||||
],
|
||||
];
|
||||
|
||||
// 2. Cards section ---------------------------------------------------
|
||||
$elements[] = [
|
||||
'id' => $cards_section_id,
|
||||
'name' => 'section',
|
||||
'parent' => 0,
|
||||
'children' => [$cards_container_id],
|
||||
'settings' => ['_cssClasses' => 'av-section'],
|
||||
'label' => 'Industries grid',
|
||||
];
|
||||
$elements[] = [
|
||||
'id' => $cards_container_id,
|
||||
'name' => 'container',
|
||||
'parent' => $cards_section_id,
|
||||
'children' => [$cards_grid_id],
|
||||
'settings' => ['_cssClasses' => 'av-container'],
|
||||
];
|
||||
$elements[] = [
|
||||
'id' => $cards_grid_id,
|
||||
'name' => 'block',
|
||||
'parent' => $cards_container_id,
|
||||
'children' => $cards_children,
|
||||
'settings' => ['_cssClasses' => 'av-grid-4'],
|
||||
];
|
||||
|
||||
foreach ($industries as $i => $ind) {
|
||||
$ids = $card_ids[$i];
|
||||
|
||||
$elements[] = [
|
||||
'id' => $ids['card'],
|
||||
'name' => 'block',
|
||||
'parent' => $cards_grid_id,
|
||||
'children' => [$ids['eyebrow'], $ids['title'], $ids['excerpt'], $ids['btn']],
|
||||
'settings' => ['_cssClasses' => 'av-card'],
|
||||
'label' => $ind['title'],
|
||||
];
|
||||
$elements[] = [
|
||||
'id' => $ids['eyebrow'],
|
||||
'name' => 'text-basic',
|
||||
'parent' => $ids['card'],
|
||||
'settings' => [
|
||||
'text' => $ind['eyebrow'],
|
||||
'tag' => 'p',
|
||||
'_cssClasses' => 'av-card__eyebrow',
|
||||
],
|
||||
];
|
||||
$elements[] = [
|
||||
'id' => $ids['title'],
|
||||
'name' => 'heading',
|
||||
'parent' => $ids['card'],
|
||||
'settings' => [
|
||||
'tag' => 'h2',
|
||||
'text' => $ind['title'],
|
||||
'_cssClasses' => 'av-card__title',
|
||||
],
|
||||
];
|
||||
$elements[] = [
|
||||
'id' => $ids['excerpt'],
|
||||
'name' => 'text-basic',
|
||||
'parent' => $ids['card'],
|
||||
'settings' => [
|
||||
'text' => $ind['excerpt'],
|
||||
'tag' => 'p',
|
||||
'_cssClasses' => 'av-card__excerpt',
|
||||
],
|
||||
];
|
||||
$elements[] = [
|
||||
'id' => $ids['btn'],
|
||||
'name' => 'button',
|
||||
'parent' => $ids['card'],
|
||||
'settings' => [
|
||||
'text' => $ind['cta'],
|
||||
'tag' => 'a',
|
||||
'link' => [
|
||||
'type' => 'external',
|
||||
'url' => $home_url . ltrim($ind['href'], '/'),
|
||||
],
|
||||
'_cssClasses' => 'av-btn av-btn--secondary av-btn--md',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
return $elements;
|
||||
}
|
||||
Reference in New Issue
Block a user