Hooks
Every default, limit and message has a filter, and every change fires an action.
axle_category_tag_trash_supports_taxonomyFilter( bool $keep, string $taxonomy )Return false to delete a taxonomy’s terms for good, as WordPress normally does. Menus (nav_menu) are never kept
axle_category_tag_trash_keep_termFilter( bool $keep, WP_Term $term )Whether one deleted term goes to the trash, for example to let empty tags go for good
axle_category_tag_trash_retention_daysFilter( int $days )Days a trashed term is kept. Wins over the setting on the screen
axle_category_tag_trash_retention_choicesFilter( int[] $days )Periods offered on the screen. Default 7, 30, 90 and 365
axle_category_tag_trash_undo_secondsFilter( int $seconds )How long the Undo notice after a bulk delete stays. Default 300
axle_category_tag_trash_trashedAction( int $item_id, Snapshot $snapshot )A deleted term landed in the trash
axle_category_tag_trash_deletedAction( int $item_id, Snapshot $snapshot )A trashed term is about to be deleted for good: Empty trash, Delete permanently or the daily clean-up. Not on restore
axle_category_tag_trash_purgedAction( int $deleted )The daily clean-up deleted this many expired terms
axle_category_tag_trash_restoredAction( int $term_id, string $taxonomy, Snapshot $snapshot, int[] $object_ids )Fires once the term is back. $object_ids holds the objects re-attached in that request, at most 5,000
axle_category_tag_trash_objects_restoredAction( int $term_id, string $taxonomy, int[] $object_ids )Fires for every batch of objects re-attached, in the request and in the background
axle_category_tag_trash_restore_completeAction( int $term_id, string $taxonomy, Snapshot $snapshot )Fires once every object is back
axle_category_tag_trash_restore_batch_sizeFilter( int $size )Objects re-attached per request or cron run. Default 5000
axle_category_tag_trash_capabilityFilter( string $capability )Capability for Tools > Axle Category & Tag Trash. Default manage_categories. Each restore and delete still checks the term’s own taxonomy
No hook matches that. Try a shorter word.
WP-CLI
wp axle-category-tag-trash list [--taxonomy=<taxonomy>] [--format=table|csv|json|count|ids]
wp axle-category-tag-trash restore <id>...
wp axle-category-tag-trash delete <id>...
wp axle-category-tag-trash delete --all [--yes]Abilities
What AI agents can do through the WordPress Abilities API and MCP, with the same permissions as the screen.
axle-category-tag-trash/listRead-only. Trashed terms, newest first, with what a restore brings back. Input: taxonomy, search, limit, page
Who can run it: the Axle Category & Tag Trash capability. Terms of taxonomies you cannot manage are left out
axle-category-tag-trash/restoreRestores trash item id with its posts, child terms and menu links
Who can run it: the Axle Category & Tag Trash capability and the term’s own taxonomy
axle-category-tag-trash/deleteDeletes trash item id for good. Destructive, so the REST API runs it with DELETE
Who can run it: the Axle Category & Tag Trash capability and the term’s own taxonomy
Built from REFERENCE.md for version 3.0.0.
More on hooks
// Never keep deleted tags.
add_filter( 'axle_category_tag_trash_supports_taxonomy', function ( $keep, $taxonomy ) {
return 'post_tag' === $taxonomy ? false : $keep;
}, 10, 2 );
// Let empty categories go for good, keep the rest.
add_filter( 'axle_category_tag_trash_keep_term', fn( $keep, $term ) => $keep && $term->count > 0, 10, 2 );
// Offer a 14-day option.
add_filter( 'axle_category_tag_trash_retention_choices', fn( $days ) => array_merge( $days, array( 14 ) ) );
More on abilities
On WordPress 6.9 and later, Axle Category & Tag Trash registers abilities, which AI agents find and run through the MCP adapter and anything else through the REST API under /wp-abilities/v1/. Each one is marked public, which the MCP adapter needs before it lists an ability. An agent that deleted the wrong category can put it back.
More on WP-CLI
<id> is the trash item ID from wp axle-category-tag-trash list, not the term ID. restore re-attaches every object in the same run, even for a term on a million posts, and also finishes a restore that is running in the background.
PHP API
$plugin = AryanX\Axle\CategoryTagTrash\Plugin::instance();
$plugin->trash()->find( array( 'taxonomy' => 'category', 'per_page' => 100 ) ); // [ 'ids' => [...], 'total' => n ], at most 500 per page
$plugin->restorer()->restore( $item_id ); // [ 'term_id' => n, 'notes' => [...], 'background' => bool ] or WP_Error
$plugin->restorer()->restore( $item_id, true ); // the same, with every object re-attached before it returns
Data
Each trashed term is an axle_ctt_item post (hidden, not exported, kept when its author is deleted). Its post meta holds:
| Meta key | What |
|---|---|
_axle_category_tag_trash_snapshot | the term row, meta, children, menu links, object count and a sample of object IDs |
_axle_category_tag_trash_objects | one row per 1,000 objects, packed as id:order,id:order |
_axle_category_tag_trash_fallback | one row per 1,000 objects that only had this term, packed as id,id |
_axle_category_tag_trash_restore_state | where a background restore is up to |
Items in the trash have the status publish, items being restored in the background pending. The setting is the axle_category_tag_trash_settings option. The cron events are axle_category_tag_trash_purge (daily), axle_category_tag_trash_empty and axle_category_tag_trash_restore_batch.
Uninstalling removes all of it on every site of a multisite network, 100 sites at a time.