# Beaver Builder + UABB Implementation Notes

**Source:** Beaver Builder Pro 2.x + UABB Pro on `servicetechohio.com`, read directly via SSH on 2026-04-29.
**Purpose:** Reference notes for IM-Press future releases. **Not a copy-paste roadmap** — IM-Press is a Gutenberg-native plugin, BB has its own frontend editor architecture, so many patterns translate but not all.

> Triggered by John's observation that BB's live implementation could inform IM-Press dev beyond just v4.8.0. Captured during v4.7.0 deploy prep.

---

## 1. Module file layout (BB convention)

Each BB core module is a self-contained directory:

```
modules/heading/
├── heading.php                  ← class definition + register_module() call
├── css/                         ← module-specific CSS files
├── deprecated/                  ← old setting handlers
├── deprecated.php               ← migration logic
└── includes/
    ├── frontend.php             ← rendered HTML output
    └── frontend.css.php         ← per-instance scoped CSS
```

**Worth borrowing:** the `frontend.php` / `frontend.css.php` separation. IM-Press blocks currently emit inline `<style>` tags in the render callback. BB's pattern of separating PHP-templated CSS (with the module's settings interpolated into it) keeps render functions readable. Worth considering when blocks grow past ~150 LOC.

**Not applicable:** the `deprecated/` directory pattern is BB-specific because BB's module schemas have changed many times in 8+ years. IM-Press is younger; we can use a simpler `filter_settings()` method on each block class when needed.

---

## 2. Module settings UI architecture

Every BB module is registered with this nested structure:

```php
FLBuilder::register_module('FLHeadingModule', array(
    'general' => array(             // ← TAB
        'title' => 'General',
        'sections' => array(
            'general' => array(     // ← SECTION (collapsible)
                'title' => '',
                'fields' => array(
                    'heading' => array(  // ← FIELD
                        'type'        => 'text',
                        'label'       => 'Heading',
                        'default'     => '',
                        'preview'     => array('type' => 'text', 'selector' => '.fl-heading-text'),
                        'connections' => array('string'),
                    ),
                    'tag' => array(
                        'type'     => 'select',
                        'options'  => array('h1' => 'h1', 'h2' => 'h2', /* ... */),
                        'sanitize' => array('FLBuilderUtils::esc_tags', 'h2'),
                    ),
                    'link' => array(
                        'type'          => 'link',
                        'show_target'   => true,
                        'show_nofollow' => true,
                        'show_download' => true,
                    ),
                ),
            ),
        ),
    ),
    'style' => array(   /* ← TAB */ ),
    'advanced' => array(/* ← TAB */ ),
));
```

### Insights worth adopting in IM-Press

| BB pattern | Why it's useful | IM-Press status |
|---|---|---|
| **Three-tab UX** (General / Style / Advanced) | Sidebar doesn't drown the user as block deepens. Heading has 50+ fields across 3 tabs, but each tab is browseable. | IM-Press uses flat `PanelBody` stack. As blocks grow (info-box now 25 attrs, modal now 30) we'll start hitting clutter. **Worth adopting in v4.8.0+ for new blocks; existing blocks can stay flat to avoid disruption.** |
| **Composite `link` field type** with `show_target` / `show_nofollow` / `show_download` flags | One field renders three controls. Saves sidebar space. Authoring UX: user thinks "I'm setting up a link" not "I'm setting 3 separate attrs". | IM-Press v4.7.0 has separate `linkUrl` + `linkTarget` (via Block_Link_Controls) + `linkRel`. **Worth designing a `<LinkControl>` shared React component that bundles all three into a single sidebar interaction.** |
| **Composite `typography` field** | Stores font-family + size + weight + line-height + letter-spacing + transform + alignment in one composite field, with `_medium` and `_responsive` variants for breakpoints. | IM-Press has individual `fontSize`, `fontWeight`, etc. Per-breakpoint typography deferred for v4.7.0. **If we revisit per-breakpoint typography later, this composite-field pattern is the right architecture — atomic save, single UI panel.** |
| **`preview` hint per field** | Tells the editor whether changing this field needs full block re-render (`refresh`) or just text replacement (`text` with selector) or nothing (`none`). | IM-Press uses `ServerSideRender` which always refetches the entire block. Less efficient. **Not directly translatable** because Gutenberg's block API doesn't have BB's preview-update model. Could matter eventually if we build our own frontend editor. |
| **`connections` array** on field | Marks fields as available for dynamic-content connection (post title, ACF fields, etc.). Enables BB Theme Builder to bind to them. | IM-Press has Block_Data_Bindings (`class-block-data-bindings.php`) which uses Gutenberg's native bindings API. **Already covered, different mechanism.** |
| **`sanitize` callback per field** | Whitelist + escape per-field. Heading `tag` uses `array('FLBuilderUtils::esc_tags', 'h2')` — sanitizer + fallback. | IM-Press relies on attribute schema validation in `register_block_type`. Looser. **Worth adding explicit sanitization in render callbacks for any user-input field that could leak to attributes (URLs, emails, anchor IDs).** |
| **`filter_settings()` method per module** for back-compat | Each module class has a `filter_settings()` method that runs on every load, normalizing old attribute shapes into new ones (e.g. `font` array → `typography` composite). | IM-Press has no formal pattern. **Worth adopting:** when v4.7.0 deepens info-box from 6→25 attrs, a `filter_settings()`-equivalent on the render callback could quietly remap legacy attr names. We did some of this manually in v4.7.0 (e.g., `circleBar:true` → `numberType:'circle'` on numbers block). **Formalize it: add a `migrate_attributes()` static method convention to deepened blocks for v4.8.0+.** |

