🔵 other: Rename project and publish

This commit is contained in:
Keith Solomon
2026-07-29 14:25:19 -05:00
parent 5512918b0f
commit 7dbb991fb9
70 changed files with 558 additions and 5386 deletions
+115 -98
View File
@@ -1,44 +1,61 @@
# Architecture
A deep dive into how VDI-Starter-v5 is organized, how it boots, and the conventions it uses.
A deep dive into how SoloFrame Evo is organized, how it boots, and the conventions it uses.
## Table of Contents
- [Bootstrap Flow](#bootstrap-flow)
- [Architectural Layers](#architectural-layers)
- [Namespace Conventions](#namespace-conventions)
- [Global Variables](#global-variables)
- [WordPress Hooks Cleanup](#wordpress-hooks-cleanup)
- [Enqueue System](#enqueue-system)
- [theme.json Design System](#themjson-design-system)
- [Architecture](#architecture)
- [Table of Contents](#table-of-contents)
- [Bootstrap Flow](#bootstrap-flow)
- [Architectural Layers](#architectural-layers)
- [1. Entry Layer](#1-entry-layer)
- [2. Service Layer](#2-service-layer)
- [3. UI Templates and Components](#3-ui-templates-and-components)
- [4. Styling](#4-styling)
- [5. Client Scripts](#5-client-scripts)
- [6. Data Layer](#6-data-layer)
- [7. Infrastructure](#7-infrastructure)
- [Namespace Conventions](#namespace-conventions)
- [Global Variables](#global-variables)
- [WordPress Hooks Cleanup](#wordpress-hooks-cleanup)
- [Enqueue System](#enqueue-system)
- [Frontend (`enqFEAssets()`)](#frontend-enqfeassets)
- [Admin (`enqBEAssets()`)](#admin-enqbeassets)
- [Block Editor (`enqEditorAssets()`)](#block-editor-enqeditorassets)
- [theme.json Design System](#themejson-design-system)
- [Colors](#colors)
- [Typography](#typography)
- [Layout](#layout)
- [Spacing](#spacing)
- [Global Styles](#global-styles)
## Bootstrap Flow
When WordPress loads a theme, it starts with `style.css` (for theme metadata) and `functions.php` (for logic). Here's exactly what happens in VDI-Starter-v5:
When WordPress loads a theme, it starts with `style.css` (for theme metadata) and `functions.php` (for logic). Here's exactly what happens in SoloFrame Evo:
```
```plain
WordPress loads the theme
├─ style.css → Theme declaration (name, description, version)
└─ functions.php → Entry point
├─ namespace BasicWP
├─ namespace SoloFrameEvo
├─ glob(__DIR__ . '/lib/*.php') → Autoloads every PHP file in lib/
│ ├─ activation.php → Theme activation handler (runs once)
│ ├─ class-acf.php → ACF JSON sync paths
│ ├─ class-breadcrumbs.php → Breadcrumb generation
│ ├─ class-enqueue.php → Asset loading (CSS, JS, fonts)
│ ├─ class-menuitems.php → Nav menu rendering
│ ├─ class-resources.php → Custom post type
│ ├─ extras.php → Sidebar, page header, Owner role, etc.
│ ├─ helpers.php → Utility functions, globals, ACF options page
│ ├─ hooks.php → WordPress hooks, cleanup, SVG support
│ ├─ search-features.php → Enhanced search
│ └─ show-template.php → Debug template path display
├─ glob(__DIR__ . '/lib/*.php') → Autoloads every PHP file in lib/
│ ├─ activation.php → Theme activation handler (runs once)
│ ├─ class-acf.php → ACF JSON sync paths
│ ├─ class-breadcrumbs.php → Breadcrumb generation
│ ├─ class-enqueue.php → Asset loading (CSS, JS, fonts)
│ ├─ class-menuitems.php → Nav menu rendering
│ ├─ class-resources.php → Custom post type
│ ├─ extras.php → Sidebar, page header, Owner role, etc.
│ ├─ helpers.php → Utility functions, globals, ACF options page
│ ├─ hooks.php → WordPress hooks, cleanup, SVG support
│ ├─ search-features.php → Enhanced search
│ └─ show-template.php → Debug template path display
└─ regACFBlocks() → Registers ACF blocks (init hook, priority 5)
└─ regACFBlocks() → Registers ACF blocks (init hook, priority 5)
└─ Scans views/blocks/*/block.json (skips 'boilerplate')
```
@@ -55,7 +72,7 @@ The theme is organized into seven distinct layers, each with a clear responsibil
The two files WordPress needs to recognize the theme:
| File | Purpose |
|------|---------|
| ------ | --------- |
| `functions.php` | Autoloads `lib/*.php`, registers ACF blocks on `init` |
| `style.css` | Theme declaration — name, description, version, author |
@@ -66,7 +83,7 @@ The two files WordPress needs to recognize the theme:
PHP classes and utility functions in `lib/` that provide core functionality:
| File | Class/Function | Purpose |
|------|---------------|---------|
| ------ | --------------- | --------- |
| `class-enqueue.php` | `Enqueue` | Loads all frontend CSS, JS, and fonts with cache-busting |
| `class-menuitems.php` | `MenuItems` | Resolves WordPress nav menus into renderable item trees |
| `class-breadcrumbs.php` | `Breadcrumbs` | Context-aware breadcrumb trails with Schema.org markup |
@@ -86,7 +103,7 @@ WordPress template hierarchy files, ACF blocks, reusable components, and icons:
**Template Hierarchy:**
| File | WordPress Template For |
|------|----------------------|
| ------ | ---------------------- |
| `front-page.php` | The front page |
| `index.php` | Blog posts listing (fallback for all) |
| `single.php` | Individual posts |
@@ -103,7 +120,7 @@ WordPress template hierarchy files, ACF blocks, reusable components, and icons:
Each block follows a consistent three-file pattern: `block.json` (registration) + `{name}.php` (template) + `{name}.css` (styles).
| Block | Purpose |
|-------|---------|
| ------- | --------- |
| `accordion` | Collapsible content sections |
| `boilerplate` | Starting template for new blocks (not registered) |
| `button` | Single configurable button element |
@@ -120,7 +137,7 @@ Each block follows a consistent three-file pattern: `block.json` (registration)
**Components (in `views/components/`):**
| Component | Purpose |
|-----------|---------|
| ----------- | --------- |
| `nav-aux.php` | Auxiliary navigation bar (social links + search) |
| `nav-main.php` | Primary navigation menu |
| `nav-main__toggle.php` | Mobile menu toggle button |
@@ -129,7 +146,7 @@ Each block follows a consistent three-file pattern: `block.json` (registration)
**Partials (in `views/partials/`):**
| Partial | Purpose |
|---------|---------|
| --------- | --------- |
| `page-hero.php` | Page hero section |
| `social-media.php` | Social media links |
@@ -141,38 +158,38 @@ SVG icon partials for Facebook, Instagram, LinkedIn, Pinterest, Twitter, YouTube
CSS is organized as a layered cascade, managed through Tailwind CSS v4:
```
styles/theme.css ← Entry point (imports everything below)
├── @import "tailwindcss" ← Tailwind CSS v4 base
├── @import "./base/index.css" ← Base styles barrel file
│ ├── break-out.css ← Container break-out utilities
│ ├── colors.css ← Color custom properties
│ ├── forms.css ← Form element styles
│ ├── global.css ← Global resets and base styles
│ ├── misc.css ← Miscellaneous utilities
│ ├── prose.css ← Prose/typography styles
│ ├── skip-link.css ← Accessibility skip link
│ └── typography.css ← Typography scale and fonts
├── @import "./navigation/index.css" ← Navigation barrel file
│ ├── nav-aux.css ← Auxiliary nav
│ ├── nav-footer.css ← Footer nav
│ ├── nav-functional.css ← Functional nav styles
│ ├── nav-main-default.css ← Default main nav
│ ├── nav-main-mega.css ← Mega menu nav
│ ├── nav-mobile-accordion.css ← Accordion mobile nav
│ └── nav-mobile-sliding.css ← Sliding mobile nav
├── @import "./fonts/lineicons.css" ← Icon font (600+ glyphs)
├── @import "./base/break-out.css" ← Break-out utilities (loaded after nav)
├── @import "./components/index.css" ← Components barrel file
│ ├── breadcrumbs.css ← Breadcrumbs
│ ├── pagination.css ← Pagination
│ ├── post-list.css ← Post listings
│ ├── sidebar.css ← Sidebar
│ ├── site-footer.css ← Footer
│ └── site-header.css ← Header
└── @import "./blocks/index.css" ← Block styles barrel file
├── buttons.css ← Button styles with CSS custom properties
└── core.css ← Core block overrides
```plain
styles/theme.css ← Entry point (imports everything below)
├── @import "tailwindcss" ← Tailwind CSS v4 base
├── @import "./base/index.css" ← Base styles barrel file
│ ├── break-out.css ← Container break-out utilities
│ ├── colors.css ← Color custom properties
│ ├── forms.css ← Form element styles
│ ├── global.css ← Global resets and base styles
│ ├── misc.css ← Miscellaneous utilities
│ ├── prose.css ← Prose/typography styles
│ ├── skip-link.css ← Accessibility skip link
│ └── typography.css ← Typography scale and fonts
├── @import "./navigation/index.css" ← Navigation barrel file
│ ├── nav-aux.css ← Auxiliary nav
│ ├── nav-footer.css ← Footer nav
│ ├── nav-functional.css ← Functional nav styles
│ ├── nav-main-default.css ← Default main nav
│ ├── nav-main-mega.css ← Mega menu nav
│ ├── nav-mobile-accordion.css ← Accordion mobile nav
│ └── nav-mobile-sliding.css ← Sliding mobile nav
├── @import "./fonts/lineicons.css" ← Icon font (600+ glyphs)
├── @import "./base/break-out.css" ← Break-out utilities (loaded after nav)
├── @import "./components/index.css" ← Components barrel file
│ ├── breadcrumbs.css ← Breadcrumbs
│ ├── pagination.css ← Pagination
│ ├── post-list.css ← Post listings
│ ├── sidebar.css ← Sidebar
│ ├── site-footer.css ← Footer
│ └── site-header.css ← Header
└── @import "./blocks/index.css" ← Block styles barrel file
├── buttons.css ← Button styles with CSS custom properties
└── core.css ← Core block overrides
```
**Why this structure?** The barrel files (`index.css`) make it easy to add or remove stylesheets without modifying `theme.css`. Navigation styles are grouped because you typically only use one variant (default vs mega menu, accordion vs sliding mobile). Block-specific CSS lives alongside each block in `views/blocks/` and is auto-loaded by WordPress when the block renders.
@@ -183,19 +200,19 @@ styles/theme.css ← Entry point (imports everything below)
JavaScript modules loaded via WordPress's `wp_enqueue_script_module()` API (requires WordPress 6.5+):
```
```plain
static/js/theme.js (entry point for frontend)
├── Navigation.js → Mobile menu, sliding viewport, keyboard nav
├── backToTop.js → BackToTopButton custom element
├── button.js → ButtonComponent custom element (<x-button>)
├── GetHeaderHeight.js → Sets --header-height CSS variable
├── Navigation.js → Mobile menu, sliding viewport, keyboard nav
├── backToTop.js → BackToTopButton custom element
├── button.js → ButtonComponent custom element (<x-button>)
├── GetHeaderHeight.js → Sets --header-height CSS variable
└── TagExternalLinks.js → Adds target="_blank" rel="noopener" to external links
static/js/admin.js (entry point for editor)
└── button.js → ButtonComponent for editor context
└── button.js → ButtonComponent for editor context
```
**How script modules work:** WordPress's `wp_enqueue_script_module()` creates proper ES module dependencies. The `Enqueue` class registers `basicwp-theme` (theme.js) as a root module, and `basicwp-button` (button.js) declares a dependency on it. This means button.js won't load until theme.js has loaded — no more manual script ordering.
**How script modules work:** WordPress's `wp_enqueue_script_module()` creates proper ES module dependencies. The `Enqueue` class registers `sf-evo-theme` (theme.js) as a root module, and `sf-evo-button` (button.js) declares a dependency on it. This means button.js won't load until theme.js has loaded — no more manual script ordering.
**Passive event listener polyfill:** `theme.js` includes a polyfill that makes scroll, touch, and mouse event listeners passive by default. This improves scrolling performance without requiring `addEventListener(..., { passive: true })` on every listener.
@@ -203,10 +220,10 @@ static/js/admin.js (entry point for editor)
### 6. Data Layer
ACF field group JSON files in the `acf/` directory:
SCF/ACF field group JSON files in the `acf/` directory:
| File | Block/Feature |
|------|-------------|
| ------ | ------------- |
| `group_5f7f85a2a3e13.json` | Accordion block fields |
| `group_5fd3e006e5da5.json` | Global Fields (site-wide contact, social, footer settings) |
| `group_600f5a9e242c3.json` | Grid block fields |
@@ -218,6 +235,7 @@ ACF field group JSON files in the `acf/` directory:
| `group_645e7cf448e66.json` | Contact Info block fields |
**Why JSON sync?** The `ACF` class in `class-acf.php` sets custom save/load paths so that field groups created in the WordPress admin are automatically saved as JSON files. This means:
- Field group configurations are version-controlled in Git
- Field groups survive database resets
- Multiple environments stay in sync
@@ -228,7 +246,7 @@ ACF field group JSON files in the `acf/` directory:
Build, CI/CD, and configuration files that support development and deployment:
| File | Purpose |
|------|---------|
| ------ | --------- |
| `bin/.build.js` | Production build script — compiles Tailwind CSS with `--optimize` |
| `bin/.watch.js` | Development server — BrowserSync with live reload |
| `bin/.utils.js` | Shared utilities for build scripts (`tailwindToCSS`, debounce) |
@@ -248,15 +266,13 @@ Build, CI/CD, and configuration files that support development and deployment:
The project uses several naming conventions that can be confusing at first:
| Convention | Value | Where Used |
|-----------|-------|-----------|
| PHP namespace | `BasicWP` | All PHP files use `namespace BasicWP;` |
| Text domain | `basicwp` | WordPress translation functions (`__()` , `_e()`) |
| Block category | `vdi-blocks` | Groups custom blocks in the editor (defined in `helpers.php::blockCategories()`) |
| Script module IDs | `basicwp-theme`, `basicwp-button`, `basicwp-admin` | JavaScript module registration in `class-enqueue.php` |
| WP Engine folder | `vdi-v5` | Deployment target in `.github/workflows/wpengine.yml` |
| Git repo name | `VDI-Starter-v5` | The repository and theme directory name |
**The story:** "VDI" is Vincent Design Inc., the agency. "BasicWP" was the original internal code name. "vdi-blocks" and "vdi-v5" are deployment-facing names that align with the client's branding. They all refer to the same theme — just used in different contexts.
| ----------- | ------- | ----------- |
| PHP namespace | `SoloFrameEvo` | All PHP files use `namespace SoloFrameEvo;` |
| Text domain | `sf-evo` | WordPress translation functions (`__()` , `_e()`) |
| Block category | `sf-blocks` | Groups custom blocks in the editor (defined in `helpers.php::blockCategories()`) |
| Script module IDs | `sf-evo-theme`, `sf-evo-button`, `sf-evo-admin` | JavaScript module registration in `class-enqueue.php` |
| WP Engine folder | `soloframe-evo` | Deployment target in `.github/workflows/wpengine.yml` |
| Git repo name | `SoloFrame-Evo` | The repository and theme directory name |
## Global Variables
@@ -264,13 +280,14 @@ Two global variables are defined in `helpers.php`:
```php
global $theme, $views;
$theme = get_template_directory(); // e.g., /var/www/wp-content/themes/VDI-Starter-v5
$views = $theme . '/views'; // e.g., /var/www/wp-content/themes/VDI-Starter-v5/views
$theme = get_template_directory(); // e.g., /var/www/wp-content/themes/SoloFrame Evo
$views = $theme . '/views'; // e.g., /var/www/wp-content/themes/SoloFrame Evo/views
```
**`$theme`** — Absolute path to the theme directory. Used when including files that need the full server path.
**`$views`** — Absolute path to the views directory. Used by `MenuItems::render()` to include navigation templates:
```php
include $views . '/components/menu-items/index.php';
```
@@ -284,7 +301,7 @@ The `init()` function in `hooks.php` runs on every page load at priority 1. It p
**What gets removed:**
| What | Why |
|------|-----|
| ------ | ----- |
| Emoji detection scripts & styles | Most sites don't use WordPress emojis; they add ~10KB to every page |
| `wp-block-library` styles | Theme provides its own block styles; core defaults add ~100KB |
| `global-styles` & `core-block-styles` | Theme overrides these via `theme.json` and custom CSS |
@@ -304,7 +321,7 @@ The `init()` function in `hooks.php` runs on every page load at priority 1. It p
**What gets added:**
| Feature | Why |
|---------|-----|
| --------- | ----- |
| `post-thumbnails` | Featured image support |
| `title-tag` | WordPress manages `<title>` tag |
| `html5` (caption, comment-form, comment-list, gallery, search-form, script, style) | Modern HTML5 markup |
@@ -323,32 +340,32 @@ The `Enqueue` class (in `class-enqueue.php`) manages all asset loading:
### Frontend (`enqFEAssets()`)
| Asset | Method | Notes |
|-------|--------|-------|
| ------- | -------- | ------- |
| `static/dist/theme.css` | `wp_enqueue_style()` | Compiled Tailwind CSS, cache-busted with `filemtime()` |
| Raleway font | `wp_enqueue_style()` | Google Fonts with `preconnect` hint |
| `basicwp-theme` (theme.js) | `wp_enqueue_script_module()` | Frontend entry point |
| `basicwp-button` (button.js) | `wp_enqueue_script_module()` | Depends on `basicwp-theme` |
| `sf-evo-theme` (theme.js) | `wp_enqueue_script_module()` | Frontend entry point |
| `sf-evo-button` (button.js) | `wp_enqueue_script_module()` | Depends on `sf-evo-theme` |
| jQuery | `wp_enqueue_script()` | Needed by downstream scripts; modules can't depend on classic scripts |
### Admin (`enqBEAssets()`)
| Asset | Method | Notes |
|-------|--------|-------|
| ------- | -------- | ------- |
| Raleway font | `wp_enqueue_style()` | Same Google Fonts |
| `styles/backend/admin.css` | `wp_enqueue_style()` | Admin-specific overrides |
| `basicwp-admin` (admin.js) | `wp_enqueue_script_module()` | Admin entry point |
| `basicwp-button` (button.js) | `wp_enqueue_script_module()` | Depends on `basicwp-admin` |
| `sf-evo-admin` (admin.js) | `wp_enqueue_script_module()` | Admin entry point |
| `sf-evo-button` (button.js) | `wp_enqueue_script_module()` | Depends on `sf-evo-admin` |
### Block Editor (`enqEditorAssets()`)
| Asset | Method | Notes |
|-------|--------|-------|
| ------- | -------- | ------- |
| Raleway font | `wp_enqueue_style()` | Same Google Fonts |
| `styles/backend/editor.css` | `wp_enqueue_style()` | Editor-specific styles, scoped to block editor |
**Cache busting:** All enqueued files use `filemtime()` as the version number. This means the browser cache is automatically busted whenever a file changes — no manual version bumps needed.
**Script modules:** The theme uses `wp_enqueue_script_module()` (WordPress 6.5+) instead of traditional `wp_enqueue_script()` for frontend and admin JavaScript. This creates proper ES module dependencies where `basicwp-button` won't load until `basicwp-theme` has loaded.
**Script modules:** The theme uses `wp_enqueue_script_module()` (WordPress 6.5+) instead of traditional `wp_enqueue_script()` for frontend and admin JavaScript. This creates proper ES module dependencies where `sf-evo-button` won't load until `sf-evo-theme` has loaded.
## theme.json Design System
@@ -359,7 +376,7 @@ The `theme.json` file (WordPress block editor v3 schema) defines the design syst
Colors are defined as CSS custom properties and mapped to WordPress editor slugs:
| Editor Slug | CSS Variable | Purpose |
|------------|-------------|---------|
| ------------ | ------------- | --------- |
| `black` | `#000` | Pure black |
| `white` | `#fff` | Pure white |
| `theme-bg` | `var(--color-background)` | Page background |
@@ -380,7 +397,7 @@ The actual color values for the CSS variables are defined in `styles/base/colors
One font family (`var(--font-sans)`) and 15 size presets:
| Slug | Variable | Typical Use |
|------|----------|-------------|
| ------ | ---------- | ------------- |
| `base` | `var(--text-base)` | Body text |
| `text-14px` | `var(--text-14px)` | Small text |
| `text-16px` | `var(--text-16px)` | Standard text |
@@ -400,7 +417,7 @@ One font family (`var(--font-sans)`) and 15 size presets:
### Layout
| Property | Value | Meaning |
|----------|-------|---------|
| ---------- | ------- | --------- |
| `contentSize` | `100%` | Default content width (full-width by default) |
| `wideSize` | `1536px` | Wide-alignment max width |
@@ -411,11 +428,11 @@ Available units: `px`, `em`, `rem`, `vh`, `vw`, `%`
### Global Styles
| Property | Value |
|----------|-------|
| ---------- | ------- |
| Background | `var(--wp--preset--color--background)` |
| Text color | `var(--wp--preset--color--text)` |
| Link color | `var(--wp--preset--color--theme-bodylinks)` |
| Font family | `var(--wp--preset--font-family--theme-sans)` |
| Line height | `1.5` |
**Why `theme.json` matters:** Changes to this file immediately affect the block editor UI — colors appear in the palette, font sizes in the typography controls, and spacing in the spacing panel. This is the single source of truth for the design system, and CSS custom properties cascade from here into the frontend styles.
**Why `theme.json` matters:** Changes to this file immediately affect the block editor UI — colors appear in the palette, font sizes in the typography controls, and spacing in the spacing panel. This is the single source of truth for the design system, and CSS custom properties cascade from here into the frontend styles.