Building A Tag Cloud In WordPress
I decided to make a tag cloud for WordPress today, but with a twist. Most of the tag clouds I see were category tag clouds, meaning they were based on the number of posts in a category. I don’t really have enough categories yet to do something like this though. Instead, this is more of a keyword or post tag cloud.
This kind of cloud tag makes a little more sense to me, at least from the perspective of a visitor. They can, in one quick view, tell exactly what you talk about in your blog posts. I also made it so visitors can click on any of the tags and it will use the built-in search engine to find posts with whatever word they clicked on.
I should warn you before you continue reading, I slapped this together in a couple of hours and it is what you would call a very, very rough draft. I will be updating this code in the near future, using WordPress’ classes instead. It will most likely become a plugin too. Alright, enough of the boring stuff, here is the PHP code.
<?php
DEFINE('DB_HOST', 'localhost');
DEFINE('DB_USER', 'username');
DEFINE('DB_PASS', 'password');
DEFINE('DB_NAME', 'database');
$link = @mysql_connect(DB_HOST, DB_USER, DB_PASS)
or die('Could not connect to MySQL: ' . mysql_error());
@mysql_select_db(DB_NAME)
or die('Could no select the database: ' . mysql_error());
$query = "SELECT post_content FROM posts WHERE post_status='publish'";
$result = mysql_query($query);
while ($row = mysql_fetch_array($result)) {
$post = $row[0];
$content .= $post;
}
mysql_close();
$content = strip_tags($content);
$content = str_replace("—", " ", $content);
$content = str_replace(" ", " ", $content);
$content = str_replace("—", " ", $content);
$content = str_replace("&", "", $content);
$content = str_replace(""", "", $content);
$content = str_replace("\\", "", $content);
$content = eregi_replace("!|\?", "", $content);
$content = eregi_replace("[0-9]", "", $content);
$content = trim($content);
$content = strtolower($content);
$wordlist = preg_split('/\s*[\s+\.|\?|,|(|)|\-+|\'|\"|=|_|—|%|\*|\[|\]|\\|\^|;|×|\$|\/|:|{|}]\s*/i', $content);
$a = array_count_values($wordlist);
$overusedwords = array('','one','two','three','four','five','six','seven','eight',
'nine','ten','am','come','does','its','must','seen','yet',
'an','the','and','of','to','is','in','with','for','as',
'that','on','at','this','my','was','our','it','you','we',
'about','after','all','almost','along','also','amp',
'another','any','are','area','around','available','back',
'be','because','been','being','best','better','big','bit',
'both','but','by','came','can','capable','control','could',
'course','dan','day','decided','did','didn','different',
'div','do','doesn','don','down','drive','each','easily',
'easy','edition','end','enough','even','every','example',
'few','find','first','found','from','get','go','going',
'good','got','gt','had','hard','has','have','he','her',
'here','how','if','into','isn','just','know','last','left',
'li','like','little','ll','long','look','lot','lt','made',
'make','many','mb','me','menu','might','mm','more','most',
'much','name','nbsp','need','new','no','not','now','number',
'off','old','one','only','or','original','other','out',
'over','part','place','point','pretty','probably','problem',
'put','quite','quot','re','really','results','right','same',
'saw','see','set','several','she','sherree','should','since',
'size','small','so','some','something','special','still',
'stuff','such','sure','system','take','than','their','them',
'then','there','these','they','thing','things','think',
'those','though','through','time','today','together','too',
'took','two','up','us','use','used','using','ve','very','want',
'way','well','went','were','what','when','where','which',
'while','white','who','will','would','away','before','your','a',
'b','c','d','e','f','g','h','i','j','k','l','m','n','o','p',
'q','r','s','t','u','v','w','x','y','z','try','why','instead',
'either','actually','www','com','px','top','read');
foreach($overusedwords as $word) {
unset($a[$word]);
}
asort($a);
echo "<p>";
foreach ($a as $word => $count) {
if ($count <= 5) {
$size = 75;
} elseif ($count <= 10) {
$size = 100;
} elseif ($count <= 15) {
$size = 125;
} elseif ($count <= 20) {
$size = 150;
} elseif ($count <= 25) {
$size = 175;
} elseif ($count <= 30) {
$size = 225;
} elseif ($count <= 35) {
$size = 250;
} elseif ($count <= 40) {
$size = 275;
} elseif ($count <= 50) {
$size = 300;
} elseif ($count <= 100) {
$size = 340;
}
if ($count >= 10) {
echo " <a href=\"/?s=".$word."\" title=\"The word "$word" appears ".$count." times in divspace posts\" style=\"font-size:".$size."%;\">".$word."</a> ";
}
}
echo "</p>";
unset($a, $word, $count, $size);
?>
I warned you it was going to be sloppy! But sloppiness aside, here are some things I will definately be adding:
-
For the size of my blog, this code is no problem, but for users with hundreds of posts, it makes more sense to cache the tag cloud and just include that instead.
-
This will obviously become a function, and I’d prefer to give people the option to adjust how the tag cloud is displayed. For example, some users might want the "heavier" words on top, not the bottom. Some users might want it sorted alphabetically.
-
Possibly come up with a better way to get rid of common words. There’s two different ways to achieve this. You can manually enter the words in the
$overusedwordsarray, or keep increasing the threshold on the countifstatement.
Oh, and as for the configuration of this, all you really need to mess with is the DB_USER, DB_PASS, and DB_NAME. Enjoy!
November 5th, 2006 at 06:06 pm
[…] « Building A Tag Cloud In WordPress […]
December 11th, 2006 at 06:24 pm
Interesting, but why do you *sort* the tags?
December 11th, 2006 at 06:50 pm
Well you can sort them a number of ways. From A-Z, Z-A, largest to smallest, smallest to largest, or just let it fall as it may. Depends on how you want it really.
December 12th, 2006 at 02:07 pm
[…] Hypernarrative.com now has a tagcloud autogenarated from the contents of the blog. A script reads the text and filters certain words. […]
February 3rd, 2007 at 08:18 am
Nice Script.
I don’t want to have the tags sorted.
If I remove the asort($a); the tags aren’t sorted anymore, but the tags that should be large are small.
I just changed the sizes and now it works unsorted…
August 6th, 2007 at 11:27 am
Hi,
This script is not working in my wordpress blog, you can my site: http://www.0hv.net
Please advice, need installation instructions in more details.
Thanks.
February 20th, 2010 at 03:36 pm
[…] Relationships.=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- =-Related blog postsdivspace | Programming ? Building A Tag Cloud In WordPressthe groovement 19.09.07"the l word" recaps: episode 5.6 "lights! camera! action […]