Skip to content

refactor: move token infrastructure to global includes/ - #169

Merged
jackgranatowski merged 2 commits into
mainfrom
claude/gutenberg-integration-scope-jSOZX
May 31, 2026
Merged

refactor: move token infrastructure to global includes/#169
jackgranatowski merged 2 commits into
mainfrom
claude/gutenberg-integration-scope-jSOZX

Conversation

@jackgranatowski

@jackgranatowski jackgranatowski commented May 31, 2026

Copy link
Copy Markdown
Contributor

$(cat <<'EOF'

Summary

  • Token overrides, REST API, and admin page are now global — moved from integrations/bricks/includes/ to includes/ and renamed from Slashed_Bricks_* to Slashed_*
  • slashed.php owns the global token pipeline: loads shared classes, registers slashed/v1 REST routes, injects override CSS on both wp_enqueue_scripts and enqueue_block_editor_assets (priority 20), and bootstraps the Tokens admin page
  • Bricks integration cleaned up: standalone fallback loads global classes from ../../includes/; Bricks-specific REST endpoints updated to slashed/v1 namespace; override CSS injection removed from Slashed_Bricks_Enqueue (now handled globally)

What moved

Old (Bricks-scoped) New (global)
Slashed_Bricks_Token_Store Slashed_Token_Store
Slashed_Bricks_Token_Sanitizer Slashed_Token_Sanitizer
Slashed_Bricks_Token_Defaults Slashed_Token_Defaults
Slashed_Bricks_Tab_Registry Slashed_Tab_Registry
Slashed_Bricks_CSS_Generator Slashed_CSS_Generator
Slashed_Bricks_REST_Controller (slashed-bricks/v1) Slashed_REST_Controller (slashed/v1)
Slashed_Bricks_Admin_Page_Svelte Slashed_Token_Page

Migration

Slashed_Token_Store::get_settings() performs a one-time silent migration: if slashed_tokens doesn't exist but slashed_bricks_tokens has data, it copies to the new option and deletes the old one. Existing token configurations are preserved automatically.

Test plan

  • Unified mode (slashed.php): token editor loads, saves, and applies CSS overrides on both Bricks and Gutenberg pages
  • Standalone Bricks plugin: activating slashed-bricks.php directly still works — loads global classes from ../../includes/
  • REST routes respond at slashed/v1 (tokens, settings, rebemer/unused, bricks-fonts)
  • Existing slashed_bricks_tokens option is migrated to slashed_tokens on first load
  • No PHP notices/errors with Bricks inactive (Gutenberg-only)

https://claude.ai/code/session_01DU3r3kT7GqH7w7jeadV2DT
EOF
)


Generated by Claude Code

Summary by CodeRabbit

  • Refactor

    • Unified token management infrastructure from integration-specific to shared core plugin layer
    • Consolidated REST API endpoints under single namespace (slashed/v1)
    • Reorganized token override CSS generation system for improved maintainability
  • Chores

    • Removed duplicate code from integration layer
    • Streamlined admin initialization

Token overrides (--sf-* CSS variables), REST API, admin page, and
supporting classes are framework-level concerns shared by all builder
integrations — not Bricks-specific.

Moved from integrations/bricks/includes/ → includes/:
  class-token-store.php       → Slashed_Token_Store (was Slashed_Bricks_Token_Store)
  class-token-sanitizer.php   → Slashed_Token_Sanitizer
  class-token-defaults.php    → Slashed_Token_Defaults
  class-tab-registry.php      → Slashed_Tab_Registry
  class-css-generator.php     → Slashed_CSS_Generator
  class-rest-controller.php   → Slashed_REST_Controller (namespace: slashed/v1)
  class-admin-page-svelte.php → class-token-page.php (Slashed_Token_Page)

slashed.php now owns: token class loading, REST route registration
(slashed/v1), global override CSS injection (wp_enqueue_scripts +
enqueue_block_editor_assets at priority 20), and admin page bootstrap.

slashed-bricks.php: standalone-mode fallback loads shared classes from
../../includes/; Bricks REST endpoints (rebemer, fonts) updated to
slashed/v1 namespace; override CSS injection removed from Enqueue class
(now handled globally).

Slashed_Token_Store performs a one-time migration from the legacy
slashed_bricks_tokens option to slashed_tokens on first read.

https://claude.ai/code/session_01DU3r3kT7GqH7w7jeadV2DT
@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jackgranatowski, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 46 minutes and 40 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4c21092a-5a3e-48f1-8f18-2bf2a8e4b5e0

📥 Commits

Reviewing files that changed from the base of the PR and between fbc8c7d and 5744f07.

📒 Files selected for processing (6)
  • includes/class-css-generator.php
  • includes/class-token-page.php
  • includes/class-token-store.php
  • integrations/bricks/includes/class-inventory.php
  • integrations/bricks/includes/class-rebemer-rest.php
  • integrations/bricks/slashed-bricks.php
📝 Walkthrough

Walkthrough

This PR consolidates Bricks-specific token management infrastructure (store, sanitizer, REST API, admin page) into unified, shared plugin components registered under the slashed/v1 namespace. The refactoring eliminates duplicate code, establishes a single source of truth for token persistence and validation, and enables both unified and standalone operation modes.

Changes

Unified Token Infrastructure

Layer / File(s) Summary
Token Store: Centralized persistence
includes/class-token-store.php
New Slashed_Token_Store class provides static methods for reading/writing token overrides with legacy migration, per-section updates, and plugin settings merged with defaults.
Token Sanitizer: Input validation and normalization
includes/class-token-sanitizer.php
New Slashed_Token_Sanitizer class validates and sanitizes token submissions, grouping color pairs by suffix precedence (_raw > _hex), stripping CSS-breaking characters, and detecting hex literals with PHP 7.4 compatibility.
Unified registry and defaults: Namespace consolidation
includes/class-tab-registry.php, includes/class-token-defaults.php
Slashed_Bricks_Tab_RegistrySlashed_Tab_Registry and Slashed_Bricks_Token_DefaultsSlashed_Token_Defaults; consolidates single source of truth for admin tabs and default token structures.
CSS Generator: Unified class and filter hook
includes/class-css-generator.php
Refactors Slashed_Bricks_CSS_GeneratorSlashed_CSS_Generator to use Slashed_Token_Store for option access, updates override-CSS filter hook to slashed/override_css, and rewrites helper methods with updated settings access patterns and fluid clamp() computation.
REST Controller and Token Page: Unified admin interface
includes/class-rest-controller.php, includes/class-token-page.php
New Slashed_REST_Controller registers unified REST endpoints (POST /tokens, /tokens/validate, /tokens/reset, GET /tokens/export, POST /tokens/import, GET /settings, POST /settings) under slashed/v1. New Slashed_Token_Page handles admin page registration, conditional SPA asset enqueueing, and localization with REST metadata.
Main plugin bootstrap and token injection
slashed.php
Extends main plugin to load token infrastructure, register REST routes, instantiate Slashed_Token_Page in admin, and inject token override CSS via slashed_inject_token_overrides() hooked to both frontend and editor enqueue flows.
Bricks integration: Conditional loading and namespace updates
integrations/bricks/slashed-bricks.php, integrations/bricks/includes/class-*.php, .php
Adjusts Bricks bootstrap to conditionally load shared token classes in standalone mode, updates REST endpoints from slashed-bricks/v1 to slashed/v1, removes Bricks-specific admin/token CRUD implementations (class-admin-page-svelte.php, class-rest-controller.php, class-token-sanitizer.php, class-token-store.php), and updates option/class references throughout integration.

Possibly related PRs

  • codeslash-dev/SLASHED#77: Initial Bricks admin-token GUI infrastructure refactored and consolidated by this PR into shared unified classes.
  • codeslash-dev/SLASHED#98: Admin SPA expansion that adds POST /settings endpoint and surfaces pluginSettings/inventory now supported by the unified REST controller and token store.
  • codeslash-dev/SLASHED#71: Initial Bricks enqueue class implementation that this PR refactors by moving inline token-override CSS injection to main plugin bootstrap.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.91% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the primary change: moving token infrastructure from Bricks-specific integration folders to global includes/ with corresponding class renames.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/gutenberg-integration-scope-jSOZX

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (2)
integrations/bricks/includes/class-rebemer-rest.php (1)

71-72: 💤 Low value

Stale docblock reference to the "legacy admin REST controller."

register_routes() is no longer called "alongside the legacy admin REST controller" — slashed_bricks_rest_routes_init() now registers only the Bricks-specific endpoints, with the token CRUD controller registered globally by slashed.php. Update this note for accuracy.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@integrations/bricks/includes/class-rebemer-rest.php` around lines 71 - 72,
Docblock text is stale: update the comment for register_routes() so it no longer
claims it runs "alongside the legacy admin REST controller"; instead state that
slashed_bricks_rest_routes_init() registers only Bricks-specific endpoints and
that the token CRUD controller is registered globally by slashed.php. Edit the
docblock on register_routes() in class-rebemer-rest.php to replace the legacy
admin controller reference with this accurate description and keep function
names exactly as mentioned (register_routes(),
slashed_bricks_rest_routes_init(), slashed.php, token CRUD controller) for
clarity.
integrations/bricks/slashed-bricks.php (1)

138-152: 💤 Low value

Stale docblock references the removed slashed_bricks_admin_init().

Lines 146-151 still describe a now-deleted admin-init path ("ALSO instantiated inside slashed_bricks_admin_init()"), which no longer exists after this refactor. Trim this paragraph to avoid misleading future readers, since the controller is now registered globally by slashed.php.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@integrations/bricks/slashed-bricks.php` around lines 138 - 152, The docblock
still mentions a removed admin-init path; remove or trim the paragraph
referencing slashed_bricks_admin_init() so it no longer claims the REST
controller is "ALSO instantiated inside `slashed_bricks_admin_init()`"; keep the
explanation that routes are registered via rest_api_init and note that the
controller is now registered globally by slashed.php (and that NAMESPACE is
available for wp_localize_script) to avoid misleading readers.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@includes/class-css-generator.php`:
- Around line 32-33: The code is directly calling get_option(...) which bypasses
the legacy migration in Slashed_Token_Store; replace those direct reads with
Slashed_Token_Store::get_settings() so the migration path in
includes/class-token-store.php runs; specifically update the has_overrides()
method and the other read sites around the 64-69 region to call
Slashed_Token_Store::get_settings() (instead of
get_option(Slashed_Token_Store::OPTION_NAME, array())) and use the returned
array for checks so existing installs trigger the "first load" migration.

In `@includes/class-rest-controller.php`:
- Around line 300-316: The import currently seeds $all from
Slashed_Token_Store::get_settings(), causing a merge instead of replacing the
token state; change the logic so you build a fresh settings array from
$body['tokens'] (use Slashed_Tab_Registry::is_token_tab and
Slashed_Token_Sanitizer::sanitize_section to validate and sanitize each section)
and then call Slashed_Token_Store::update_settings with only those sanitized
sections so any sections not present in the import are removed rather than
preserved.

In `@includes/class-token-page.php`:
- Around line 41-61: The register_menu() method (and the class-token-page usage)
assumes unified-plugin constants like SLASHED_VERSION, SLASHED_URL,
SLASHED_PATH, and SLASHED_CSS_REF are always defined; when SLASHED_VERSION is
undefined the standalone branch still later dereferences those constants and can
fatal or load wrong assets. Fix by adding defensive checks and fallbacks: change
any unconditional uses of SLASHED_URL, SLASHED_PATH, SLASHED_VERSION,
SLASHED_CSS_REF to use defined(...) ? constant : sensible default (or properties
injected by the bootstrap), and/or update the class constructor to accept and
store injected baseUrl/basePath/version/cssRef values so register_menu(),
render_page(), and asset-resolution code use the injected properties instead of
raw constants.

In `@includes/class-token-sanitizer.php`:
- Around line 45-51: The current array handling in the token sanitizer only
sanitizes one level via array_map and casts nested arrays to "Array", losing
nested token maps; replace that one-level array_map callback with a recursive
sanitizer method (e.g., sanitize_value) that: when $value is an array iterates
keys, uses sanitize_key() and skips empty keys, recursively calls
self::sanitize_value() for nested values, and for non-arrays returns
self::sanitize_css_value( sanitize_text_field( (string) $value ) ); then use
this sanitize_value function wherever the one-level array_map/static callback
was used (the existing array handling in the class-token-sanitizer.php) so
nested token maps like typography.font_sizes.* and spacing.space_sizes.* are
preserved.

In `@includes/class-token-store.php`:
- Around line 113-114: delete_settings() currently only deletes
self::OPTION_NAME which leaves the legacy option 'slashed_bricks_tokens' intact
and causes it to be re-migrated on next get_settings(); update delete_settings()
to also delete the legacy option by calling
delete_option('slashed_bricks_tokens') (or the stored legacy constant/name) so
both the current option (self::OPTION_NAME) and the legacy option are removed to
make “Reset all” durable across upgraded installs; reference delete_settings(),
get_settings(), and self::OPTION_NAME when making the change.

In `@integrations/bricks/includes/class-inventory.php`:
- Around line 192-193: get_admin_color_overrides() currently reads tokens
directly via get_option(Slashed_Token_Store::OPTION_NAME) which bypasses the
token-store API and prevents the legacy migration in
Slashed_Token_Store::get_settings() from running; update
get_admin_color_overrides() in class-inventory.php to call
Slashed_Token_Store::get_settings() (or the appropriate accessor on
Slashed_Token_Store) and use the returned settings/tokens instead of calling
get_option() directly so the legacy migration path
(Slashed_Token_Store::LEGACY_OPTION_NAME) is honored and admin color overrides
reflect migrated values.

---

Nitpick comments:
In `@integrations/bricks/includes/class-rebemer-rest.php`:
- Around line 71-72: Docblock text is stale: update the comment for
register_routes() so it no longer claims it runs "alongside the legacy admin
REST controller"; instead state that slashed_bricks_rest_routes_init() registers
only Bricks-specific endpoints and that the token CRUD controller is registered
globally by slashed.php. Edit the docblock on register_routes() in
class-rebemer-rest.php to replace the legacy admin controller reference with
this accurate description and keep function names exactly as mentioned
(register_routes(), slashed_bricks_rest_routes_init(), slashed.php, token CRUD
controller) for clarity.

In `@integrations/bricks/slashed-bricks.php`:
- Around line 138-152: The docblock still mentions a removed admin-init path;
remove or trim the paragraph referencing slashed_bricks_admin_init() so it no
longer claims the REST controller is "ALSO instantiated inside
`slashed_bricks_admin_init()`"; keep the explanation that routes are registered
via rest_api_init and note that the controller is now registered globally by
slashed.php (and that NAMESPACE is available for wp_localize_script) to avoid
misleading readers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: eef7974a-a0d8-43a7-9d67-f31431603c14

📥 Commits

Reviewing files that changed from the base of the PR and between 7a7c9bc and fbc8c7d.

📒 Files selected for processing (18)
  • includes/class-css-generator.php
  • includes/class-rest-controller.php
  • includes/class-tab-registry.php
  • includes/class-token-defaults.php
  • includes/class-token-page.php
  • includes/class-token-sanitizer.php
  • includes/class-token-store.php
  • integrations/bricks/includes/class-admin-page-svelte.php
  • integrations/bricks/includes/class-enqueue.php
  • integrations/bricks/includes/class-fonts-rest.php
  • integrations/bricks/includes/class-inventory.php
  • integrations/bricks/includes/class-rebemer-enqueue.php
  • integrations/bricks/includes/class-rebemer-rest.php
  • integrations/bricks/includes/class-rest-controller.php
  • integrations/bricks/includes/class-token-sanitizer.php
  • integrations/bricks/includes/class-token-store.php
  • integrations/bricks/slashed-bricks.php
  • slashed.php
💤 Files with no reviewable changes (5)
  • integrations/bricks/includes/class-token-store.php
  • integrations/bricks/includes/class-rest-controller.php
  • integrations/bricks/includes/class-enqueue.php
  • integrations/bricks/includes/class-admin-page-svelte.php
  • integrations/bricks/includes/class-token-sanitizer.php

Comment thread includes/class-css-generator.php Outdated
Comment on lines +300 to +316
$all = Slashed_Token_Store::get_settings();
$imported = 0;

foreach ( $body['tokens'] as $section => $values ) {
if ( ! Slashed_Tab_Registry::is_token_tab( $section ) || ! is_array( $values ) ) {
continue;
}
$sanitized = Slashed_Token_Sanitizer::sanitize_section( $section, $values );
if ( ! empty( $sanitized ) ) {
$all[ $section ] = $sanitized;
++$imported;
} else {
unset( $all[ $section ] );
}
}

Slashed_Token_Store::update_settings( $all );

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Import should replace the saved token state, not merge into it.

Line 300 seeds the import with the site's existing overrides, so an export file that only contains colors will leave any old spacing, layouts, etc. in place on the target site. That means export → import does not faithfully reproduce the source configuration.

Suggested fix
-		$all      = Slashed_Token_Store::get_settings();
+		$all      = array();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@includes/class-rest-controller.php` around lines 300 - 316, The import
currently seeds $all from Slashed_Token_Store::get_settings(), causing a merge
instead of replacing the token state; change the logic so you build a fresh
settings array from $body['tokens'] (use Slashed_Tab_Registry::is_token_tab and
Slashed_Token_Sanitizer::sanitize_section to validate and sanitize each section)
and then call Slashed_Token_Store::update_settings with only those sanitized
sections so any sections not present in the import are removed rather than
preserved.

