Posts tagged ‘shortlink’

I recently acquired a short domain name, otto42.com (the otto.com domain is owned by a German company, and I use Otto42 as my alias a lot on sites as “Otto” is usually already taken). So I decided to use it to make my own URL shortener.

I looked at various methods for this, including simply writing my own (honestly, it ain’t that hard), but I wanted to see what was already available first.

First thing I looked at was the shortlinks system built into Google Apps. I’ve used it before, and it’s fairly nifty. They even have an API available for interfacing it to other things. And hey, the redirections would be served up by Google’s servers, which you can’t beat for reliability. Sadly, after screwing around with this for a while, and trying out some example code, I was totally unable to get their API to work. The whole thing is written in Python, which I have an intense dislike of (whitespace my ass!), and when trying to access the thing via direct calls, it gave me nothing but errors and annoyances.

So I searched around a bit more, and was relegated to building my own, when a tweet by @ozh mentioned that he’d put a blog up on yourls.org. This looked promising, as I know Ozh is active in WordPress, and so of course it would have a plugin. After investigating, I went with it. It works pretty well, actually.

How to do it

First thing I did was to point my short domain at a directory on my hosting account. If it’s going to run code, it needs to have a place to do it from. So I made a yourls directory and pointed the domain to it using my hosting control panel.

Next, I grabbed a copy of the yourls code and installed it there. 300+ files to FTP? Yikes. Complex. A quick bit of reading told me that it needed a database and a config file. Very similar to WordPress in this respect, except the config file resides in the includes subdirectory for some reason. Not so obvious, but whatever.

I toyed with the idea of using the same database for yourls that I already use for WordPress, but ended up creating another one for it. I’m now thinking that it might be worth merging them though, as that way, VaultPress would probably back up the yourls tables too.

After some hosting weirdness, the thing was up and running.

Plugin

Installing the WordPress plugin is a snap. Just find it in the Add New Plugin interface and hit install. After Network Activating it for all my sites, I went to configure it. I had to configure it on each site separately, but no big deal.

Configuration is fairly straightforward. Tell it URL of the API interface, give it my username and password, and voila. Worked first try.

There’s a bunch of Twitter stuff there as well which I only set up to make it stop bothering me about it. I don’t want this plugin to send out my tweets on new posts, as I already use my own Simple Twitter Connect for that. Still, it bugs you with an error message if you don’t set it up, so I did. Thankfully, there’s checkboxes to turn the autotweeting on and off, so I just leave these turned off. Honestly, I think this whole Twitter thing should be removed from the plugin, but I can understand the “easy” factor here for new users. Making them totally optional would be a nice enhancement though.

At first, I was confused because when I turned it on, I saw no way to make it back-populate my old posts into the shortener. Turns out I didn’t need to, it started doing it all by itself shortly afterwards. I think it actually does shortening on an on-demand basis, creating a shortlink whenever there isn’t one already there for a post.

The plugin also hooks into the Shortlink API, meaning that my Twitter plugin will automagically use the new shortlink. You can see that the shortlink box below this post has the otto42.com shortlink in it. I had to make zero changes to make that work. Isn’t interoperability fun?

One other thing I did have to do was to turn off the old wp.me shortlinks I used. These are provided by the WordPress.com Stats plugin, and there’s a checkbox in its options page to turn them off. No big deal.

Final thought

So yeah, if you have a short domain and want to make your own shortlinks, then YOURLS is a pretty good choice. I haven’t played with the stats gathering part of it yet, for the simple reason that I only just turned it on and thus have no stats to view. Still very easy to do, on the whole. Of course, if it could be entirely a WordPress plugin, then I might think it much cooler. ๐Ÿ™‚

Update: There is a minor problem in the way the YOURLS plugin handles the WP Shortlink API. I’ve reported it upstream, hopefully it can be fixed soon. Still, it’s a minor issue. The workaround for now is to call wp_get_shortlink(get_the_ID()) when you want to get the shortlink for a post inside the Loop.

Shortlink:

