Rewrite permalink with PHP processing

Based on your example there are 4 fundamental steps to take. I’ve tried to use examples below, and they may not work as is, but they demonstrate the fundamental principles needed:

1. Add a query var shorty

This whitelists shorty and gives the 2c from /shorty/2c somewhere to be stored

function shorty_query_vars( array $qvars ) : array {
    $qvars[] = 'shorty';
    return $qvars;
add_filter( 'query_vars', 'shorty_query_vars' );

2. Add a rewrite rule that maps to the shorty query var for /shorty

This takes the URL and uses a regular expression to map it to an ugly permalink, using the query var we just added.

add_action( 'init',  function() {
    add_rewrite_rule( 'shorty/([a-z0-9-]+)[/]?$', 'index.php?shorty=$matches[1]&p=0', 'top' );
} );

3. Use pre_get_posts to process it and rewrite p

This checks if the query var we just added has a value, aka when the rewrite rule is used, and modifies the main query to pull in the post we want. This is where base_convert is called. The main query is what determines the template, and the posts that WP fetches, so this part is where the most modification will be needed:

function process_shorty_if_set( \WP_Query $query ) : void {
    // don't run on admin, and only on the main query
    if ( is_admin() || ! $query->is_main_query() ) {

    // return early if shorty isn't set
    if ( empty( $query->get( 'shorty' ) ) ) {
    $shorty = $query->get( 'shorty' );
    $post_id = base_convert( $shorty, 36, 10 );
    $query->set( 'p', $post_id );
add_action( 'pre_get_posts', 'process_shorty_if_set' );

4. Save Permalinks and Test

After you flush permalinks, by visiting the permalink settings page, test this out by visiting /shorty/2s, and it should load post 100 if it exists.

More specifically WP will see that 2s does not match the canonical URL and do a redirect to the canonical permalink for SEO purposes.

You may want to install a rewrite rule testing plugin to verify the rule added in step 2 is working and not overridden by another rule with a higher priority ( this can happen if your rule is super generic ). If your rule works but the wrong post or no posts are found when they should be, then the pre_get_posts filter will need modifying.