Skip to content

feat: add flat CSS bundle toggle to plugin settings - #79

Merged
jackgranatowski merged 1 commit into
mainfrom
claude/flat-css-bundles-plugin-s1vj9s
Jun 26, 2026
Merged

feat: add flat CSS bundle toggle to plugin settings#79
jackgranatowski merged 1 commit into
mainfrom
claude/flat-css-bundles-plugin-s1vj9s

Conversation

@jackgranatowski

Copy link
Copy Markdown
Contributor

Adds a css_flat boolean setting so users can opt into the flat (no-@layer)
variant of whichever bundle they have selected. Changes:

  • class-settings.php: new get_css_flat() + css_flat persisted in save()
  • class-css-loader.php: appends .flat to the CSS filename when enabled
  • class-admin.php: flat toggle UI in Plugin Settings; handles POST save;
    local-file-ok check honours the flat suffix
  • class-framework-updater.php: best-effort download of .flat.css files
    alongside base bundles on every framework update

Adds a css_flat boolean setting so users can opt into the flat (no-@layer)
variant of whichever bundle they have selected. Changes:

- class-settings.php: new get_css_flat() + css_flat persisted in save()
- class-css-loader.php: appends .flat to the CSS filename when enabled
- class-admin.php: flat toggle UI in Plugin Settings; handles POST save;
  local-file-ok check honours the flat suffix
- class-framework-updater.php: best-effort download of .flat.css files
  alongside base bundles on every framework update
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

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 58 minutes and 44 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ 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.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

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: 68d70b62-4fd0-4bde-b0ba-6d24b0de3eca

📥 Commits

Reviewing files that changed from the base of the PR and between 58ebab4 and 9ef30ba.

📒 Files selected for processing (4)
  • SLASHED-for-WP/includes/class-admin.php
  • SLASHED-for-WP/includes/class-css-loader.php
  • SLASHED-for-WP/includes/class-framework-updater.php
  • SLASHED-for-WP/includes/class-settings.php
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/flat-css-bundles-plugin-s1vj9s

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.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add css_flat toggle to load/download .flat.css bundle variants
✨ Enhancement ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

Description

• Add a persisted "Use flat CSS bundle" setting for improved @layer compatibility.
• Resolve CSS file names with optional ".flat" suffix across admin checks and runtime loader.
• Download ".flat.css" bundle variants best-effort during framework updates (skip missing files).
Diagram

graph TD
A["Admin settings"] --> B[("WP options") ] --> C["CSS Loader"] --> D["Resolved CSS filename"]
D --> E[("dist/ CSS files")]
D --> F{{"CDN"}}
G["Framework updater"] --> F --> E
A --> E
subgraph Legend
  direction LR
  _svc["Service/Module"] ~~~ _db[("Storage")] ~~~ _ext{{"External"}}
end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Download flat variants only when css_flat is enabled
  • ➕ Reduces bandwidth/disk usage for users who never enable flat bundles
  • ➕ Keeps updater behavior simpler for older versions (no extra requests)
  • ➖ Toggling css_flat could require an immediate download step (more UX complexity)
  • ➖ Introduces an extra failure mode at toggle time instead of update time
2. Derive flat CSS locally by stripping @layer at runtime/update time
  • ➕ Removes dependency on CDN providing prebuilt .flat.css variants
  • ➕ Ensures flat option is always available for any version
  • ➖ Risky/fragile transformation (CSS parsing/rewriting) and hard to guarantee identical output
  • ➖ Adds maintenance and performance overhead versus serving a prebuilt artifact

Recommendation: Current approach is a good tradeoff: keep base bundle downloads atomic, and treat .flat.css as an optional enhancement with best-effort retrieval (skipping 404s preserves rollback compatibility). Consider the first alternative only if bandwidth/storage becomes a proven issue.

Files changed (4) +89 / -4

Enhancement (3) +65 / -3
class-admin.phpAdd "Use flat CSS bundle" setting UI and persist on save +35/-1

Add "Use flat CSS bundle" setting UI and persist on save

• Reads a new css_flat checkbox from POST and persists it via settings save. Updates the local CSS file existence check to include the optional .flat suffix. Adds admin-page styles and a new settings row explaining flat bundles.

SLASHED-for-WP/includes/class-admin.php

class-css-loader.phpAppend .flat suffix when resolving CSS filename +3/-2

Append .flat suffix when resolving CSS filename

• Updates bundle docblock to match current allowed bundles. Incorporates Slashed_Settings::get_css_flat() so the resolved CSS filename becomes slashed.<bundle>.flat.css when enabled.

SLASHED-for-WP/includes/class-css-loader.php

class-framework-updater.phpBest-effort download of .flat.css variants after base bundle update +27/-0

Best-effort download of .flat.css variants after base bundle update

• Documents the atomic-vs-best-effort behavior for base vs flat bundles. After successfully downloading base bundles, attempts to fetch slashed.<bundle>.flat.css for each bundle; non-200 responses are ignored to support older tags that lack flat artifacts.

SLASHED-for-WP/includes/class-framework-updater.php

Other (1) +24 / -1
class-settings.phpPersist and expose new css_flat boolean setting +24/-1

Persist and expose new css_flat boolean setting

• Extends settings shape to include css_flat, adds get_css_flat() accessor with safe fallback, and ensures save() persists the boolean. This allows other components to consistently resolve flat bundle behavior from stored settings.

SLASHED-for-WP/includes/class-settings.php

@jackgranatowski
jackgranatowski merged commit 7d93c17 into main Jun 26, 2026
9 checks passed
@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Missing flat file drops CSS 🐞 Bug ☼ Reliability
Description
For local delivery, Slashed_CSS_Loader::get_url() returns an empty string when the selected
*.flat.css file is missing, and Slashed_Core_Enqueue then skips enqueuing the framework
stylesheet entirely. This makes enabling css_flat break styling whenever the local flat artifact
is absent (e.g., after a rollback to a version without flat bundles).
Code

SLASHED-for-WP/includes/class-css-loader.php[R55-58]

		$source   = Slashed_Settings::get_css_source();
		$bundle   = self::get_bundle();
-		$filename = 'slashed.' . $bundle . '.css';
+		$flat     = Slashed_Settings::get_css_flat();
+		$filename = 'slashed.' . $bundle . ( $flat ? '.flat' : '' ) . '.css';
Relevance

⭐⭐⭐ High