(Note to future readers: This is fixed in WordPress 3.3, so this article is now out-of-date. See http://core.trac.wordpress.org/changeset/18541ย for the patch.)

I was not aware that other people didn’t know about this until recently, but since it seems to be little known, I thought I’d write a post on the topic.

Chain LinksIn WordPress, you should never start the custom permalink string with any of these %postname%, %category%, %tag%, or %author%. (Unless you know what you’re doing, of course. ๐Ÿ™‚ )

Meaning that “%category%/%postname% ” is a bad custom permalink string. So is just “%postname%” for that matter.

Why? Well, it has to do with how the WordPress Rewrite system works.

Rewriting Explained

See, when you request a URL from a WordPress site, WordPress gets the URL and then has to parse it to determine what it is that you’re actually asking for.

It does this by using a series of rules that are built whenever you add new content to WordPress. Generally the list of rules is pretty small, but there are specific cases that can cause it to balloon way out of control.

Normal Rules

Let’s say you’re using a normal permalink string, like my preferred “%year%/%postname%”. The rules that are generated will look like this:

/robots.txt (for the privacy settings)
/feed/* (for normal feeds of any kind)
/comments/* (for comments feeds)
/search/* (pretty url for searches, not often used)
/category/%category% (category archives)
/tag/%tag% (tag archives)
/author/%author% (author archives)
/%year%/%month%/%day% (with each of those after year being optional)
/%year%/%postname% (this is the permalink string you define)
/%pagename% (any Page)

The way that system works is that it compares the URL it has to each of those in turn, from the top to the bottom. When one of them fits, then WordPress knows what to display and how to do it.

Note that the order I listed those in is is significant. Each one from the top down is less specific than the previous one.ย  For example, “robots.txt” matches only that, while “/feed/*” matches anything starting with /feed/. And so on down the list. The %postname%, %category%, %tag%, %author%, and %pagename% will match any string, but the other WordPress % ones will only match numeric fields. Like %year% is always a number.

Notice that the last one is %pagename%. This basically matches everything, because %pagename% can be anything at all. Even hierarchical pages like /plugins/whatever/something will cause this to match. It’s the fall-through position. And then, if that page doesn’t actually exist on your site, then this causes the query to trigger the 404 condition internally, which causes your theme’s 404.php to load up.

Pretty simple and straightforward, really.

Problem Rules

The problem comes in when you try to use a non-number for the beginning of your permalink string. Let’s examine those last two rules closer:

/%year%/%postname% (this is the permalink string you define)
/%pagename% (any Page)

What if you used “%category%/%postname%” for your custom permalink string? Now those last two rules are these:

/%category%/%postname% (this is the permalink string you define)
/%pagename% (any Page)

That violates our main rule, doesn’t it? That each one should be less specific than the one above it? Because %category% can match any string too, just like the %pagename% can… With this set of rules, there’s no way to view any of the Pages. Not good.

So, WordPress detects this condition and works around it. Internally, this sets a flag called “use_verbose_page_rules”, and that triggers the rewrite rebuild to make this set of rules instead:

/robots.txt (for the privacy settings)
/AAA
/BBB
/CCC (one of these for each of your Pages)
/feed/* (for normal feeds of any kind)
/comments/* (for comments feeds)
/search/* (pretty url for searches, not often used)
/category/%category% (category archives)
/tag/%tag% (tag archives)
/author/%author% (author archives)
/%year%/%month%/%day% (with each of those after year being optional)
/%category%/%postname% (this is the permalink string you define)

Now we have basically the same set of rules, except for those new ones at the top. Every Page now gets its own very specific rule, and this satisfies our main condition once again.

Pages

But what if you have a lot of Pages? I once read a post by a person who had over 50,000 Pages on his site. That is a special case obviously, but consider our lookup system. We’re going through these rules one at a time. With our first method, our rule list was only 10 rules, maximum. With this new method, you add a rule for every single Page you make. Going through 50,000 rules takes a lot longer than going through 10. And even just building that list of rules can take a long time.

Basically you’ve created a performance issue. Your Pages now won’t scale to unlimited numbers. Your site’s speed is linearly dependent on the number of Pages you have.

This is a bad thing.

Conclusion

Firstly, it’s really not any better for SEO to have the category in there, or to have just the postname there by itself. And anybody who tells you differently is wrong. If you disagree with me, then no, I’m not interested in arguing this point with you; you’re just wrong, period, end of discussion.

Secondly, shorter links are great and all, but hell, why not use a real shortlink? WordPress 3.0 now has a ShortLink API that defaults to using ?p=number links on your own domain. These will actually work for any WordPress site, even ye back unto WordPress 2.5. WordPress 3.0 just makes it nicer and easier to use these with the Shortlink API (as well as allowing plugins to make this automagically use services like wp.me or bit.ly). So use that instead.

The conclusion is, in general, just don’t do it. Leave a number, or something static, at the beginning of your permalink string and you’ll never have any sort of problems. But if you really MUST do this sort of thing, then keep your number of Pages low. Don’t try it when you have more than, say, 30-50 Pages.

Addendum

Okay, so I actually simplified things for this post. It’s actually worse than this, as verbose page rules can add much more than one rule per page, as this post demonstrates (he gets 11 per extra page!).

Shortlink:

For you people who do your own theme work:

<?php if (function_exists('wp_get_shortlink')) { ?>
<div><span class="post-shortlink">Shortlink: 
<input type='text' value='<?php echo wp_get_shortlink(get_the_ID()); ?>' onclick='this.focus(); this.select();' />
</span></div>
<?php } ?>

Basically that adds a little Shortlink: input box with the shortlink in it. Click the box, and the shortlink becomes selected for easy copy and paste.

It’ll also work with any shortlink plugin that uses the “get_shortlink” filter to override the shortlink properly (like WordPress.com Stats).

Put it somewhere in The Loop or on the Single Post pages or what have you.

Shortlink:

I updated Simple Twitter Connect to version 0.4. New stuff:

Login message

The Login plugin now correctly displays an error message when somebody attempts to login as a user that isn’t recognized yet. This should prevent confusion about why “login doesn’t work” after activating the plugin.

Tweetmeme button

New Tweetmeme button plugin added. STC was already perfectly compatible with the existing TweetMeme plugins, but for completeness (and because it was easy), I added this. It’s much like the SFC Share plugin, really.

Note: In the future, an actual STC Share plugin will be created, which will send tweets directly from your own Twitter Application, instead of through TweetMeme. That will be a sorta replacement for this, in that it will have the same basic functionality.

Shortlink support (or lack thereof)

I made the plugin give more information about shortlinks and how they work. Basically, I’m not going to support shortlinks directly. There’s just too many of them. Instead, I have put in support for generic shortlink plugins. The idea here is that anybody can make a plugin to do some form of shortlink support, and this plugin can then use it automatically.

How this idea works:
1. A shortlink plugin author implements this function: “get_shortlink($post_id)”.
2. That’s it. Do that and the plugin will use it.

Any plugin author creating a shortlink plugin should be able to easily do this. In fact, one already has. If you use the WordPress.com Stats plugin, then you automatically get “wp.me” style shortlinks. STC will use them because they implement this function in a pluggable way.

This is also the best solution for people who prefer to implement their own shortlinks in some custom manner. All they need to do is to create a get_shortlink function that returns the shortlink string, and voila, it’ll be used.

So, there you go. Enjoy.

Shortlink: