Skip to content

fix(assets): enqueue wu-admin styles on addon pages for wu-form modals#891

Merged
superdav42 merged 1 commit intomainfrom
fix/addon-pages-wu-form-styling
Apr 16, 2026
Merged

fix(assets): enqueue wu-admin styles on addon pages for wu-form modals#891
superdav42 merged 1 commit intomainfrom
fix/addon-pages-wu-form-styling

Conversation

@superdav42
Copy link
Copy Markdown
Collaborator

@superdav42 superdav42 commented Apr 16, 2026

Summary

  • Fix unstyled wu-form modals on addon pages like the multinetwork addon's /wp-admin/network/admin.php?page=wu-networks
  • Broaden wu_is_wu_page() to also match hook suffixes containing _page_wu-, covering addon slug conventions
  • Add a new wu_is_wu_page filter so addons with non-standard slugs can opt in

Root cause

PR #433 (commit cb5a40f) introduced wu_is_wu_page() which only returned true for hook suffixes containing wp-ultimo. This correctly scoped 150KB+ of CSS/JS away from unrelated admin pages, but also broke addon pages whose slugs start with wu- (the long-standing convention for addons).

On the multinetwork page, clicking "Add New Network" opens a wu-form via wubox's createAjaxBox, which injects the form content inline into the parent document. Without wu-admin.css loaded on the parent page, the modal rendered completely un-styled.

Changes

inc/functions/assets.phpwu_is_wu_page()

  • Now matches both wp-ultimo (core) and _page_wu- (addons) in the hook suffix.
  • Trailing hyphen in _page_wu- prevents false positives on unrelated slugs like wunderground.
  • Result is passed through a new wu_is_wu_page filter for explicit opt-in/opt-out.

tests/WP_Ultimo/Functions/Assets_Functions_Test.php — 8 new test cases covering core, addon (toplevel / network / submenu), unrelated pages, the false-positive guard, and the filter opt-in/opt-out.

tests/WP_Ultimo/Scripts_Test.php — bonus: fix stale assertions still referencing admin_init after PR #433 moved the enqueue hook to admin_enqueue_scripts.

Testing

  • PHPStan: clean on changed files.
  • Logic smoke-tested standalone — 11/11 assertions pass.
  • Full phpunit runs in CI.

Backward compatibility

No breaking changes. Addon developers using non-wu- slugs can register via the filter:

add_filter( 'wu_is_wu_page', function ( $is_wu_page, $hook_suffix ) {
    if ( str_contains( $hook_suffix, 'my-addon-slug' ) ) {
        return true;
    }
    return $is_wu_page;
}, 10, 2 );

Summary by CodeRabbit

  • New Features

    • Introduced a customizable filter for admin page detection, enabling developers to extend or modify the default detection behavior
  • Improvements

    • Enhanced detection logic to recognize more Ultimate Multisite admin page patterns, including core and add-on pages
  • Tests

    • Added comprehensive test coverage for various admin page detection scenarios and edge cases

