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?
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?
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
settings > permalinks
Commented
Sep 2, 2011 at 14:00
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.
Commented
Jul 2, 2012 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]
using Redirection plugin, you can add a redirect which achieves this without touching PHP or .htaccess.
prerequisites
add redirect
redirect parameters
this method has the following advantages
notes
thanks to @its_me for the .htaccess method as this gave me the exact regex expressions i needed