外掛說明
- 不使用
switch_to_blog()函式。也就是說,Super Admin All Sites Menu 會比 WordPress 工具列的 [我的網站] 選單更快且使用更少資源。 - 子網站選單會儲存在伺服器本機的 IndexedDB (我說過它很快) 中,伺服器本機儲存區會因為以下狀況而更新:
- 啟用外掛。
- 新增或刪除網站。
- 變更網站名稱。
- IndexedDB 與網站變更不同步。
- 啟用或停用 Restricted Site Access 外掛。
- 更新子網站選單資料後,使用 AJAX 並以增量方式處理 (每次增量處理 100 個網站)。
- 列出全部子網站。WordPress 工具列上的 [我的網站] 僅會列出具備子網站網站管理員權限的網站。
- 使用 Restricted Site Access 外掛限制存取的網站會以紅色圖示標示。
- 依據字母順序排列網站選單。
- 搜尋篩選條件。
- 新增更多選單項目
- 在 [多站網路管理中心]…
- 新增網站
- 在每個網站…
- 新增頁面
- 使用者
- 外掛
- 設定
- 在 [多站網路管理中心]…
必要條件
- WordPress 多站網路
- 新式瀏覽器 (不支援 IE11)
功能示範
這個外掛已在 WordPress Playground 上提供功能示範。由於會載入 50 個子網站,所以載入速度稍慢。
-
如果在主要網站的 [外掛] 選單中停用 Super Admin All Sites Menu,便會發現 WordPress 工具列的 [我的網站] 選單無法捲動且無法查看全部網站,這是已經存在長達 14 年的 WordPress 核心程式的程式碼錯誤。
-
如果啟用 Restricted Site Access 外掛,便會看到網站名稱旁顯示紅色圖示。目前由於 WordPress Playground 的問題,Restricted Site Access 的紅色圖示僅能在主要網站上顯示。
篩選器
網站管理員可以使用以下篩選器覆寫預設值:
-
all_sites_menu_order_by-
選單排序方式預設值為
name,接受id、url或name。add_filter( 'all_sites_menu_order_by', function( string $order_by ) : string { return 'url'; } );
-
-
all_sites_menu_load_increments-
AJAX 載入增量。預設值為 100。
add_filter( 'all_sites_menu_load_increments', function( int $increments ) : int { return 300; } );
-
-
all_sites_menu_plugin_trigger-
外掛啟用或停用後,觸發伺服器本機儲存區 (IndexedDB) 更新。預設值為
[ 'restricted-site-access/restricted_site_access.php' ]。注意事項:值必須為陣列,且在陣列中的每個元素都必須指向外掛主要檔案。語法為
'外掛資料夾/外掛主要檔案.php'。add_filter( 'all_sites_menu_plugin_trigger', function( array $plugins ) : array { return [ 'restricted-site-access/restricted_site_access.php', 'myplugin/myplugin.php', ]; } );
-
-
all_sites_menu_search_threshold-
如果值小於 N (代表子網站數量) ,則不顯示搜尋欄位。預設值為 20。
add_filter( 'all_sites_menu_search_threshold', function( int $increments ) : int { return 40; } );
-
-
all_sites_menu_search_threshold-
如果值小於 N (代表子網站數量) ,則不顯示搜尋欄位。預設值為 20。
add_filter( 'all_sites_menu_search_threshold', function( int $increments ) : int { return 40; } );
-
-
all_sites_menu_force_refresh_expiration-
設定強制重新整理時間間隔,單位為秒。預設值為
3600,設定為0代表停用強制重新整理。add_filter( 'all_sites_menu_force_refresh_expiration', function( int $seconds ) : int { return 3600; } );
-
-
all_sites_menu_submenu_items-
自訂個別網站子選單項目 (新增、移除或重新排序)。項目自訂方式:
['id' => string, 'title' => string, 'href' => string]。接收$items、$blog_id、$admin_url及$site_url。// Add an "Edit Site" link pointing to the network admin site-info page. add_filter( 'all_sites_menu_submenu_items', function( array $items, int $blog_id, string $admin_url ) : array { $items[] = [ 'id' => 'edit-site', 'title' => 'Edit Site', 'href' => network_admin_url( 'site-info.php?id=' . $blog_id ), ]; return $items; }, 10, 3 );
-
外掛的開發工作位置
- 這個外掛的開發工作都在 GitHub 存放庫上進行。
使用者評論
這個外掛目前沒有任何使用者評論。
參與者及開發者
變更記錄
1.12.1
- Fixed: Menu sometimes not loading after a REST API error — partial data is cleared and the next page load retries automatically
- Fixed: Nonce middleware stacking on every REST batch request, causing slowdowns on large networks
- Fixed: Infinite REST requests when API returns empty data — loading now terminates correctly
- Fixed: Infinite loop when
loadincrementsis falsy/0 — defaults to 100 - Fixed:
refreshAdminbar()duplicating event listeners on repeated calls, causing erratic hover/toggle - Changed: Converted recursive REST loader to iterative loop to prevent stack overflow on large networks
- Added: Test coverage for REST loading edge cases and refresh idempotency
1.12.0
- Added: Menu colors now follow the user’s Administration Color Scheme
- Added: Hover/focus on menu items uses the scheme’s highlight background, matching the admin sidebar
1.11.1
- Fixed search box styling inconsistency between admin and front-end pages
- Fixed
action_enqueue_scriptsparameter type error on front-end - Updated dependencies: @wordpress/api-fetch, @wordpress/i18n (56), @wordpress/scripts, dexie
- Security: Resolved all npm audit vulnerabilities
1.11.0
- Performance: Replaced per-site WP_Site::get_details() calls with a single batch SQL query, eliminating hidden switch_to_blog() overhead in the REST endpoint
1.10.1
- Updated: @wordpress/scripts 30.7.0 31.6.0
- Updated: dexie 4.0.11 4.2.0
- Security: Resolved Dependabot alerts #102, #104, #108, #109 (minimatch ReDoS, serialize-javascript RCE, @tootallnate/once)
- Changed: Added npm overrides for transitive dependency vulnerabilities (0 audit findings)
1.10.0
- Added: Filterable per-site submenu items via
all_sites_menu_submenu_itemsfilter (#46) - Added: Numeric
blog_idfield in REST response for use in filters and custom JS (#46) - Added: Search by URL — the search filter now matches site URLs in addition to site names (#45)
- Added: Updated search placeholder to “Search by name or URL”
- Fixed: Sort by ID now uses numeric
blog_idindex for correct order instead of lexicographic string sort (#47) - Fixed: Admin bar item IDs now use correct
blog-Nstring instead of0(#46) - Fixed: Search URL indexing decoupled from submenu order via
data-urlattribute (#46)
1.9.0
- Fixed: PHP copy-paste bug in set_properties() — cache expiration validation checked wrong variable
- Fixed: Removed dead REST guard in init() that could never match
- Fixed: Removed redundant header() in REST callback
- Fixed: toggleClass ReferenceError in refresh.js — Tab key navigation into submenus was broken
- Fixed: IntersectionObserver race condition that could duplicate menu HTML
- Fixed: Added partial-load recovery — failed REST fetches now clear IndexedDB so next load retries
- Security: Added URL sanitisation and attribute escaping in menu template to prevent XSS
- Changed: Rewrote refresh.js — removed dead code, modernised to classList API
- Changed: Moved build-only packages from dependencies to devDependencies
- Changed: Updated all npm packages to latest compatible versions
- Tested up to WordPress 7.0
1.8.4
- Update dependencies
1.8.3
- Housekeeping
1.8.2
- Abort early if the user does not have the required permissions
- Security: Added endpoint verification for REST API requests
- Bug fix: Added rest endpoint permission check
- Code improvement: Added strict types declaration
- Code improvement: Added return type declarations
1.8.1
- Remove duplicate code
1.8.0
REQUIRE PHP 8.0 OR HIGHER
- Code modernization: Refactored to use PHP 8.0+ features
- Enhancement: Improved type safety and error handling
- Performance: Better code organization with Config class
- Enhancement: Increased default search threshold to 20 sites
1.7.3
- Fixed search functionality:
- Improved search performance with better indexing
- Added mutation observer to handle dynamically loaded sites
- Fixed event handling for search input
- Added improved error handling for search elements
- Better handling of empty search inputs
1.7.2
- Bump version to trigger a deploy to WordPress.org
1.7.1
- Bump version to trigger a deploy to WordPress.org
1.7.0
- Major code refactoring and improvements:
- Added comprehensive JSDoc documentation
- Improved error handling throughout the codebase
- Enhanced IndexedDB implementation with private class fields
- Added debouncing to search functionality
- Improved intersection observer implementations
- Better type checking and null safety
- Modernized class structure and module organization
1.6.9
- Update dependencies
1.6.8
- Update dependencies
1.6.7
- Update dependencies
1.6.6
- Tested with WordPress 6.4
1.6.5
- Tested with WordPress 6.3
1.6.4
- Fix bug in handling the REST API.
1.6.2
- Tested with WordPress 6.0
1.6.1
- Await for the promise
populateDB()to resolve before continuing.
1.6.0
- Use
@wordpress/api-fetchto fetch subsite data.
1.5.0
- Use REST instead of AJAX.
1.4.28
- Housekeeping
1.4.27
- Add missing textdomain to translations.
- Update uninstall.php
1.4.26
- Bundle Dexie using wp-scripts
1.4.25
- Housekeeping
1.4.24
- Use @wordpress/i18n to translate JavaScript.
1.4.23
- Fix typo in textdomain.
1.4.22
- Housekeeping
1.4.21
- Update translation file (.pot)
1.4.20
- Don’t set dependencies for style.
1.4.19
- Import @wordpress/i18n
1.4.18
- Replace build script from webpack to wp-scripts (@wordpress/scripts)
1.4.17
- Use correct AJAX URL
1.4.16
- Upgrade Dexie.js to v 3.2.0
1.4.15
- Only load the plugin code if the admin bar is available.
1.4.14
- Force refresh using a site transient.
1.4.13
- Don’t list sites that are tagged as archived, deleted, mature or spam.
1.4.12
- Update plugin banner
1.4.11
- Add plugin banner
1.4.10
- Housekeeping
1.4.9
- Deploy to https://wordpress.org/plugins/super-admin-all-sites-menu/
1.4.8
- Remove external dependencies.
1.4.7
- Remove
type=modulefrom script tag. Not needed anymore since the script and modules are packed.
1.4.6
- Pack JavaScript using webpack.
1.4.5
- Only run if multisite.
- Improved Dexie versioning.
1.4.4
- Pass only one parameter to
plugin_update_local_storage() - Close db connection when getting version number.
1.4.3
- IndexedDB maintenance, i.e. remove old databases.
1.4.2
- Dexie schema change, bump Dexie version number.
1.4.1
- Make sure the local storage (IndexedDB) is in sync with server changes.
1.4.0
- Refactored JavaScript again, I’m using this plugin to experiment with and to learn JavaScript better.
1.3.8
- Refactor and rename db module.
1.3.7
- Don’t display search field if there’s less than 20 subsites. The threshold is adjustable using the
all_sites_menu_search_thresholdfilter
1.3.6
- Fix load increments bug.
1.3.5
- Housekeeping.
1.3.4
- Add filters to defaults.
1.3.3
- Update IndexedDB when you change a blog name.
1.3.2
- Only change
text/javscripttomodulewhen tag hassrcattribute
1.3.0
- Refactor
- Split JavaScript into modules
- If empty, populate IndexedDB with sites menu data.
1.2.4
- Adjust the sites menu wrapper height
1.2.3
- Remove
window.hoverintent, it’s slow when you have a lot of sites, useaddEventListenerin capturing mode instead.
1.2.2
- Housekeeping.
1.2.1
- Update IndexedDB when Restricted Site Access is (de)activated.
1.2.0
- Store subsite menu data in IndexedDB (local storage).
- IndexedDB is updated when a site is added / deleted.
- Add search.
1.1.2
- Fix translations.
1.1.1
- Housekeeping.
1.1.0
- Lazy load the subsite menu, using IntersectionObserver and AJAX, loading only 80 subsites at a time.
- Make subsites menu scrollable.
1.0.x
- Initial release.


