Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Right now my shortlink structure looks something like this:

example.com/?p=451

I would prefer it to look more like this:

example.com/abc123

Any ideas how I can alter the code to do just this?

share|improve this question
    
Do you mean edit the core file itself? If so, that's probably not a good idea as it makes upgrading harder. A plugin would be the way to go. –  chrisguitarguy Aug 29 '11 at 18:34
    
@Christopher Davis This is true...Ahhh I was trying to avoid a plugin as many seem to slow down my sites. –  Matt Aug 29 '11 at 21:07
2  
Plugins don't slow down sites. Overly complex plugins that try to do too much slow down sites. I run upwards of 50 plugins and have no issues. Just something to keep in mind: simple is better. –  Otto Aug 29 '11 at 22:14

2 Answers 2

up vote 2 down vote accepted

Okay, so, as mentioned in my comment to you: altering core files is not a good idea. But here is a plugin solution.

First we're going to create our own rewrite rules that rewrite s/123 (replace 123 with a post ID) to index.php?short=123. We'll also have to filter the WordPress query variables so we can use them later.

<?php
add_action( 'init', 'wpse26869_add_rewrites' );
function wpse26869_add_rewrites()
{
    add_rewrite_rule( '^s/(\d+)$', 'index.php?short=$matches[1]', 'top' );
}

add_filter( 'query_vars', 'wpse26869_query_vars', 10, 1 );
function wpse26869_query_vars( $vars )
{
    $vars[] = 'short';
    return $vars;
}

The add_rewrite_rule call says "rewite s followed by a slash and a string of one or more digits to index.php?short=the_string_of_digits.

Then we can hook into template redirect and see if our query variable is there. If it is, we'll try and get a permalink out of it. If that fails, we'll throw a 404 error. Otherwise, we'll use `wp_redirect' to send folks to the actual post.

<?php
add_action( 'template_redirect', 'wpse26869_shortlink_redirect' );
function wpse26869_shortlink_redirect()
{
    // bail if this isn't a short link
    if( ! get_query_var( 'short' ) ) return;
    global $wp_query;

    $id = absint( get_query_var( 'short' ) );
    if( ! $id )
    {
        $wp_query->is_404 = true;
        return;
    }

    $link = get_permalink( $id );
    if( ! $link )
    {
        $wp_query->is_404 = true;
        return;
    }

    wp_redirect( esc_url( $link ), 301 );
    exit();
}

Finally, we hook into get_shortlink to change how our rel="shortlink" appears in the <head> section of the site, and elsewhere. This new shortlink structure will reflect the rewrite rule we wrote above.

<?php
add_filter( 'get_shortlink', 'wpse26869_get_shortlink', 10, 3 );
function wpse26869_get_shortlink( $link, $id, $context )
{
    if( 'query' == $context && is_single() )
    {
        $id = get_queried_object_id();
    }
    return home_url( 's/' . $id );
}

As a plugin: https://gist.github.com/1179555

share|improve this answer
    
you're the man. Thank you. –  Matt Aug 31 '11 at 20:07
    
I'm actually having a little bit of trouble with this plugin. Right now my ShortUrl (without any plugin or modification to WordPress) looks like this structure: example.com/?p=451 How can I get it to look like this: example.com/short451 (I guess 451 is the post id?) –  Matt Sep 2 '11 at 13:37
    
You need to change your permalink settings to pretty permalinks. settings > permalinks –  chrisguitarguy Sep 2 '11 at 14:00
    
do I need to somehow activate this option? I don't see it in settings > permalinks –  Matt Sep 2 '11 at 15:46
1  
One redirect happens. example.com/s/121 is rewritten, not redirected. The function hooked into template_redirect actually does the redirect from short URL to the canonical permalink. –  chrisguitarguy Jul 2 '12 at 4:56

Aside from @ChristopherDavis's answer, you can also do it in a PHP independent way, using .htaccess. Simply add this rule:

RewriteEngine On
RewriteRule ^s/(\d+)$ index.php?p=$1 [L]

Alternative without mod_rewrite, using mod_alias:

RedirectMatch Permanent ^/s/(\d+)$ /?p=$1

The only problem is, two redirects happen here (instead of 1) — (for example) if user visits http://example.com/s/121/ he is redirected by the web server to http://example.com/index.php?p=121/ and then by WordPress to the actual permalink of the post.

The advantage is, this never breaks! Plugins may break, but this does not.

PS: I use this (short link structure would be http://example.com/-121 where 121 is post ID):

RewriteEngine On
RewriteRule ^-(\d+)$ index.php?p=$1 [L]
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.