cloudy

something i’ve been wanting to do for a while is shift from the boring and overwhelming list of categories on my sidebar to a tag cloud in the ultrahip web 2.0 folksonomic tradition. this is not because i aspire to be hip like three snaps in a 2(.0) formation, but because i think clouds are a good idea.

i like clouds because:
they have more information in them than lists (size is information!).
they are prettier than lists.
they take up less room than lists.
they are where the care bears live.

what’s not to love?

once upon a time, in a spurt of energy to this end, i downloaded and installed the formidably named Ultimate Tag Warrior plugin, which promises nifty tag cloud goodness for all, but which ended up requiring too much of me in order to realize such goodness, so i let it drop.

i think i was frustrated because i knew deep down that it was not a very complicated problem, but it was still too much for me to think about on any one given day, so i ignored it for a silly long time.

therein languish so many of the ills of this world…

but today i prevailed!
go look! (you have to be on the main page, not viewing just this post)
heeeheehee!!!

and if you don’t want to hear anything geekier than that, you should stop reading, because now i’m gonna talk about code and stuff. so consider yourself warned.

i decided to search around again for options and advice, and i found very fruitful beginnings in:
this blog entry wherein the code professor churns out some wordpress-ready php for cloud-building, he being inspired in turn by
the technology evangelist writing about using php and css to build tag clouds for movable type blogs.

i liked the approach suggested by them because the core idea for wordpress is simple:
1) replace the part of the sidebar.php file that goes to fetch the category list with your own code that makes a tag cloud.
2) size appropriately using css.

once i thought about this, installing a plugin for the task felt silly and much less fun, so i was inspired to follow their trail.

the php as provided went through the trouble of counting the number of posts in each category even though wordpress provides a function for that, but then someone in the comments pointed that out and offered some new code, so that was nice.

the css was taken from the technology evangelist as written, and i didn’t really like it. it basically assigned each tag an id based on the number of posts in the category and then sized the tags based on that number, which is reasonable in theory except in practice it led to css brackets like this:

a.tag4 ,a.tag5, a.tag6 {
 font-size:16px;
 font-weight:300;
}

for each triad of numbers up to 30.

and apparently it just expects that no category will have more than 30 posts.

this seems short-sighted to me, particularly because if you were a somewhat balanced category user and you blogged for a number of years you would eventually get to the point where almost all of your tags were the same size. which defeats the purpose.
and sure you could go in as you wrote more and change the numbering scheme, but who wants to do that?

it makes more sense to me to size each category based on the percentage of total posts. in the beginning all your tags would be big because each post would be a large percentage of the total, but it seems like it would equalize out pretty quick, and then scale well with time.

the only downside is that it requires you to count all the posts, and writing another loop for that seemed a little excessive. i did a little more searching and found this, which offers a php function that will get the total number of posts for you. apparently people want to do that somewhat often, but wordpress doesn’t support it directly. yet. but i still love them.

anyway, here is the code that i ended up with after mashing those bits and pieces together and fiddling with dangling quotation marks and asking david for some help because he conveniently appeared on IM right when i was having an issue.

thanks, david!

if you are running wordpress and want a tag cloud like mine, open your sidebar.php file (it’s in wp-content/themes/youractivetheme), find the part that looks like this:


and replace it with this:

categories ORDER BY cat_name";


$cats = $wpdb->get_results($qrystr);


//get total number of posts to use for normalizing 
//the size of the category tags
$totalposts = $wpdb->get_var('select count(*) from wp_posts 
where post_status = "publish"');

//read and write the category data
echo '
'; foreach ($cats as $cat) { $catname = $cat->cat_name; $catlink = get_category_link($cat->cat_ID); $postcnt = $cat->category_count; $catweight = $postcnt/$totalposts; /*this part sets the values that are used to do the tag sizing. you can fiddle with the percentage thresholds if you don't like the size distribution within your cloud. if you only have a few posts or a few categories, everything will be big for a while. blog more! :) you can also change the id text if my flippancy annoys you. just be sure to change the css too. and bah, humbug. ;) */ if ($catweight == 0) $tagweight="zilch"; elseif ($catweight < .02) $tagweight = "notmuch"; elseif ($catweight < .05) $tagweight = "some"; elseif ($catweight < .1) $tagweight = "couplefew"; elseif ($catweight < .15) $tagweight = "several"; elseif ($catweight < .25) $tagweight ="lots"; else $tagweight = "damn"; echo ''; echo $catname," "; } echo '
'; ?>

then open your style.css file and add this:

#cloud {padding:1px; line-height:20px;text-align:center;}
#cloud a {text-decoration:none;padding:0px;}


a.zilch {
display:none;
}


a.notmuch {
 font-size:12px;
}

a.some {
 font-size:16px;
 font-weight:200;
}

a.couplefew {
 font-size:18px;
 font-weight:300;
}

a.several {
 font-size:20px;
 font-weight:400;
}

a.lots { 
 font-size:24px;
 font-weight:500;
}

a.damn {
 font-size:28px;
 font-weight:600;
}

then tell me if it works and if you like it!

now it is time for bed.

UNEXPECTED PLUG: putting lots of code in your wordpress posts without it interpreting the code as code is aNNoying. i used this plugin. it made me happy.

6 Responses to “cloudy”

  1. shveta Says:

    Thanks for sharing this. I too want to try out tag clouds, not sure if blogger would allow that like wordpress though.

  2. Mom Says:

    Speaking of pretty tag clouds! http://multiplex.integralinstitute.org/public/about/multiplexmap.aspx

  3. Erik Says:

    I did this on my site too! I calculated the item size algorithmically though. Here’s my method, which is pretty crappy code, but it works, and I don’t have time to make it right.

    function wp_tag_cloud($wpdb) {
    // Grab category info from the database table wp_categories
    $qrystr = “SELECT * from $wpdb->categories ORDER BY cat_name”;

    $cats = $wpdb->get_results($qrystr);

    //get total number of posts to use for normalizing
    //the size of the category tags
    $totalposts = $wpdb->get_var(“select count(*) from wp_posts where post_status = \”publish\””);

    //read and write the category data
    foreach ($cats as $cat)
    {
    $catname = $cat->cat_name;
    $catlink = get_category_link($cat->cat_ID);
    $postcnt = $cat->category_count;

    if ($postcnt “;
    echo strtolower($catname) . “   “;
    }
    }

  4. Erik Says:

    Obviously that code is broken, because wordpress stripped out the tag. Meh.

  5. kynthia Says:

    sweet! i am a trendsetter!
    ;)

    that’s a good idea; i will consider it when it sounds fun to revise mine further.
    right now i am enjoying it working all by itself. :)

    fwiw i think the tiny text on your cloud is too tiny.
    i know not always what it says.
    but i still like it!
    yay clouds!

    and wordpress stripped out what where?
    i don’t even see it if i look at the original and try to fix it for you, but i am nearing a food coma, so my eyes are far from their sharpest.

  6. Erik Says:

    stripped out the php. not sure it’s worth trying to make that work. :)

Leave a Reply