• About Us
    • New York
  • Work
  • Capabilities
  • Careers
  • Technology
  • Blog
  • Contact Us
  • About Us
    • New York
  • Work
  • Capabilities
  • Careers
  • Technology
  • Blog
  • Contact Us
September 06, 2011

Custom WordPress Shortlinks

Posted by Christopher Davis

WordPress ships with the ability to create shortlinks for you. Most of the time that means something like http://yoursite.com/?p=123. Or, if you opted in, a wp.me shortlink.

WordPress Shortlink Button

Those are solid options, but what if you want to use your own shortlink service? Or you want short links that are a little bit prettier? Fortunately nearly everything in WordPress has a hook attached to it, meaning it’s very easy to modify that built in shortlink functionality without changing the code.

Making Pretty Shortlinks

?p=123 at the end of a URL is not so pretty. The first half of this tutorial will be learning how you can create a better, cleaner shortlink. This involves using WordPress’s built in Rewrite API.

1. Setting Up a Rewrite

The first thing we’re going to do is add a rewrite rule. add_rewrite_rule takes three arguments: the regular expression that WP will try to match a URL against, the rewrite destination, and the priority.

1
2
3
4
5
add_action(‘init’,‘pmgtut_add_rewrites’);
functionpmgtut_add_rewrites()
{
    add_rewrite_rule(‘^s/(d+)$’,‘index.php?short=$matches[1]’,‘top’);
}

We’re hooking into init here because need to be sure the entire WordPress environment (including our add_rewrite_rule function) is loaded. The add_rewrite_rule says, “whenever someone visits a URL that starts with s, followed by a slash and one or more digits, rewrite that URL to index.php?short=the_digits.

Unfortunately WordPress will see that short query argument on the URL and not recognize it. As such, it will get stripped out. So we need to tell WordPress that short is a valid query argument by hooking into the query_vars filter.

1
2
3
4
5
6
add_filter(‘query_vars’,‘pmgtut_query_vars’,10,1);
functionpmgtut_query_vars($vars)
{
    $vars[]=‘short’;
    return$vars;
}

Aside: Rewriting vs. Redirecting

When a URL is redirected, it changes. When it’s rewritten, it’s done so transparently at the server level without the user knowing: the URL does not change. Rewrites are how the WordPress permalink system works. What we’re doing here is harnessing that system to roll our own rewrites.

2. Dealing With the Rewritten URL

Despite us telling WordPress that short is a valid query argument, it still has no idea what to do. For that, we need to hook into template redirect, a hook that fires right before WordPress chooses which PHP file in your current theme to use.

First, we’ll check to see if short argument is there with get_query_var. If it isn’t, we’ll bail and let WordPress continue doing its thing.

1
2
3
4
5
6
add_action(‘template_redirect’,‘pmgtut_shortlink_redirect’);
functionpmgtut_shortlink_redirect()
{
    // bail if this isn’t a short link
    if(!get_query_var(‘short’))return;
}

Next we’ll try to turn our query argument into an absolute integer, and get a permalink out of it. If either of those fail, we’ll say that this is a 404, error page and return out of our function. The last step is calling wp_redirect to send people on the canonical URL.

$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();
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
add_action(‘template_redirect’,‘pmgtut_shortlink_redirect’);
functionpmgtut_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();
}

That’s it! you now have custom shortlinks, but we’re not done yet.

3. Modifying the Shortlink API

WordPress lets you click on that handy Get Shortlink button to grab your shortlink in the admin section. It also adds the shortlink into the <head> section of your site. We need to modify that output to reflect our new, pretty shortlinks.

The filter in question here is get_shortlink.

1
2
3
4
5
6
7
8
9
add_filter(‘get_shortlink’,‘pmgtut_get_shortlink’,10,3);
functionpmgtut_get_shortlink($link,$id,$context)
{
    if(‘query’==$context&&is_single())
    {
        $id=get_queried_object_id();
    }
    returnhome_url(‘s/’.$id);
}

You can see this entire thing in action as a plugin.

Using An External Source for Shortlinks

If you’re using an external service, you don’t need to worry about steps one and two above. Instead, you’ll need something that interacts with a service’s API, grabs the shortlink and puts it int he correct places.

For this tutorial, we’ll be using dlvr.it as our external shortlink provider.

To start, we’ll keep a good portion of our get_shortlink function above. This will be in a plugin, so we’ll also include PHP class that encapsulates the Dlvr.it API.

