Advertisement

Quick Tip: Automatically Link Twitter Handles With a Content Filter

by

This Cyber Monday Tuts+ courses will be reduced to just $3 (usually $15). Don't miss out.

A few days ago I was working on a blog post on my personal blog about some recent stories. I wanted to attribute those stories to the proper source/author, which in some cases, were from Twitter. I started to manually link Twitter handles in the WordPress editor when I realized there was an easier way to do this that would then go back and link any unlinked Twitter handles on my blog. And the answer was a simple content filter.

Note: This is not integrating with the Twitter API / including tweets. If you'd like to learn how to do that, head on over to Stephen's great tutorial on Creating a Recent Tweets Widget.


Our Initial Filter

So in order to accomplish this task, we need to make use of two things: WordPress content filters and Regular Expressions (or Regex for short). First I'll show you the code and then we can go through it:

function wptuts_twitter_handles($content) {
	$pattern= '|@([a-zA-Z0-9_]*)|';
	$replace= @<a href="http://www.twitter.com/$1">$1</a>';
	$content= preg_replace($pattern, $replace, $content);
	return $content;
}

add_filter( "the_content", "wptuts_twitter_handles" );

Alright – the first thing we do is define our function, wptuts_twitter_handles() (notice I added a prefix to prevent overrides / errors). This function is going to get called in our add_filter() function, where we specify what we want to filter (or change) and a callback function. For that reason our function takes one argument, $content, which is the content of the current post.

Note 2: I am not a Regex expert and Google helped me a lot. I will link to posts that I used and explain the expressions as well as I can.

To achieve this goal, we're going to use a PHP function for processing regular expressions called preg_replace(), which accepts a pattern we're looking for, what we want to replace that pattern with, and the string we want to search. It returns the modified string. We are going to make an assumption here: any alpha-numeric string, with the inclusion of the underscore (_), preceded by an at symbol (@) is a Twitter handle. What we want to do is look through our content for any of these strings and make them hyperlinks to Twitter profiles. The pattern (as defined in our $pattern variable) we use is this: |@([a-zA-Z0-9_]*)|. The pipes on either end are simply beginning and ending delimiters, telling our program to look for what's in between them. The '@' symbol will be taken literally since it is outside the parenthesis. Inside the parenthesis is where the magic happens. The section '[a-zA-Z0-9_]' tells our program to look for any string with lowercase and uppercase letters, digits, and underscores, in any order. The asterisk (*) says it can occur 0 or more times (this is the greedy method; it could be replaced by '+', which is 1 or more). We want to replace the pattern with a Twitter link to the pattern, as defined in our variable $replace. preg_replace() will store each match in a numeric variable, which we can then reference in the replacement string. Since we are only looking for one pattern, we will reference with $1.

Now we'll do the actual replacement, which we do on this line: $content= preg_replace($pattern, $replace, $content);. This will replace our current content with the linkified content. We return $content and boom! Our Twitter handles are now linked without us having to do it manually.


One More Thing...

As Colombo (and later Steve Jobs) famously said when he was ready to wrap up, I have just one more thing to tell you. While our current pattern does in-fact detect Twitter handles, it will also detect email addresses, as it does here on my blog:


It replaces not only the email address, but the email address within the hyperlink, breaking everything!

Because of this, we'll need a regular expression that's a bit more sophisticated, looking for certain text before the '@' symbol to make sure we're not linking an email address. Twitter user @shasmirj provides us with a really nice expression to do that on his blog. Let's replace $pattern in our function with this:

	$pattern= '/(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9_]+)/i';

As you can see, this is a bit more complicated. The gist of what's going on here is that we want to make sure a few things before the '@' symbol (namely alpha-numeric strings) are excluded. With Regex, the carrot symbol (^) is used for exclusion. What this pattern essentially says is to exclude any string that has numbers or letters before the '@' while still properly checking for Twitter usernames. The alpha-numeric check is important; we still want the Twitter handle to be linked if, for example, we put it in parenthesis. This one is actually a little better than the one above, as it checks to make sure the first symbol is strictly a letter, which is a requirement for Twitter handles. The best part about this implementation is that it will exclude linked text, so if you have older blog posts where you manually link a Twitter handle, those won't break!

That means our new function looks like this:

function wptuts_twitter_handles($content) {
	$pattern= '/(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9_]+)/i';
	$replace= @<a href="http://www.twitter.com/$1">$1</a>';
	$content= preg_replace($pattern, $replace, $content);
	return $content;
}

add_filter( "the_content", "wptuts_twitter_handles" );

Just copy this bad boy and paste it into your functions.php file and you'll be good to go! And as a fun fact, you can use the same pattern to detect and link hashtags. Just replace the '@' symbol with a number sign (#).

Advertisement