Team previously fixed missing/removed bundle breakage via migration to keep CSS loading (PR #77);
similar reliability concern.

PR-#77
PR-#79

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The loader now appends .flat to the local filename when css_flat is enabled and returns '' if
that specific file doesn’t exist. The frontend/editor enqueue code treats '' as a hard stop and
returns early, so the framework stylesheet is never enqueued when the flat local file is missing.

SLASHED-for-WP/includes/class-css-loader.php[54-80]
SLASHED-for-WP/includes/class-core-enqueue.php[40-69]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
When `css_flat` is enabled and source is `local`, the loader only looks for `slashed.<bundle>.flat.css`; if it doesn't exist it returns `''`, and the enqueue layer bails, resulting in no framework CSS loaded.

## Issue Context
Returning `''` is currently used to surface missing local files, but with `css_flat` this can happen during normal supported workflows (e.g., rollback) and can wipe styling.

## Fix Focus Areas
- In local mode, if flat is enabled but the flat file is missing, fall back to the non-flat `slashed.<bundle>.css` if it exists.
- Keep the admin notice behavior if desired (e.g., detect “flat requested but missing” separately), but do not drop CSS entirely when a valid non-flat bundle is present.

### Suggested code-level approach
In the `else` (local) branch of `get_url()`:
- If `$flat` is true:
 - Check for `slashed.<bundle>.flat.css`; if present, use it.
 - Else check for `slashed.<bundle>.css`; if present, use it.
 - Else return `''`.

## Fix Focus Areas (exact locations)
- SLASHED-for-WP/includes/class-css-loader.php[54-80]
- SLASHED-for-WP/includes/class-core-enqueue.php[40-68]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Stale flat files on rollback 🐞 Bug ≡ Correctness
Description
In Slashed_Framework_Updater::download_files(), flat bundle downloads are skipped on non-200
responses and write failures are ignored, so existing slashed.*.flat.css files can remain from a
previous version after a rollback. With css_flat enabled, Slashed_CSS_Loader::get_url() will
keep serving that stale flat file even though LOCAL_VER_OPTION is updated to the rolled-back
version.
Code

SLASHED-for-WP/includes/class-framework-updater.php[R181-202]

+		// Best-effort: download flat (.flat.css) variants. These were introduced
+		// alongside the layer-based bundles; older release tags may not have them,
+		// so a non-200 response is silently skipped rather than failing the update.
+		foreach ( self::BUNDLES as $bundle ) {
+			$filename = 'slashed.' . $bundle . '.flat.css';
+			$url      = sprintf( self::CDN_BASE, rawurlencode( $version ), $filename );
+
+			$response = wp_remote_get(
+				$url,
+				array(
+					'timeout'    => 30,
+					'user-agent' => 'SLASHED/' . SLASHED_VERSION . '; WordPress/' . get_bloginfo( 'version' ),
+				)
+			);
+
+			if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
+				continue;
+			}
+
+			$content = wp_remote_retrieve_body( $response );
+			$wp_filesystem->put_contents( $dist_dir . $filename, $content, FS_CHMOD_FILE );
+		}
Relevance

⭐⭐ Medium