---

## 3. Module catalog (BB Pro + UABB Pro on STO)

- **bb-plugin** core: 42 modules
- **bb-ultimate-addon** (UABB Pro): 74 modules
- **Total available**: 116
- **Used in production** (per the 4-hitech.com audit, 6,168 instances): 58 distinct types

The 58 actually-used types are what the parity audit covered. The remaining 58 are likely rarely used or recently added.

**Implication:** IM-Press's existing 100+ blocks already match BB's surface area in count. The gap is depth, not coverage — which is exactly what v4.7.0 closes.

---

## 4. BB Theme Builder — directly informs v4.8.0

### Architecture

Theme Builder lives as an *extension* in `bb-plugin/extensions/fl-theme-builder-core/`. Three core classes:

1. **`class-fl-theme-builder-layout-data.php`** — stores theme layouts (header/footer/archive/single/etc.) as `fl-builder-template` CPT posts. The template's body is a normal BB layout — same blocks, same editing experience.
2. **`class-fl-theme-builder-rules-location.php`** (50 KB!) — the conditional display rules engine. This is the meat.
3. **`class-fl-theme-builder-field-connections.php`** — dynamic content bindings (post title → block attribute).

### Location rules data shape

A theme layout has a `_fl_theme_builder_locations` post meta storing rules like:

```php
array(
    array('location' => 'general:site'),                          // entire site
    array('location' => 'post:page'),                             // all pages
    array('location' => 'post:post'),                             // all blog posts
    array('location' => 'post:page:42'),                          // specific page ID
    array('location' => 'taxonomy:category'),                     // category archive
    array('location' => 'taxonomy:category:5'),                   // specific category
    array('location' => 'archive:date'),                          // date archive
    array('location' => 'archive:author'),                        // author archive
    array('location' => 'archive:404'),                           // 404 page
    array('location' => 'archive:search'),                        // search results
)
```

Plus an `_fl_theme_builder_exclusions` for "show on X *except* Y" cases.

### Rules engine flow

1. WP loads the page → `wp` action fires.
2. `FLThemeBuilderRulesLocation::get_current_page_location()` figures out what kind of page we're on (returns e.g., `'post:page:42'`).
3. `get_current_page_posts()` walks all `fl-builder-template` posts, checks each one's location rules + exclusions against the current page, returns the matching templates.
4. Templates with location `header` are rendered before content; `footer` after; `single`/`archive` replace the WP loop entirely.

### Direct application to v4.8.0 (Site Theme Mode)

**Simplest scope** (90% of users) — single global header + single global footer template, applied to all pages, with per-page opt-out:

```php
// New options in imp_site_config:
'theme_mode' => 'auto'|'global'    // default 'auto' (current invisible Passthrough)
'header_template_id' => INT        // ID of the IM-Press page acting as header
'footer_template_id' => INT        // ID of the IM-Press page acting as footer

// Per-page meta override:
_imp_use_site_chrome => true|false|null  // null = follow site config
```

**Mid scope** (BB-equivalent feature parity) — multiple headers/footers with location rules, e.g. "this header on /shop/, that header everywhere else":

Adopt BB's location-rule shape verbatim (string format like `post:page:42`, `taxonomy:category:5`) — minus the BB-internal types (`fl-theme-layout`, `fl-builder-template`). Store as post meta on a new IM-Press CPT `imp_template`. At `wp` action, walk all `imp_template` posts and decide which one to render based on rules.

**Recommended for v4.8.0:** ship simple scope first. Mid scope can be v4.9.0 if usage demands it.

---

## 5. UABB module conventions

UABB modules follow the same BB module structure but with UABB-specific extensions:

- **`uabb-` prefix** on every block name (`uabb-heading`, `uabb-info-box`, etc.)
- **More fields per module on average** — UABB heading has ~42 populated fields per production instance vs core BB heading's ~16
- **More elaborate visual layouts** — info-box has explicit positioning controls (above/left/right/below) for both icon and image, plus separator-under-title
- **`responsive_align`** + `r_custom_alignment` patterns — UABB ships per-breakpoint alignment as a first-class field on every text-bearing module

The depth audit Track B already addressed UABB depth — IM-Press's deepened info-box, callout, heading, button, etc. now match UABB capability.

---

## 6. BB extensions worth reviewing later

The `bb-plugin/extensions/` directory has 12 sub-extensions, each adding a feature surface:

| Extension | Function | IM-Press equivalent / status |
|---|---|---|
| `fl-theme-builder-core` | Theme Builder (header/footer/archive/single) | **Direct reference for v4.8.0.** |
| `fl-builder-global-styles` | Site-wide color/typography palette tied to design tokens | IM-Press has Site Config; could deepen with proper design-token system. |
| `fl-builder-popup-maker` | Modal/popup layouts triggered by user behavior | IM-Press has `imp/modal` (deepened in v4.7.0) + `imp/notification-bar`; covers most. |
| `fl-builder-cloud` | Sync layouts across multiple sites | **Not a current IM-Press priority.** |
| `fl-builder-multisite` | Multi-site network compatibility | Out of scope. |
| `fl-builder-version-control` | Layout revisions | WP core revisions cover this. |
| `fl-builder-user-templates` | Save/import user-created layout templates | IM-Press has Page Templates + Block Patterns. Adequate. |
| `fl-builder-cache-helper` | Page cache invalidation hooks | IM-Press has class-performance.php; check coverage. |
| `fl-builder-seo-plugins` | Yoast / Rank Math integration shims | IM-Press replaces Yoast directly; not applicable. |
| `fl-builder-template-data-exporter` | Export layouts as JSON | IM-Press has html-importer + page-templates; could add JSON export. |
| `fl-builder-addons-installer` | One-click install of additional addons | Marketplace pattern; long-term. |
| `fl-builder-dynamic-global` | Dynamic content via globals | Block_Data_Bindings covers. |

---

## 7. Net takeaways for IM-Press roadmap

### Adopt in v4.8.0
- Site Theme Mode using simplified BB location-rules model (single global header + footer with per-page override).
- Move new blocks (and v4.7.0-deepened blocks if we revisit them) to a tab-organized InspectorControls UI (General / Style / Advanced), via a shared React component.

### Adopt in v4.9.0+
- Composite field types — `<LinkControl>` (URL + target + rel + download) and `<SpacingControl>` (top/right/bottom/left with link button).
- `migrate_attributes()` convention on every deepened block class for back-compat as schemas change.
- Multiple theme templates with location rules (BB Theme Builder mid-scope parity).

### Track but do not commit
- Per-breakpoint typography (BB's strength; modern fluid trend competes with it). Decide based on user feedback after v4.7.0 ships.
- Frontend editor (BB's flagship differentiator, parity audit Option B). Heavyweight project. Only if user demand justifies the build cost.
- Global style tokens system (BB's `fl-builder-global-styles`). Useful but Site Config + Passthrough already cover ~70% of need.

### Do not adopt
- BB's `preview` hint system — irrelevant to Gutenberg's block API.
- BB's `deprecated/` directory pattern — over-engineered for IM-Press's age and release cadence.
- BB's `connections` field — overlaps with Gutenberg native bindings; pick one.

---

## 8. How to keep these notes current

- After every release that touches block UX, append a "Compared to BB on [date]" subsection in this doc.
- When a v4.7.0+ block reaches 30+ attrs, time to evaluate the tab-organized UI conversion.
- When designing v4.8.0 / v4.9.0, re-read sections 4 and 7 first.

**Source files re-read for this doc** (all on STO at `~/servicetechohio.com/wp-content/plugins/`):
- `bb-plugin/modules/heading/heading.php` — settings form + register_module
- `bb-plugin/extensions/fl-theme-builder-core/classes/class-fl-theme-builder-rules-location.php` — location rules engine
- `bb-plugin/extensions/fl-theme-builder-core/classes/class-fl-theme-builder-layout-data.php` — layout data store
- `bb-ultimate-addon/modules/info-box/info-box.php` — UABB depth pattern
- `bb-plugin/extensions/` listing — extension surface inventory