Comment thread includes/class-token-page.php
Comment on lines +45 to +51
if ( is_array( $value ) ) {
$sanitized[ $key ] = array_map(
static function ( $v ) {
return self::sanitize_css_value( sanitize_text_field( (string) $v ) );
},
$value
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve nested token maps when sanitizing non-color sections.

This only sanitizes one array level. Shapes like typography.font_sizes.2xs = ['min' => ..., 'max' => ...] and spacing.space_sizes.* will hit the callback as arrays, get cast to "Array", and lose their bounds on save.

Suggested fix
-			if ( is_array( $value ) ) {
-				$sanitized[ $key ] = array_map(
-					static function ( $v ) {
-						return self::sanitize_css_value( sanitize_text_field( (string) $v ) );
-					},
-					$value
-				);
-			} else {
-				$sanitized[ $key ] = self::sanitize_css_value( sanitize_text_field( (string) $value ) );
-			}
+			$sanitized[ $key ] = self::sanitize_value( $value );
private static function sanitize_value( $value ) {
	if ( is_array( $value ) ) {
		$sanitized = array();

		foreach ( $value as $key => $nested_value ) {
			$key = sanitize_key( $key );
			if ( '' === $key ) {
				continue;
			}

			$sanitized[ $key ] = self::sanitize_value( $nested_value );
		}

		return $sanitized;
	}

	return self::sanitize_css_value( sanitize_text_field( (string) $value ) );
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@includes/class-token-sanitizer.php` around lines 45 - 51, The current array
handling in the token sanitizer only sanitizes one level via array_map and casts
nested arrays to "Array", losing nested token maps; replace that one-level
array_map callback with a recursive sanitizer method (e.g., sanitize_value)
that: when $value is an array iterates keys, uses sanitize_key() and skips empty
keys, recursively calls self::sanitize_value() for nested values, and for
non-arrays returns self::sanitize_css_value( sanitize_text_field( (string)
$value ) ); then use this sanitize_value function wherever the one-level
array_map/static callback was used (the existing array handling in the
class-token-sanitizer.php) so nested token maps like typography.font_sizes.* and
spacing.space_sizes.* are preserved.

Comment thread includes/class-token-store.php
Comment thread integrations/bricks/includes/class-inventory.php Outdated
- class-css-generator: use Slashed_Token_Store::get_settings() instead
  of direct get_option() in both has_overrides() and get_override_css()
  so the legacy slashed_bricks_tokens → slashed_tokens migration always
  runs on first access regardless of which read path fires first

- class-token-store: delete_settings() now also deletes the legacy
  LEGACY_OPTION_NAME option so "Reset all" is durable on upgraded
  installs (without this, the migration would repopulate tokens on the
  next get_settings() call)

- class-inventory: get_admin_color_overrides() routed through
  Slashed_Token_Store::get_settings() for the same migration reason

- class-token-page: enqueue_assets() and get_class_hints() now use
  defined() checks with SLASHED_BRICKS_* fallbacks so the class is
  safe to instantiate when only the standalone Bricks plugin is active

- slashed-bricks.php (standalone): add missing bootstrap block —
  registers Slashed_REST_Controller routes, instantiates Slashed_Token_Page
  (admin only), and hooks slashed_inject_token_overrides so token override
  CSS is injected in standalone mode the same way slashed.php does it

- Stale docblocks in class-rebemer-rest.php and slashed-bricks.php
  updated to reflect the current architecture

https://claude.ai/code/session_01DU3r3kT7GqH7w7jeadV2DT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants