Skip to content

Hooks & Filters

Hooks split into two namespaces:

  • wp-wireframe/… — package-level. Shared across every plugin using the framework. Use these to extend the framework itself (registering field types, mutating access decisions globally).
  • {prefix}/… — per-plugin. Each consuming plugin’s prefix scopes its own hooks. Handlers wire to one plugin’s events without affecting the others.
HookTypePurpose
wp-wireframe/field_typesfilterAdd or replace registered field type classes.
wp-wireframe/config/for_userfilterMutate the config after access filtering, before localize.
wp-wireframe/access/resolvefilterOverride yes/no for a single (verb, level, id, user) check.
wp-wireframe/access/can_resetfilterOverride whether a user may reset on a given page.
wp-wireframe/save/editable_fieldsfilterFinal list of writable field IDs for a save request.
wp-wireframe/save/payloadfilterTransform the sanitised payload before merge.
wp-wireframe/suppress_admin_noticesfilterReturn false to keep third-party admin notices on Wireframe pages.
// Register a custom field type.
add_filter('wp-wireframe/field_types', function (array $types): array {
$types['my_custom'] = MyCustomField::class;
return $types;
});
// Mutate the config after access filtering, before localize.
add_filter('wp-wireframe/config/for_user',
function (array $config, string $pageId, ConfigAccessMap $map): array {
return $config;
},
10, 3
);
// Override a single access decision.
add_filter('wp-wireframe/access/resolve',
function (bool $allowed, array $ctx): bool {
// $ctx: ['verb' => 'view'|'edit', 'level' => 'tab'|'section'|'field', 'id' => string, 'user' => WP_User, ...]
return $allowed;
},
10, 2
);
// Reset eligibility.
add_filter('wp-wireframe/access/can_reset',
function (bool $can, WP_User $user, array $viewable, array $editable): bool {
return $can;
},
10, 4
);
// Editable field list for a save.
add_filter('wp-wireframe/save/editable_fields',
function (array $ids, string $pageId, ConfigAccessMap $map): array {
return $ids;
},
10, 3
);
// Transform payload before merge.
add_filter('wp-wireframe/save/payload',
function (array $values, string $pageId, array $payload): array {
return $values;
},
10, 3
);
// Third-party admin notices are hidden on Wireframe pages by default.
add_filter('wp-wireframe/suppress_admin_notices',
function (bool $suppress, WP_Screen $screen): bool {
return $suppress;
},
10, 2
);

Fire under the consuming plugin’s prefix:

HookTypePurpose
{prefix}/settings_savedactionAfter a successful save. Args: $values, $pageId.
{prefix}/settings_resetactionAfter a successful reset. Args: $pageId.
{prefix}/can_savefilterWhether Save shows and the save endpoint accepts writes. Args: $canSave, $pageId, $map. See Save & Reset.
{prefix}/can_resetfilterWhether Reset shows and the reset endpoint is allowed. Args: $canReset, $pageId, $map.
add_action('my-plugin/settings_saved', function (array $values, string $pageId) {
wp_cache_delete('my-plugin-config', 'options');
}, 10, 2);

The action field type dispatches each button press through a per-button filter. Default value is the private Unhandled sentinel; a 404 wireframe_action_unhandled is returned if no listener attaches.

HookTypePurpose
{prefix}/action/{pageId}/{fieldId}/{actionId}filterHandle a button press. Args: $default, $values, $request.

| {prefix}/header_action/{pageId}/{actionId} | filter | Handle a header action press. Same args. |

In sugar mode (no args.buttons[]), the {actionId} is the literal string run.

See Action Field for the full handler contract.

The table field type uses hooks-first dispatch with legacy callback fallback. If a filter has no listener, the controller falls back to the corresponding args.*_callback keys (data_callback, actions[].callback, detail_view.fetch_callback, etc.).

HookTypeArgs
{prefix}/table/{pageId}/{fieldId}/datafilter$default, $query → ['items', 'total']
{prefix}/table/{pageId}/{fieldId}/{actionId}filter$default, $ids, $request
{prefix}/table/{pageId}/{fieldId}/detail/fetchfilter$default, $entryId, $request
{prefix}/table/{pageId}/{fieldId}/detail/renderfilter$default, $entry, $request
{prefix}/table/{pageId}/{fieldId}/detail/titlefilter$default, $entry, $request (optional)