Site Editor Bake & Sync (rig:bake)

Site Editor work — custom templates, template parts, user-created patterns, Global Styles, Font Library activations — lives in the WordPress database, not in your repo. Without a round-trip, that work is invisible to git, unreviewable, and lost when the site dies. rig:bake (shipped in WP Rig 3.5) closes the loop: it bakes database state into version-controlled theme files, then verifies and scrubs the database records.

Availability & requirements

  • Paradigm: active for universal and block-based themes — classic themes refuse with guidance (exit 1).
  • Requirements: Node 18+, WP-CLI 2.12+, writable active block theme.
  • Origin: a Node port of bacoords/wp-theme-control by Brian Coords, pinned to an upstream SHA, with WP Rig-specific forks.

Commands

npm run rig:bake            # all scopes: fonts → templates → styles → patterns
npm run rig:bake:plan       # read-only inventory + collision report
npm run rig:bake:clean -- .wp-theme-control/runs/<run>/manifest.tsv
npm run rig:bake -- <scope> [flags]   # one scope + upstream flags passthrough
ScopeWrites
planNothing — inventory, collisions, “nothing to bake” report.
patternspatterns/<slug>.php from published unsynced wp_block posts.
templatestemplates/*.html, parts/*.html — runtime-URL content patternizes to patterns/hidden-*.php with Inserter: no.
fontsassets/fonts/<slug>/ + the overlay’s fonts block.
stylesThe overlay’s settings/styles blocks (raw user Global Styles).
cleanDeletes only DB records whose exported files still match the manifest sha256; also removes the overlay.

Passthrough flags: --path=, --url=, --user=, --state-dir=, --dry-run, --clean, --force.

What ships where

ArtifactPathGit
Baked patternspatterns/*.php, patterns/hidden-*.phptracked
Baked templates/partstemplates/*.html, parts/*.htmltracked
Baked font filesassets/fonts/<slug>/**tracked
Global Styles overlayconfig/user-styles.jsontracked
Generated theme.jsontheme.jsongitignored — tokens.js is the sole writer
Run manifests/backups.wp-theme-control/**gitignored

The safety model

Every write appends kind / record_id / slug / target / sha256 to a per-run manifest under .wp-theme-control/runs/ (gitignored), with backups per run. Cleanup is conservative by design: rig:bake:clean deletes only records whose exported files still match the manifest hash, only for the expected post type, and only while the pattern is still unsynced or the Global Styles post is unchanged. --force bypasses the hash check only. Each baked pattern file carries an idempotent Baked: yes header so lint tooling can recognize it.

Runtime URLs

Content that references local absolute URLs (your dev site’s uploads, theme assets) is rewritten in PHP — via wp eval, so WordPress’ own parse_blocks() semantics stay byte-identical — to the three sanctioned runtime expressions: get_stylesheet_directory_uri(), wp_get_upload_dir()['baseurl'], and home_url(). Anything else containing PHP syntax is refused.

The user-styles overlay (SPEC-016)

Baked Global Styles and font activations never write theme.json directly — rig:tokens is the sole theme.json writer and would clobber them. Instead they land in config/user-styles.json, a git-tracked overlay that the tokens generator merges last:

  • Objects deep-merge; arrays replace wholesale.
  • Fonts collapse — custom definitions win on duplicate slugs.
  • SSOT keys (version, $schema, settings.viewport, settings.blockVisibility, isGlobalStylesUserThemeJSON) never merge.
  • Regeneration is deterministic: two rig:tokens runs after a bake are byte-identical.
  • The PHP runtime is overlay-blind — it is a build-time input only, guarded by a PHPUnit parity test.

The usage loop

git status                        # must be clean — a bake is reviewed as a diff
npm run rig:bake:plan             # inventory + collisions (writes nothing)
npm run rig:bake                  # writes files; does NOT clean the DB
npm run lint:patterns && npm run lint:blocks && npm run lint:css
git add -p && git commit          # review the diff
npm run rig:bake:clean -- .wp-theme-control/runs/<run>/manifest.tsv

The bake is a review-first workflow: nothing leaves the database until you have read the diff and committed it.

Lint integration for baked files

Patterns marked Baked: yes keep their Title/Slug/Categories and markup-validity checks but get a tolerance profile: scaffold-placeholder content downgrades to a warning, and hidden runtime patterns get a Categories warning. The three sanctioned runtime-URL PHP expressions are neutralized in block-comment attributes — any other PHP still fails lint:patterns.

Known boundaries

  • Synced patterns are not migrated; distribution packaging, localization, Media Library moves, and remote SSH targets are upstream boundaries, inherited.
  • The overlay never carries PHP expressions — local absolute URLs in captured styles are flagged (report-only), and media belongs in block markup instead.
  • Baked font families replace the token-derived fontFamilies list in editor presets (the user layer wins) — see Font Management.
  • Font asset files survive clean for recoverability; the overlay is removed with the styles/fonts clean.

Pair this with Design Tokens v2 (the merge contract), Font Management (the fonts boundary), and Theme Paradigms (why this is gated to block-capable themes).