WordPress Admin URL Building
SkillDev toolsPatterns for building WordPress admin page URLs in Simple History. Use when constructing admin links, settings tabs, or menu URLs dynamically.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the WordPress Admin URL Building skill
What this skill tells your AI
The instructions your AI receives, as published by bonny/wordpress-simple-history in .claude/skills/wp-admin-urls/SKILL.md and read by ahel’s review.
Simple History's admin pages can live in different locations depending on user settings (top-level, inside Tools, inside Dashboard). Never hardcode admin URLs. Always use the helper methods.
Key Helpers
All in inc/class-helpers.php:
| Method | Returns | Example |
|---|---|---|
Helpers::get_history_admin_url() | Main history page URL (no filters) | admin.php?page=simple_history_admin_menu_page |
Helpers::get_filtered_history_url($args) | History URL with filters applied | See "Building Filtered URLs" below |
Helpers::get_settings_page_url() | Settings page URL | admin.php?page=simple_history_settings_page |
Helpers::get_settings_page_tab_url($tab) | Settings tab URL | ...&selected-tab=general_settings_subtab_general |
Helpers::get_settings_page_sub_tab_url($sub_tab) | Settings sub-tab URL | ...&selected-tab=...&selected-sub-tab=... |
Why URLs Are Dynamic
The base admin URL changes with menu location:
| Location setting | History base | Settings base |
|---|---|---|
top / bottom | admin.php?page=... | admin.php?page=... |
inside_tools | tools.php?page=... | options-general.php?page=... |
inside_dashboard | index.php?page=... | options-general.php?page=... |
Menu Page Slugs
Defined as constants in inc/class-simple-history.php:
Simple_History::MENU_PAGE_SLUG- Main history pageSimple_History::SETTINGS_MENU_PAGE_SLUG- Settings page
Settings Tab URL Structure
Settings uses a tab/sub-tab system with query parameters:
?page=simple_history_settings_page
&selected-tab=general_settings_subtab_general ← main tab
&selected-sub-tab=general_settings_subtab_alerts ← sub-tab
Build these with Helpers::get_settings_page_sub_tab_url('slug') — never manually.
Common Tab Slugs
Look up tab slugs in the module or service that registers them:
- Alerts (free teaser):
Alerts_Settings_Page_Teaser::MENU_SLUG(general_settings_subtab_alerts) - Alerts (premium):
Alerts_Module::ALERTS_TAB_SLUG(same value, premium add-on only) - General settings:
Setup_Settings_Page::SETTINGS_GENERAL_SUBTAB_SLUG - Check module/service classes for their
*_TAB_SLUGorMENU_SLUGconstants
History Page Filter Parameters
The main history page accepts URL query parameters that pre-fill filters:
| Parameter | Format | Example |
|---|---|---|
date | lastdays:N, allDates, month:YYYY-MM, customRange | date=allDates |
context | key:value (one per line) | context=post_id:123 |
show-filters | 1 to expand filter panel | show-filters=1 |
messages | JSON array (URL-encoded) | See below |
users | JSON array of user objects | [{"id":"1","value":"Jane (jane@example.com)"}] |
Building the messages Parameter
The messages param is a JSON array of objects, each with value (display label) and search_options (array of LoggerSlug:message_key strings):
$messages_json = wp_json_encode( array(
array(
'value' => 'All posts & pages activity',
'search_options' => array(
'SimplePostLogger:post_created',
'SimplePostLogger:post_updated',
'SimplePostLogger:post_trashed',
),
),
) );
Building Filtered URLs
Always use Helpers::get_filtered_history_url() — it handles the JSON encoding gotcha internally:
// General-purpose filtered URL.
$url = Helpers::get_filtered_history_url( array(
'date' => 'allDates',
'context' => 'post_id:123',
'show_filters' => true,
'messages' => array(
array(
'value' => 'All posts & pages activity',
'search_options' => array(
'SimplePostLogger:post_created',
'SimplePostLogger:post_updated',
),
),
),
) );
// Shortcut for post-specific history (used by row actions and History column).
$url = Post_History_Column::get_post_history_url( $post_id );
Never pass messages via add_query_arg() — it double-encodes JSON. The shared helper handles this correctly with rawurlencode().
Finding Logger Slugs and Message Keys
Each logger has a $slug property and messages array in get_info(). The search_options format is LoggerSlug:message_key. Check the logger class to find available keys:
grep -n "slug\|messages" loggers/class-post-logger.php | head -20
Anti-Patterns
// WRONG: Hardcoded URL breaks when menu location changes.
$url = admin_url('admin.php?page=simple_history_settings_page&selected-sub-tab=alerts');
// WRONG: Building URL manually in JavaScript.
const url = `${adminUrl}admin.php?page=simple_history_settings_page...`;
// RIGHT: Use helper in PHP, pass to JS if needed.
$url = Helpers::get_settings_page_sub_tab_url( Alerts_Settings_Page_Teaser::MENU_SLUG );
Passing URLs to JavaScript
When JS components need admin URLs, generate them in PHP and pass them via:
wp_localize_script— for URLs needed immediately on page loadsimple_history/search_options_datafilter — for URLs consumed by React components via the search-options REST API
See the php-to-react-data skill for details on choosing between these approaches.
Signals
- GitHub stars
- 317
- Forks
- 74
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
wp-admin-urls- Source
- github.com/bonny/wordpress-simple-history