Sorting Categories Any Way You Please

Strange adding a category called categories… but I digress.

Two Roads Diverged…

I’ve been working on a new blog in which I want to sort the categories in order other than alphabetical. Now, there is an quick and ugly solution, and there is a time-consuming and beautiful solution. First, we’ll look at the ugly way of sorting your categories of the U.S. Presidents:

The Easy, Ugly Way

Create first category for Washington, only call it 01:Washington. Create second category for Adams… name it 02:Adams. So and so on through the U.S. Presidents. When Movable Type builds your page, it catches those initial numbers and puts them in order by number. A solution, but an ugly one, because you’re list is uglied by those darn digit prefixes.

The Difficult, Prettier and Ultimately More Rewarding Way

The second, cleaner solution requires you to install Brad Choate’s MT-Regex plugin. It’s a simple plugin that’s oh-so-powerful because it gives you the ability to search and replace using Unix-style regular expressions. In laymen’s terms it’s going to allow us to find the 01: before Washington and 02: before Adams and get rid of them. “So why put them in there in the first place if they’re just going to be deleted?” Because it removes it after Movable Type has processed the category, meaning it sorts by the 01:, 02:, but erases them before they appear on the page, giving you the power to sort the way you like.

Now to the time-consuming (unless you copy-and-paste, which is really why you’re here, right?) part. First, you need to define the regular expression that will tell MT-Regex what you want taken off your categories:

<MTRegexDefine name="patt2">s/..://gi</MTRegexDefine>

You’ll probably want to put this right before your categories code on your page so it doesn’t get lost. What you’re doing is defining a pattern named “patt2”. The ‘s’ indicates that you are performing a search, after which you would place a forward slash (/) followed by your what you’re searching for. In this example, we want to search for two digits followed by a colon. In regex, you can use a period (.) as a wildcard for any single digit. So the ‘..’ will find 01 as well as 99. If you have more digits preceeding, just be sure to have one period for each digit. Next we place another forward slash followed by it’s replacement. In this example we’re just erasing them, so we have nothing, not even a space. We close the replacement with a final forward slash followed by ‘gi’, indicating that we want the search to be global and case insensitive (neither of which really matter too much in this example). Next we need to call to the search pattern in our template. Let’s use the front page category module for our example:

<MTSubCategories>
    <MTIfNonZero tag="MTCategoryCount">
    <MTIfMatches var="CategoryLabel" pattern="m/(..:)/i">
        <a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryCount$> Entries"> <MTCategoryLabel regex="patt2"></a> |
    <MTSubCatsRecurse max_depth="3"></MTIfMatches>
    <MTElse><MTCategoryLabel regex="patt2"> | </MTElse>
    </MTIfNonZero><MTSubCatsRecurse max_depth="3">
</MTSubCategories>

If you followed the explanation earlier, the code here should make sense. We’re using the <MTIfMatches> tag to make sure that the pattern is in the category label before we load the search-and-replace function. If it exists, the pattern that we defined (patt2) is loaded and the numeric prefix is removed from the category, leaving us with a correctly sorted yet clean category list.

For more information about regex searches/syntax/possibilities, visit the Perl operators and precedence page.

Disclaimer

When your category directories are built, they will contain those first two digits. For example, your Washington directory would be /01washington/ and your Adams directory would be /02adams/. I’ve tried calling to the regex plugin in the archive file template, but it doesn’t seem to work:

<MTRegexDefine name="patt3">s/..://gi</MTRegexDefine><MTIfMatches var="CategoryPath" pattern="m/(..:)/i"><$MTCategoryPath lower_case="1" regex="patt3"$></MTIfMatches>/<$MTEntryTitle dirify="1"$>.html

All it does is take the entire category off and put the individual archives in the root directory. If anyone else has had luck with this, please leave me a content and let me know the trick…

Beta Build Issues

Also, with the new way that beta-4 handles archive file templates, I’m not sure that this old trick will work. They’ve provided ‘pre-dirifeed’ archive file path specifiers (see manual) such as %f (archive filename with the specified extension) and %c (the entry’s primary category/subcategory path passed through the dirify global filter). I still haven’t determined if mixing and matching these with normal MTTags is kosher…