PHP
// call in our dlvir API.
require_once( plugin_dir_path( __FILE__ ) . ‘api.php’ );add_filter( ‘get_shortlink’, ‘pmgtut2_get_shortlink’, 10, 3 );
function pmgtut2_get_shortlink( $link, $id, $context )
{
if( ‘query’ == $context && is_singular() )
{
$id = get_queried_object_id();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
// plugin header here
// call in our dlvir API.
require_once(plugin_dir_path(__FILE__).‘api.php’);
add_filter(‘get_shortlink’,‘pmgtut2_get_shortlink’,10,3);
functionpmgtut2_get_shortlink($link,$id,$context)
{
    if(‘query’==$context&&is_singular())
    {
        $id=get_queried_object_id();
    }
}

Now it gets a bit tricky. We don’t necessarily want to hit the API every single time we get the shortlink. Remember the mention above about how WordPress put the shortlink in the <head> section? Hitting the API on the load of every single post page is probably not a good idea: extra HTTP requests, etc. Instead, we’ll store our shortlink as a value in the wp_postmeta table. The first step is seeing if that value is there. If it is, we’ll return the short URL right away.

PHP





if( $dlvrit = get_post_meta( $id, ‘_pmg_dlvrit_url’, true ) )
{
return $dlvrit;
}
1
2
3
4
5
6
7
8
9
10
11
functionpmgtut2_get_shortlink($link,$id,$context)
{
    if(‘query’==$context&&is_singular())
    {
        $id=get_queried_object_id();
    }
    
    if($dlvrit=get_post_meta($id,‘_pmg_dlvrit_url’,true))
    {
        return$dlvrit;
    }

If we dont’ have a stored value, we’ll create a new wpDlvrit object, then get the posts permalink, and fetch the short url.

PHP


if( $dlvrit = get_post_meta( $id, ‘_pmg_dlvrit_url’, true ) )
{
return $dlvrit;
}
else
{
$dlvrit = new wpDlvrit( ‘your_api_key’ );
$long = esc_url( get_permalink( $id ) );
$short = $dlvrit->get_shortlink( $long );// If there’s a problem, return the original link
if( ! $short ) return $link;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
functionpmgtut2_get_shortlink($link,$id,$context)
{
    if(‘query’==$context&&is_singular())
    {
        $id=get_queried_object_id();
    }
    
    if($dlvrit=get_post_meta($id,‘_pmg_dlvrit_url’,true))
    {
        return$dlvrit;
    }
    else
    {
        $dlvrit=newwpDlvrit(‘your_api_key’);
        $long=esc_url(get_permalink($id));
        $short=$dlvrit->get_shortlink($long);
        
        // If there’s a problem, return the original link
        if(!$short)return$link;

Since the API class doesn’t handle json decoding or any of that jazz, we’ll have to take care of that ourselves here. Assuming everything goes according to plan, we’ll update the postmeta table and return the shortlink.

PHP





if( $dlvrit = get_post_meta( $id, ‘_pmg_dlvrit_url’, true ) )
{
return $dlvrit;
}
else
{
$dlvrit = new wpDlvrit( ‘your_api_key’ );
$long = esc_url( get_permalink( $id ) );
$short = $dlvrit->get_shortlink( $long );// If there’s a problem, return the original link
if( ! $short ) return $link;$body = json_decode( $short[‘body’] );

if( ! isset( $body[0]->short ) ) return $link;

update_post_meta( $id, ‘_pmg_dlvrit_url’, esc_url( $body[0]->short ) );
return esc_url( $body[0]->short );
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
functionpmgtut2_get_shortlink($link,$id,$context)
{
    if(‘query’==$context&&is_singular())
    {
        $id=get_queried_object_id();
    }
    
    if($dlvrit=get_post_meta($id,‘_pmg_dlvrit_url’,true))
    {
        return$dlvrit;
    }
    else
    {
        $dlvrit=newwpDlvrit(‘your_api_key’);
        $long=esc_url(get_permalink($id));
        $short=$dlvrit->get_shortlink($long);
        
        // If there’s a problem, return the original link
        if(!$short)return$link;
        
        $body=json_decode($short[‘body’]);
        
        if(!isset($body[0]->short))return$link;
        
        update_post_meta($id,‘_pmg_dlvrit_url’,esc_url($body[0]->short));
        returnesc_url($body[0]->short);
    }
}

The entire example is available as a WordPress plugin.

Developmentgoogle analyticsshortlinkswordpress
Previous
Next

Latest White Papers

  • Shifting Plans for 2020 & Beyond
  • Game On: How Brands Can Log Into A Diverse Multi-Billion Dollar Industry
  • What CCPA Means For Brands
  • How Google is Improving Consumer Data Privacy
  • Ways to Prepare for the Cookieless Future
  • See all White Papers

Featured Posts

  • Ad Age Names PMG #1 Best Place to Work in 2021
  • MediaPost Names PMG Independent Agency of the Year
  • PMG Client Portfolio Trends During Amazon Prime Day 2020
  • A Closer Look at the Congressional Big Tech Market Power Report
  • What to Know About Reddit

Categories

  • Consumer Insights
  • Content
  • Creative Design
  • Data Analytics
  • Development
  • Digital TV & Video
  • Ecommerce
  • Industry News
  • Local
  • Mobile
  • Paid Search
  • PMG Culture
  • Programmatic & Display
  • SEO
  • Social Media
  • Structured Data
Fort Worth

2845 West 7th Street
Fort Worth, TX 76107

Dallas

3102 Oak Lawn Avenue
Suite 650
Dallas, TX 75219

Austin

823 Congress Avenue
Suite 800
Austin, TX 78701

London

33 Broadwick Street
London
W1F 0DQ

New York

120 East 23rd Street
New York, NY 10010

Get in touch

(817) 420 9970
info@pmg.com

Subscribe to the PMG Newsletter
© 2021 PMG Worldwide, LLC, All Rights Reserved
  • Contact
  • Privacy Policy
 Tweet
 Share
 Tweet
 Share
 Tweet
 Share
 LinkedIn
We and our partners use cookies to personalize content, analyze traffic, and deliver ads. By using our website, you agree to the use of cookies as described in our Cookie Policy.