Fuddland
Update: The following refers only to Movable Type versions 2.5 — 2.661, and not the dynamic features of MT 3.1x.
I’ve never really figured out the best thing to do with entry categories. There are some categories for which I want to gather all the relevant entries into one archives — for example, photo-based or music-related entries — but MT has this “all-or-nothing” approach to category archives: you can either create archives of all your different categories, or have none at all. The former seemed to me like quite a waste of server space [some categories would probably never get visited], so I never bothered having true category archives, and just made bespoke templates utilising the SubCategories and CatEntries plugins. However, rebuilding each one manually was a bit of a pain, and setting them all to update automatically seemed like unnecessarily adding to rebuild time — I really wanted a better solution.
The method I devised is described below, and is probably only of interest to MT-geeks. The rest of the world can just skip to the category archive list to see the fruits of my labours.
The key was a little-known [and undocumented] feature of MT versions 2.6 or later, called MT-View; it’s a CGI script that accesses the entry database and creates on-the-fly output. Here are the steps I took to create dynamic category archives.
Firstly, I created a category archive-related template along the lines of the default template, named “Dynamic” [although you can call it what you like].
I then went to my MT archiving configuration page and added a new archive of type “Category”, selecting the template I’d just made, but leaving the Archive File Template field blank. This tells MT which template is associated with category archives, but does not create any static files.Update: This step turned out to be unnecessary, and actually created files with the default filenamecat_category_namein the root archive directory — precisely what I was trying to avoid!Because MT-View is experimental, its use is disabled by default, so I had to uncomment [or you may need to add] the line that says
Safemode 0in themt.cfgfile.
At this stage dynamic category archives were technically working: to generate the archive for any given category, I just needed to find out its associated category_id and the blog_id code, either from the mySQL database or by reading them off the appropriate MT interface URL. Say I wanted the archive for the category “Site News” — this has category_id 51, and the blog_id is 5, so I’d just point the browser to
http://somedomain.com/path/to/mt-view.cgi/5/section/51/
and MT would do the rest.
This is all you need for dynamic category archives if your category template [what I named “Dynamic”] outputs pure HTML, as the default template does. However, I had two problems: firstly, I didn’t like the “meaninglessness” of the URL above — you can’t tell by looking at it what category you’re viewing unless you happen to know the id of each one; secondly [and of a more real issue], I use PHP server-side includes and other bits in my templates. The file outputted by the CGI script doesn’t get parsed as PHP, and so all the PHP code remained unprocessed.
I decided that I wanted a URL that looked “friendlier” but still indicated that the page was dynamically-generated, along the lines of
http://somedomain.com/archives/category.php?cat=category_name
and found the general idea in a post by Brad Choate. The file category.php contains the following code:
Update: After learning a little more about PHP and how it handles variables passed from the URL, I made a slight change to the code below.
<?php
// Set the blog ID
$blog_id = <$MTBlogID$>;
// Build up an array of all category names and IDs
$cat_list = array(
<MTCategories>"<$MTCategoryLabel dirify="1"$>" => <$MTCategoryID$>,
</MTCategories>);
// If no category is specified, return an error
if ((!$cat) || ($cat=="")) {
echo "Error: no Category specified";
return;
}
// Find the ID associated with the category
// or report an error if the category name is not found
foreach ($cat_list as $name => $id) {
if ($name == $cat)
{
$cat_id = $id;
}
}
if (!$cat_id)
{
echo "Error: unknown Category specified";
return;
}
// Build up the path to mt-view.cgi
$includepath = 'http://somedomain.com/path/to/mt-view.cgi/';
$includepath .= $blog_id.'/';
$includepath .= 'section/'.$cat_id.'/';
// Output the result of mt-view.cgi
include($includepath);
?>
As you can see, this contains some MT tags, so I set it up as a new Index Template called “Dynamic Category” to live in my /archives directory, unchecked the “Rebuild this template automatically…” option, and rebuilt it once manually. Now, because the mt-view.cgi code is included into a PHP file, it gets parsed as PHP; the first section of this script automatically finds the category_id associated with the friendly dirified category name.
Creating a list of links to each category archive is easy:
<ul>
<MTCategories>
<li><a href="/archives/category.php?cat=<$MTEntryLabel dirify="1"$>"><$MTEntryLabel$></a></li>
</MTCategories>
</ul>
Everything still works when <MTCategories> is replaced with <MTSubCategories> so this technique can be used to produce a fairly extensive set of category-based archives at very little cost to server space. It could also be easily extended to the other functions of MT-View [date-based and individual archives], which I think would boil down to creating a more sophisticated version of category.php that replaced the line
$includepath .= 'section/'.$cat_id.'/';
with the appropriate text. For a more detailed guide to MT-View [actually, the only guide to MT-View I could find], see Al-Muhajabah’s Brief Users’ Guide to mt-view.cgi.
Update: Comments are now closed; if you have any questions or suggestions regarding this entry, please contact me.
Related entries
The following is an entry which follows on from the above:
-
MTIfNoEntries plugin [Fuddland]. Excerpt: MTIfNoEntries plugin: conditional tag that displays its content if there are no entries in the current context.
Comments
imogen | 2004 / 03 / 05 – 04:59
really david — who is going to need this information? i mean seriously? sigh. yawn. ; P
Jann | 2004 / 03 / 05 – 09:22
I reckon you should just write your own cms. Considering the amount of customizations and adjustments you’ve made over time..
You’re obviously geeky enough.
movable fudd? fuddworx? fuddism? no, wait…fuddland. Yeah, call it fuddland.
David | 2004 / 03 / 05 – 11:09
Re #1: You’d be surprised how many emails I’ve already received, praising me for this write-up: none. Surprised, right? No? Ah.
Re #2: I don’t know enough about databases, security and code optimisation to make writing my own CMS an option right now. Besides, I wouldn’t want to blow your own long-awaited product out of the water. ;)
Commenting Closed
Commenting on this post is closed. Thanks to all those who left comments. If you'd still like to say something about this entry, feel free to email me.