To Sub-Categorize or not to Sub-Categorize
BIOS LEVEL March 24th, 2007ObsidianSo I’m sitting here working on the updates I promised and I have a dilemma. The update in question is the reviews section. Why am working on that section over others? Because once it’s done, regardless of the rest of the site, we can start posting content and driving traffic. And then you ask what the dilemma is, and I answer: How far should one sub-categorize?
This blog for example, only has 1 level of categories. At the moment, our reviews section has 2. From the “base” category, to sub-categories of the base, to sub-categories of that level.
- hardware
- videocards
- accessories
How far do I go down? Do I break Videocards down by Chipset, Chipset by Vendor? I don’t anticipate people to look that in-depth, nor do I expect to have a great variety of similar products from different brands. So is the “videocard” category complete as is?
Should I choose to break it down farther, or at least leave the option to break a category down as far as possible in the future? The issue comes in with the code involved. The database is simplistic: Category ID, Parent, and Name. That should be self-explanatory. But when trying to retrieve all children, you’re going to end up relying on either several loops, or some recursion in your code.
function getChildren($id,&$db)
{
$cats = "";
$parent = $id;
$sqCat = "SELECT id,title FROM acats WHERE parent = $id";
$qCat = $db->query($sqCat);
if (DB::isError ($qCat))
die ("SELECT failed: " . $qCat->getMessage () . "<br/>" . $sqCat . "<br/>" . $id[3]);
while ($rCat = $qCat->fetchRow())
{
if(!($cats == ""))
{
$cats .= "|";
}
$cats .= $rCat[0] . ":" . $rCat[1];
}
// id:title|id2:title2
return $cats;
}
So the above function pulls all the children of category $id, if any. This is a shortened version of what I’m using currently, there are no checks in it, nor a control to keep the string in line (note the “:” that will appear on the end). Regardless of features, it works the same for our purposes. Now we need some code that will call upon getKids() for all the categories.
function showCats($id,$db)
{
$sRet = "<ul>";
$children = getChildren($id,&$db);
$i = 0;
while( ($kids = explode("|",$children)) && ($kids[$i] != "") )
{
$parts = explode(":",$kids[$i]);
$sRet .= "<li>$parts[1]"; // shows the name
if($parts[0] != "")
{
$sKids = showCats($parts[0],$db);
if ($sKids != "<ul></ul>")
{
$sRet .= $sKids;
}
}
$sRet .= "</li>";
$i++;
}
$sRet .= "</ul>";
return $sRet;
}
So, this second function is designed to format the information we got from getKids() and display it in an unordered list. At the same time, for each item returned to us by getKids(), it calls itself to check for children of each category all the way down the list. This should be an effective way of future-proofing our category system, allowing us to add as many sub-categories as we wish. Then it will just be a question of sanity and user-friendliness.
On a side note, I wrote this post to reason out the code needed to achieve this purpose. =P

April 12th, 2007 at 3:22 pm
[…] Finally back with some progress updates (I’ve managed to tear myself away from World of Warcraft, evil thing…). Once again, I’m focusing on the Articles & Reviews section, for some hopefully obvious reasons. […]