PR #433 scoped admin asset enqueues to pages whose hook suffix contains
`wp-ultimo`. Addon pages (e.g. multinetwork's `wu-networks`) have hook
suffixes like `toplevel_page_wu-networks-network` that do not contain
`wp-ultimo`, so wu-admin.css and wu-styling.css were never loaded. When
those pages opened a wu-form modal (injected inline by wubox), the modal
rendered with no styling.

Changes:
- Broaden wu_is_wu_page() to also match `_page_wu-`, covering both
  `toplevel_page_wu-*` and `{parent}_page_wu-*` slugs. The trailing
  hyphen avoids false positives on slugs like `wunderground`.
- Add a new `wu_is_wu_page` filter so addons with non-standard slugs
  can explicitly opt in (or opt out).
- Update PHPDoc with recognized patterns and filter usage example.
- Add tests covering core, addon, false-positive, and filter cases.
- Fix stale Scripts_Test.php assertions still referencing admin_init
  after the hook was moved to admin_enqueue_scripts in PR #433.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 16, 2026

📝 Walkthrough

Walkthrough

The wu_is_wu_page() function now detects both core WordPress Ultimo pages (wp-ultimo) and addon pages with wu- slug prefixes by checking the hook suffix against both patterns. A new wu_is_wu_page filter is applied before returning, allowing extensibility. Comprehensive tests are added for the function, and admin script/style enqueue hooks are changed from admin_init to admin_enqueue_scripts.

Changes

Cohort / File(s) Summary
Page Detection Logic
inc/functions/assets.php
Enhanced wu_is_wu_page() to detect both wp-ultimo (core) and _page_wu- (addon) patterns in hook suffixes. Introduced wu_is_wu_page filter for customization. Docblocks updated to reflect expanded detection behavior.
Function Test Suite
tests/WP_Ultimo/Functions/Assets_Functions_Test.php
Added comprehensive unit tests covering core pages, addon pages with wu- prefix, non-Ultimate Multisite pages, edge cases, and filter callback behavior for opting in and out.
Hook Timing Update
tests/WP_Ultimo/Scripts_Test.php
Updated test expectations to verify admin default styles and scripts enqueue on admin_enqueue_scripts hook instead of admin_init.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Hops of joy through wu- paths,
Core and addon both now sing,
Filter magic lets us sway,
Tests hop in every which way,
Scripts enqueue at just the right time!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(assets): enqueue wu-admin styles on addon pages for wu-form modals' accurately describes the main fix: extending asset enqueuing to addon pages to style wu-form modals.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/addon-pages-wu-form-styling

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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/WP_Ultimo/Functions/Assets_Functions_Test.php (1)

139-172: Filter cleanup is not exception-safe.

If an assertion in either filter test fails, remove_filter() never runs and the callback leaks into subsequent tests in the same process, which can make later failures confusing. Consider moving the removal into tear_down() or wrapping with try/finally. Minor — not blocking.

Proposed refactor
 	public function test_wu_is_wu_page_filter_opt_in(): void {

 		$callback = function ($is_wu_page, $hook_suffix) {
 			if ('toplevel_page_my-custom-addon' === $hook_suffix) {
 				return true;
 			}
 			return $is_wu_page;
 		};

 		add_filter('wu_is_wu_page', $callback, 10, 2);
-
-		$this->assertTrue(wu_is_wu_page('toplevel_page_my-custom-addon'));
-
-		remove_filter('wu_is_wu_page', $callback, 10);
+		try {
+			$this->assertTrue(wu_is_wu_page('toplevel_page_my-custom-addon'));
+		} finally {
+			remove_filter('wu_is_wu_page', $callback, 10);
+		}
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/WP_Ultimo/Functions/Assets_Functions_Test.php` around lines 139 - 172,
The tests test_wu_is_wu_page_filter_opt_in and test_wu_is_wu_page_filter_opt_out
add a transient filter with add_filter but call remove_filter only at the end,
so a failed assertion can leak the callback; fix by making cleanup
exception-safe: either move removal into the test class tear_down() (implement
tear_down() to call remove_filter for the same callback) or wrap each
add_filter/remove_filter pair in a try/finally so remove_filter always runs;
reference the existing callback closures and the add_filter/remove_filter calls
to ensure the exact same callback and priority (10) are removed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/WP_Ultimo/Functions/Assets_Functions_Test.php`:
- Around line 139-172: The tests test_wu_is_wu_page_filter_opt_in and
test_wu_is_wu_page_filter_opt_out add a transient filter with add_filter but
call remove_filter only at the end, so a failed assertion can leak the callback;
fix by making cleanup exception-safe: either move removal into the test class
tear_down() (implement tear_down() to call remove_filter for the same callback)
or wrap each add_filter/remove_filter pair in a try/finally so remove_filter
always runs; reference the existing callback closures and the
add_filter/remove_filter calls to ensure the exact same callback and priority
(10) are removed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dfffc000-59b3-4fd7-8092-fdc3d72afa3e

📥 Commits

Reviewing files that changed from the base of the PR and between e0e89ae and 873abc0.

📒 Files selected for processing (3)
  • inc/functions/assets.php
  • tests/WP_Ultimo/Functions/Assets_Functions_Test.php
  • tests/WP_Ultimo/Scripts_Test.php

@github-actions
Copy link
Copy Markdown

🔨 Build Complete - Ready for Testing!

📦 Download Build Artifact (Recommended)

Download the zip build, upload to WordPress and test:

🌐 Test in WordPress Playground (Very Experimental)

Click the link below to instantly test this PR in your browser - no installation needed!
Playground support for multisite is very limitied, hopefully it will get better in the future.

🚀 Launch in Playground

Login credentials: admin / password

@github-actions
Copy link
Copy Markdown

Performance Test Results

Performance test results for 7ba9e58 are in 🛎️!

Note: the numbers in parentheses show the difference to the previous (baseline) test run. Differences below 2% or 0.5 in absolute values are not shown.

URL: /

Run DB Queries Memory Before Template Template WP Total LCP TTFB LCP - TTFB
0 41 37.83 MB 862.00 ms 178.00 ms (+13.50 ms / +8% ) 1025.00 ms (-34.50 ms / -3% ) 2046.00 ms 1940.10 ms 85.95 ms (-5.60 ms / -7% )
1 56 49.03 MB 919.00 ms 140.00 ms 1066.50 ms 2036.00 ms 1954.65 ms 81.20 ms

@superdav42 superdav42 merged commit 458bc0c into main Apr 16, 2026
11 checks passed
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