Lately all I seem to be having is problems, a couple of weeks ago it was with Firefox zooming, and this last week I discovered my site had a bit of a problem with shortlinks. As you may have noticed, at the top right of this post, and all my other posts and pages on my site, there is a link labelled “Shortlink” and clicking it should make a little text box appear with a
wp.me shortlink in. This shortlink is designed for sharing links on Twitter or other sites, where you might want, or require, a more compact link than the proper christopherdowning.co.uk one, which is quite long. In short (pun alert), the problem I had was that the shortlinks worked fine on my posts, but not on my pages. By default, WordPress creates shortlinks for posts (and, as far as I can tell, only for posts) which are just:
??? is a number related to the way the post is stored in the database WordPress uses. Because this isn’t ideal, I use the Jetpack plugin, which, among other things, adds
wp.me shortlinks, which are of the form:
wp.me/something, much shorter than the defaults with my long domain name. On posts this worked fine, both on my homepage and when posts were viewed individually, but on static pages, like my About page, I would instead get a shortlink of the form:
christopherdowning.co.uk/?page_id=???, which is the link the page would have if I didn’t have pretty permalinks turned on. Being the perfectionist that I am, I couldn’t just leave it alone and be satisfied with it half working, so I set about trying to fix it.
First I tried turning the
wp.me shortlink preference on and off in the Jetpack settings menu. It didn’t help. I could have tried reinstalling the plugin, but I use some of its other features, particularly the Stats, and didn’t want to risk messing those up and have an even bigger problem to fix. So instead I started looking deeper into the problem. First I looked at the HTML that my site was producing. By default WordPress adds a meta tag to the page’s header, which contains the page’s shortlink. I noticed that while this was correct on posts, and on the homepage (which has its own shortlink), on all my static pages it was set to:
www.christopherdowning.co.uk/?page_id=0, which actually takes you to the homepage. So clearly that was wrong. I then started looked into the PHP code behind the site. I don’t really know PHP as a language, I’ve changed the odd little thing here and there, but more by trial and error than anything else, I’ve never sat down and learnt it. But as I know some HTML, and some proper programming languages too, it wasn’t really too hard to follow what was going on. First I looked at the source code for my theme, but could see nothing amiss in the way it displayed the shortlinks, and besides, the problems with the meta tags led me to believe the problem was deeper. [Edit: Having looked at my theme’s
functions.php file again (while doing something else), I now realise that it does do something with the shortlinks that explains the behaviour I was seeing, see below for a full explanation.] I then looked at the source of the Jetpack plugin, well the part of it that actually does the shortlinks, and to understand that (some of) the source code of WordPress itself. After all this, while I think I understood what was going on, or at least, what should have been going on, I was none the wiser about what was actually going wrong. The conclusion I came to was that somehow, on posts and the homepage, the Jetpack plugin was being used correctly, but on pages it was being bypassed somehow.
The solution I came up with, that seems to be working at the moment, requires a little bit of explanation. There’s a PHP function built-in to WordPress called
wp_get_shortlink, and it is this function which is used by themes to get the shortlink to display it, or by WordPress itself to put it in the header. Plugins, like Jetpack, have two ways of being able to change this functions output, using something called a filter. Basically, a filter sends data to another function if it exists, or more specifically if WordPress has been told it exists via the
add_filter function. The
wp_get_shortlink function has a filter at the start, before it does anything, and a filter at the end, after it’s finished. If the first filter is used, and returns a shortlink, then the
wp_get_shortlink function itself is bypassed, it just returns the shortlink it has been given straight away. If the second filter is used, then the shortlink created by
wp_get_shortlink is passed as an argument to the other function. Both filters pass all the arguments given to
wp_get_shortlink to the other functions. The Jetpack plugin works via the second filter, but the shortlink passed to it by
wp_get_shortlink is just ignored, it just uses the other arguments to create its own shortlink. This made it very easy to try what I thought may be a solution: making the Jetpack plugin use the first filter instead of the second. In fact, only one line of code needs to be changed, by adding just four characters. I went into the Plugins editor from the WordPress dashboard, selected Jetpack from the drop-down menu, and selected
jetpack/modules/shortlinks.php from the list of files. I then changed the line:
add_filter( 'get_shortlink', 'wpme_get_shortlink_handler', 1, 4 );
add_filter( 'pre_get_shortlink', 'wpme_get_shortlink_handler', 1, 4 );
and pressed the update file button. Straight away I went onto one of the static pages on my site, opened the Shortlink box, and success, the correct
wp.me shortlink was displayed. I also looked at the HTML source to make sure the shortlink meta tag was correct, and it was.
So now all my shortlinks are right, though I am still unsure why they weren’t working correctly in the first place. Potentially one of my other plugins was interfering in some way, but as far as I know none of my other plugins mess about with shortlinks. Another possibility is that it’s a bug in WordPress 3.2, as that has just come out and I upgraded almost straight away. But, while I only discovered the problem this week, potentially it’s been there a while, I don’t use the shortlinks on pages that often. I looked through some of my old tweets and apparently the last time I tweeted one was towards the end of February, so potentially they could have been broken since about then, but I think I’d have noticed, I have done a lot of changes to my About page since then, and a few of my reviews, I’d probably have noticed if something were wrong. Either way, it was broken and now it isn’t.
Edit (2011/07/17): I now realise that my original conclusion that my theme wasn’t to fault was incorrect. While looking at my theme’s
functions.php file again, I noticed that it has a shortlink function of its own, designed to overcome the shortcomings of the default shortlink behaviour and provide basic functionality on pages as well as posts. Like the Jetpack function does originally, it uses the
get_shortlink filter to insert its own shortlink, which explains why I had a conflict and wasn’t getting the
wp.me shortlinks all the time. As using the
pre_get_shortlink filter bypasses both WordPress’ own shortlink function, and any function using the
get_shortlink filter, changing Jetpack to use it fixed my problem, as my theme’s function is no longer called at all. I think this was definitely the most elegant way of solving my problem, and, while I’m no longer puzzled about what was happening, I am a bit confused about why the Jetpack plugin doesn’t use
pre_get_shortlink by default, as it seems to be designed specifically for plugins to use.