---
title: Remove Special Characters Developer Reference
description: Hooks, stored meta and options, the Pro query helper, background process identifiers and redirect logic for developers.
url: "https://wpfactory.com/docs/special-characters-developer-reference/"
updated: "2026-09-27"
category: Developers
---

# Remove Special Characters Developer Reference

This developer reference lists the hooks, stored data and query helpers in [Remove Special Characters From Permalinks (URLs) for WordPress](https://wpfactory.com/item/remove-special-characters-from-permalinks-wordpress-plugin/) (free 1.1.1 and Pro 1.0.8). There is nothing to configure here in the admin; the Pro settings live at **Settings > Special Characters** and the bulk tool at **Tools > Remove Characters**.

## How the save-time cleanup is wired

The free plugin (and the copy bundled inside Pro) hooks `WPFactoryRSCFPCore::insert_post_data()` to the core filter `wp_insert_post_data` at priority 10. The callback returns the data unchanged when the post has no ID, when it is a revision, or when the decoded `post_name` contains only `a-z`, `A-Z`, `0-9`, hyphen, underscore and dot. Otherwise it stores the current permalink path in post meta, then rebuilds `post_name` with `remove_accents()`, a regular expression that deletes everything outside that set, and `sanitize_title_with_dashes()`.

Because the filter runs after WordPress has already made the slug unique, the cleaned slug is not checked for uniqueness again.

## Hooks

| Hook | Type | Version | Description |
| --- | --- | --- | --- |
| `trscfp_init` | Filter | Free (and the free code inside Pro) | Return anything other than `true` to stop the save-time cleanup from initializing. It is applied while the plugin file loads, so add your callback in a must-use plugin. It does not disable Pro's settings, bulk tool or redirects. |
| `trscfp_on_activation` | Action | Free | Fires on the first `admin_init` after the free plugin is activated. The plugin uses it to show its promotional notice. |
| `trscfp_on_deactivation` | Action | Free | Fires when the free plugin is deactivated. |
| `trscfp_remove_button` | Action | Pro | Fired on `admin_init` when the **Remove special characters** form is submitted. Pro attaches `Special_Characters::create_characters_removal_bkg_process()`, which cancels any running queue and queues every matching published post. |

## Stored data

| Key | Where | Description |
| --- | --- | --- |
| `_trscfp_original_post_name` | Post meta | The post's permalink path relative to the home URL, without a trailing slash, recorded just before the slug is cleaned (free and Pro). Overwritten on each cleanup. Pro's Force Redirection matches the 404 request path against this value. |
| `trscfp_general` | Option (Pro) | Array with `redirect` (`on` or `off`, default `off`) and `email` (default: site admin email). |
| `trscfp_on_activation` | Option (free) | Temporary flag set on activation and deleted on the next admin page load. |

## Query helper (Pro)

Pro filters `posts_where`. Any `WP_Query` with the query var `trscfp` set to `post_name` gets an extra condition `post_name REGEXP '[^a-zA-Z0-9-_.]'`, which returns only posts whose slug contains special characters (URL-encoded slugs match because of the `%` sign).

```
$query = new WP_Query( array(
	'post_type'      => 'any',
	'post_status'    => 'publish',
	'posts_per_page' => -1,
	'fields'         => 'ids',
	'trscfp'         => 'post_name',
) );
```

## Background process (Pro)

The bulk tool uses the WP Background Processing library with the action `trscfp_remove`, so its identifier is `wp_trscfp_remove`. The library's standard filters use that prefix, for example `wp_trscfp_remove_default_time_limit` (seconds per batch, default 20) and `wp_trscfp_remove_cron_interval` (health check interval in minutes, default 5). The health check cron event is `wp_trscfp_remove_cron`. When the queue completes, an email is sent to the `email` setting with `wp_mail()`.

## Redirects (Pro)

`WPFactoryRSCFPProRedirect::handle_redirects()` runs on `template_redirect`. It acts only when `is_404()` is true, the `redirect` setting is `on` and the request path is not empty. It then queries published posts of any type whose `_trscfp_original_post_name` equals `$wp->request` and issues `wp_redirect( get_the_permalink(), 301 )` for the first match.

## Examples

### Turn off the save-time cleanup

Place this in a file in `wp-content/mu-plugins/` so it loads before the plugin:

```
add_filter( 'trscfp_init', '__return_false' );
```

### Read a post's original path

```
$old_path = get_post_meta( $post_id, '_trscfp_original_post_name', true );
```

Need a hand? Our team answers every ticket on the [Remove Special Characters support forum](https://wpfactory.com/support/item/remove-special-characters-from-permalinks-wordpress-plugin/).

Related articles

- [Remove Special Characters Settings Reference](https://wpfactory.com/docs/special-characters-settings/)
- [Remove Special Characters Troubleshooting](https://wpfactory.com/docs/special-characters-troubleshooting/)
- [Remove Special Characters: Free vs Pro](https://wpfactory.com/docs/special-characters-free-vs-pro/)
- [How to Remove Special Characters from WordPress URLs](https://wpfactory.com/docs/special-characters-remove-from-urls/)
- [Getting Started with Remove Special Characters From Permalinks](https://wpfactory.com/docs/special-characters-getting-started/)
