How To: Build a Tag Cloud with PHP, MySQL, and CSS

Tag clouds are everywhere. They are a popular way to show the weight (read: popularity) of tags, categories, or any words really. I needed to build a tag cloud for a project at work to display categories and show how many questions were contained inside each category. Categories with more questions would need a larger font, and categories with fewer questions would need smaller fonts. I came across this post from Steve Thomas titled How to make a tag cloud in PHP, MySQL and CSS.

Steve’s code is exactly what I was looking for. I made a few modifications to his code and wrapped it all into a custom PHP function, which you can see below.

The function returns an array that contains each category name, the CSS class that should be applied to the given category, and the category ID for linking to the page showing only questions in that category.

<?php
function tagCloud($maximum=0) {
	$cats = array(); // create empty array

	$query = mysql_query("SELECT categories.catDesc, categories.catId, COUNT( questions.id ) AS totalQuestions FROM questions, categories WHERE questions.categoryId = categories.catId GROUP BY categories.catId;");
	while ($row = mysql_fetch_array($query)) {
		$cat = $row['catDesc'];
		$counter = $row['totalQuestions'];
		$catid = $row['catID'];

		// update $maximum if this term is more popular than the previous terms
		if ($counter> $maximum) $maximum = $counter;

		$percent = floor(($counter / $maximum) * 100);
		if ($percent <20) {
			$class = 'smallest';
		}
		elseif ($percent>= 20 and $percent <40) {
			$class = 'small';
		}
		elseif ($percent>= 40 and $percent <60) {
			$class = 'medium';
		}
		elseif ($percent>= 60 and $percent <80) {
			$class = 'large';
		}
		else {
			$class = 'largest';
		}
		$cats[] = array('term' => $cat, 'class' => $class, 'catid' => $catid);

	}
	return $cats;
}
?>

You’ll also need some CSS to style your tag cloud. This CSS is pretty much identical to what Steve published, I only made some minor changes to font sizes.

#tagcloud {
    width: 300px;
    background:#FFFFCC;
    color:#0066FF;
    padding: 10px;
    border: 1px solid #FFE7B6;
    text-align:center;
}

#tagcloud a:link, #tagcloud a:visited {
    text-decoration:none;
}

#tagcloud a:hover, #tagcloud a:active {
    text-decoration: underline;
    color: #000;
}

#tagcloud span {
    padding: 4px;
}

.smallest {
    font-size: 10px;
}

.small {
    font-size: 12px;
}

.medium {
    font-size:14px;
}

.large {
    font-size:16px;
}

.largest {
    font-size:18px;
}

To use the function, do something like this:

<div id="tagcloud">
<?php
$tagCloud = tagCloud();
foreach ($tagCloud as $t) {
	$cat = $t['term'];
	$class = $t['class'];
	$catid = $t['catid'];
	print "$cat";
}
?>
</div>

I am still testing this code, but so far it seems to do exactly what I need it to do. If you experience trouble with the code or if it doesn’t act as expected, please let me know in the comments. If you’ve got ideas on how to improve the function, I’d love to hear your thoughts as well!

WordPress 2.9.2

WordPress 2.9.2 was released earlier today. You can download it here. This fixes a problem that allows users that are logged in to view trash posts authored by other users.

Thomas Mackenzie alerted us to a problem where logged in users can peek at trashed posts belonging to other authors. If you have untrusted users signed up on your blog and sensitive posts in the trash, you should upgrade to 2.9.2. As always, you can visit the Tools->Upgrade menu to upgrade.

Thomas Mackenzie goes into much greater detail about the problem on his site. Check his site out for more info on why the 2.9.2 release was necessary.

WordPress Theme: Unwakeable 1.5.3

Unwakeable 1.5.3 is available for download. This version is built off K2 1.0.3 and should work beautifully with WordPress 2.9+. You can head over to the Unwakeable page to get the download, or you can grab it here.

K2 1.0 added more support for WordPress 2.9. For example, K2 1.0 supports new WordPress features such as post thumbnail images. One of the more noticeable changes to K2 since the 1.0 release is the absence of SideBar Manager (SBM). It sounds like it was simply too much work to maintain SBM, and was beyond the scope of what K2 is:

It’s worth mentioning that the last remnants of the old SideBar Manager, or SBM, have now been removed from the codebase. It started out as a fully-fledged replacement for WP’s lacking widgets system and ended up as a patch-of-sorts to the widget system, allowing for widgets to be placed only on specified pages. But in the end, while the native widget system is still very much in need of an update, it didn’t feel right for K2 to try and cover that particular area of the administration interface. And besides, other plugins for doing just that exist already.

So instead of spending our time patching that system for an ever-changing WordPress, our time is probably better spent on more theme-specific functionality, like the rolling archives or livesearch systems, as well as keeping up with new WordPress features, like for instance Post Thumbnails.


Rather than break down all of what’s changed in recent versions of K2, I’m going to make it easy on myself and direct you to the K2 1.0 release announcement. Just know that Unwakeable 1.5.3 sports all the features found in K2 1.0.3. You can comment on this post or on the Unwakeable page with questions or comments.

WordPress 2.9.1

WordPress 2.9.1 was released a little over two weeks ago. You can download it at the usual location.

From the release announcement:

This release addresses a handful of minor issues as well as a rather annoying problem where scheduled posts and pingbacks are not processed correctly due to incompatibilities with some hosts. If any of these issues affect you, give 2.9.1 a try. Download 2.9.1 or upgrade automatically from the Tools->Upgrade menu in your blog’s admin area.

WordPress 2.9.1 came less than a month after WordPress 2.9.

WordPress 2.8.6 Security Release

WordPress 2.8.6 is available for download. It’s another security release and was released two days ago. Below is a summary from the WordPress development blog:

2.8.6 fixes two security problems that can be exploited by registered, logged in users who have posting privileges. If you have untrusted authors on your blog, upgrading to 2.8.6 is recommended.

The first problem is an XSS vulnerability in Press This discovered by Benjamin Flesch. The second problem, discovered by Dawid Golunski, is an issue with sanitizing uploaded file names that can be exploited in certain Apache configurations. Thanks to Benjamin and Dawid for finding and reporting these.

You can download WordPress 2.8.6 here.

How To: Cisco and Microsoft VPN Through Firestarter on Ubuntu

After doing a fresh install of Ubuntu 9.10 Karmic Koala on my router, I realized that I had lost the ability to connect to my employer’s VPN. I use Firestarter for managing my firewall on this particular router.

As I usually do, I googled “firestarter vpn“. Much to my dismay, it appeared that the Firestarter website was no longer alive. Instead of the usual Firestarter page, a page filled with useless links about security and anti-virus loaded. Luckily I was able to access the cached version of the page from Google. Since then, it appears that the Firestarter website has come back to life.

I wanted to make a note of how to allow VPN connections in the event that the Firestarter website becomes inaccessible again, that’s basically the point of this post. The page on the Firestarter site that details VPN connections can be found here. This should apply to pretty much every Linux distribution, not just Ubuntu.

To allow VPN connections with the Microsoft VPN client, simply enter the following lines into /etc/firestarter/user-pre.

# Forward PPTP VPN client traffic
$IPT -A FORWARD -i $IF -o $INIF -p tcp --dport 1723 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -i $IF -o $INIF -p 47 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -i $INIF -o $IF -p 47 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT


And to allow VPN connections with the Cisco VPN client, enter the following lines into /etc/firestarter/user-pre.

# Forward Cisco VPN client traffic
$IPT -A FORWARD -i $IF -o $INIF -p udp --dport 500 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -i $IF -o $INIF -p tcp --dport 500 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -i $IF -o $INIF -p 50 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -i $INIF -o $IF -p 50 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

Finally, if you’re running a Microsoft VPN server and want to allow incoming PPTP VPN connections, add the following lines to /etc/firestarter/user-pre.

# Forward PPTP VPN connections to internal server
SERVER=192.168.0.100 # Internal VPN server

$IPT -A FORWARD -i $IF -o $INIF -p tcp --dport 1723 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -t nat -A PREROUTING -i $IF -p tcp --dport 1723 -j DNAT --to $SERVER
$IPT -A FORWARD -i $IF -o $INIF -p 47 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPT -t nat -A PREROUTING -i $IF -p 47 -j DNAT --to $SERVER 

That should pretty much cover it. If you are using OpenVPN, head over to the Firestarter VPN configuration page for details.



Phoenix SEO - Search Engine Optimisation - SEO India - Contract Mobile Phones - Mobile Phones - Quick Diets
Hawaii Interior Design - Compare The Market - Payday Loans - Driving Lessons - Used Car For Sale - Security Gates
Phoenix Internet Marketing - Miami Web Design - Web Design - Bike Insurance - Search Engine Optimisation - SEO India - Scrap Gold