A WordPress plugin that allows editors to use the core navigation block to create tab-based navigation with rewrite endpoints for conditional block visibility.
-
Tab Navigation Variations: Extends the core
navigation-linkblock with three variations:- Home Tab: Links to the current page without any endpoint
- Base Tab: Links to just the endpoint without a value (e.g.,
/tab/) - Tab: Links with a rewrite endpoint and value (e.g.,
/tab/settings/)
-
Rewrite Endpoints: Registers filterable rewrite endpoints (default:
tab) withEP_ALLmask -
URL Rewriting: Automatically rewrites navigation link URLs to use the current page with the appropriate endpoint
-
Dynamic Tab Visibility Controls: Adds a "Tab Visibility" panel to all blocks (except navigation-link) that automatically appears when the page contains tab navigation (no refresh needed), with options to:
- Always show the block
- Show only when no endpoint is active
- Show only when the endpoint is in use but has no value (e.g.,
/tab) - Show only for a specific tab value (e.g.,
/tab/settings)
-
Active State: Automatically adds
hm-url-tab-activeclass to the current tab link
- Clone this repository into your
wp-content/pluginsdirectory - Run
npm installto install dependencies - Run
npm run buildto build the assets - Activate the plugin through the WordPress admin
- Add a Navigation block to your page
- Insert a navigation link and select one of the tab variations:
- Home Tab: Links to the page without any endpoint
- Base Tab: Links to just the endpoint (e.g.,
/tab/) - useful for "All" or default views - Tab: Links to a specific tab value (e.g.,
/tab/settings/)
- For regular tabs:
- Set the label (e.g., "Settings")
- Enter the tab slug in the URL field (e.g., "settings")
- The final URL will be automatically built from the current page URL with the endpoint and slug on the frontend
When your page contains tab navigation links:
- Select any block on the page (except navigation links)
- Open the "Tab Visibility" panel in the block sidebar
- Choose the display condition:
- Always show: Block is always visible
- Show when no endpoint is active: Block is only visible on the base page (Home Tab)
- Show when endpoint has no value: Block is visible when accessing
/tab/(Base Tab) - Show for specific tab: Block is only visible for the selected tab value
Create a settings page with tabbed sections:
Page URL: /settings
Navigation:
- Home Tab → /settings
- All Settings Tab (Base Tab) → /settings/tab/
- General Tab → /settings/tab/general/
- Privacy Tab → /settings/tab/privacy/
Blocks:
- Welcome message (Visibility: Show when no endpoint is active)
- All settings list (Visibility: Show when endpoint has no value)
- General settings (Visibility: Show for specific tab → general)
- Privacy settings (Visibility: Show for specific tab → privacy)
You can register additional endpoints using the hm_url_tabs_endpoints filter:
add_filter( 'hm_url_tabs_endpoints', function( $endpoints ) {
$endpoints[] = [
'name' => 'section',
'mask' => EP_ALL,
];
return $endpoints;
} );When multiple endpoints are registered, a selector will appear in the navigation link settings to choose which endpoint to use.
npm start: Start development build with watch modenpm run build: Build production assetsnpm run format: Format codenpm run lint:js: Lint JavaScriptnpm run lint:js:fix: Lint and fix JavaScriptnpm run lint:css: Lint CSSnpm run lint:css:fix: Lint and fix CSS
Use WordPress Playground for local development:
npm run playground:startThis will start a WordPress instance at http://localhost:9400 with the plugin activated.
Run Playwright tests:
npm run test:e2e # Run tests
npm run test:e2e:debug # Run tests in debug mode
npm run test:e2e:watch # Run tests in watch modeFilters the registered tab endpoints.
Parameters:
$endpoints(array): Array of endpoints with 'name' and 'mask' keys.
Example:
add_filter( 'hm_url_tabs_endpoints', function( $endpoints ) {
$endpoints[] = [
'name' => 'custom',
'mask' => EP_PAGES,
];
return $endpoints;
} );Navigation Link (core/navigation-link):
kind(string): Set to "tab-home" for home tab, "tab-base" for base tab, or "tab" for regular tabtabEndpoint(string): The endpoint name to use (default: "tab")url(string): The URL slug for the tab (uses the standard navigation-link URL field, empty for Base Tab)
All Other Blocks:
hmUrlTabVisibility(object):condition(string): "always", "no-endpoint", "endpoint-empty", or "specific-tab"endpoint(string): The endpoint nametabUrl(string): The tab URL slug to match (for "specific-tab" condition)
- Base page:
/settings - Home tab:
/settings - Base tab (endpoint without value):
/settings/tab/ - Tab with value:
/settings/tab/general/
Note: Tab URL slugs are automatically lowercased for consistency (e.g., "Settings" becomes /tab/settings/). All generated URLs include a trailing slash.
GPL-2.0-or-later
Human Made Limited - https://humanmade.com