Rollback support exists (PR #4), but no historical evidence they delete stale dist artifacts; flat
downloads intentionally best-effort (PR #79).

PR-#4
PR-#79

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The updater’s flat download loop explicitly continues on errors/non-200 and does not remove or
replace existing .flat.css files; it also ignores the return value of put_contents(). Because
the CSS loader builds the .flat.css filename when css_flat is true and serves local files based
on file_exists(), leftover flat files will continue to be served after a rollback or partial
failure.

SLASHED-for-WP/includes/class-framework-updater.php[178-202]
SLASHED-for-WP/includes/class-css-loader.php[54-80]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
When updating/rolling back framework files, the best-effort flat download loop can leave old `slashed.<bundle>.flat.css` files in `dist/` if the requested version doesn't provide flat assets (e.g., 404) or if the write fails. Since the loader prefers `.flat.css` when `css_flat` is enabled, this can cause serving a mismatched framework version.

## Issue Context
Base bundles are staged and installed atomically, but flat variants are written directly and failures are silently ignored.

## Fix Focus Areas
- Ensure no stale flat files remain after a non-200/failed flat download (delete existing `.flat.css` for that bundle when the new one can't be retrieved).
- Check `put_contents()` return value for flat writes; on failure, delete any partially written file.
- (Optional) Use the same tmp+move approach as base bundles for `.flat.css` when a 200 response is received.

### Suggested code-level approach
For each bundle in the flat loop:
- Compute `$final_path = $dist_dir . $filename`.
- If response is WP_Error or status != 200: `$wp_filesystem->delete( $final_path ); continue;`
- If 200: write to `$tmp_path = $final_path . '.tmp'`, verify write, then move to `$final_path`.

## Fix Focus Areas (exact locations)
- SLASHED-for-WP/includes/class-framework-updater.php[181-202]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment on lines +181 to +202
// Best-effort: download flat (.flat.css) variants. These were introduced
// alongside the layer-based bundles; older release tags may not have them,
// so a non-200 response is silently skipped rather than failing the update.
foreach ( self::BUNDLES as $bundle ) {
$filename = 'slashed.' . $bundle . '.flat.css';
$url = sprintf( self::CDN_BASE, rawurlencode( $version ), $filename );

$response = wp_remote_get(
$url,
array(
'timeout' => 30,
'user-agent' => 'SLASHED/' . SLASHED_VERSION . '; WordPress/' . get_bloginfo( 'version' ),
)
);

if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
continue;
}

$content = wp_remote_retrieve_body( $response );
$wp_filesystem->put_contents( $dist_dir . $filename, $content, FS_CHMOD_FILE );
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Stale flat files on rollback 🐞 Bug ≡ Correctness

In Slashed_Framework_Updater::download_files(), flat bundle downloads are skipped on non-200
responses and write failures are ignored, so existing slashed.*.flat.css files can remain from a
previous version after a rollback. With css_flat enabled, Slashed_CSS_Loader::get_url() will
keep serving that stale flat file even though LOCAL_VER_OPTION is updated to the rolled-back
version.
Agent Prompt
## Issue description
When updating/rolling back framework files, the best-effort flat download loop can leave old `slashed.<bundle>.flat.css` files in `dist/` if the requested version doesn't provide flat assets (e.g., 404) or if the write fails. Since the loader prefers `.flat.css` when `css_flat` is enabled, this can cause serving a mismatched framework version.

## Issue Context
Base bundles are staged and installed atomically, but flat variants are written directly and failures are silently ignored.

## Fix Focus Areas
- Ensure no stale flat files remain after a non-200/failed flat download (delete existing `.flat.css` for that bundle when the new one can't be retrieved).
- Check `put_contents()` return value for flat writes; on failure, delete any partially written file.
- (Optional) Use the same tmp+move approach as base bundles for `.flat.css` when a 200 response is received.

### Suggested code-level approach
For each bundle in the flat loop:
- Compute `$final_path = $dist_dir . $filename`.
- If response is WP_Error or status != 200: `$wp_filesystem->delete( $final_path ); continue;`
- If 200: write to `$tmp_path = $final_path . '.tmp'`, verify write, then move to `$final_path`.

## Fix Focus Areas (exact locations)
- SLASHED-for-WP/includes/class-framework-updater.php[181-202]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines 55 to +58
$source = Slashed_Settings::get_css_source();
$bundle = self::get_bundle();
$filename = 'slashed.' . $bundle . '.css';
$flat = Slashed_Settings::get_css_flat();
$filename = 'slashed.' . $bundle . ( $flat ? '.flat' : '' ) . '.css';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Missing flat file drops css 🐞 Bug ☼ Reliability

For local delivery, Slashed_CSS_Loader::get_url() returns an empty string when the selected
*.flat.css file is missing, and Slashed_Core_Enqueue then skips enqueuing the framework
stylesheet entirely. This makes enabling css_flat break styling whenever the local flat artifact
is absent (e.g., after a rollback to a version without flat bundles).
Agent Prompt
## Issue description
When `css_flat` is enabled and source is `local`, the loader only looks for `slashed.<bundle>.flat.css`; if it doesn't exist it returns `''`, and the enqueue layer bails, resulting in no framework CSS loaded.

## Issue Context
Returning `''` is currently used to surface missing local files, but with `css_flat` this can happen during normal supported workflows (e.g., rollback) and can wipe styling.

## Fix Focus Areas
- In local mode, if flat is enabled but the flat file is missing, fall back to the non-flat `slashed.<bundle>.css` if it exists.
- Keep the admin notice behavior if desired (e.g., detect “flat requested but missing” separately), but do not drop CSS entirely when a valid non-flat bundle is present.

### Suggested code-level approach
In the `else` (local) branch of `get_url()`:
- If `$flat` is true:
  - Check for `slashed.<bundle>.flat.css`; if present, use it.
  - Else check for `slashed.<bundle>.css`; if present, use it.
  - Else return `''`.

## Fix Focus Areas (exact locations)
- SLASHED-for-WP/includes/class-css-loader.php[54-80]
- SLASHED-for-WP/includes/class-core-enqueue.php[40-68]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

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.

1 participant