Sorting Categories Any Way You Please

17 Aug 2005 ~ Link ~ Category: Categories ~ Comments: 10

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 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…

TrackBacks

Articles That Link To This One

TrackBack URL for this entry:
http://plasticmind.com/cgi-bin/mt4/mt-tb.cgi/726

Comments

Hello Jesse,

regarding the "directory naming problem" please have a look at my article

http://www.movable-type-weblog.com/archive/entry/faq-sorting-the-categories-and-avoid-alphabetical-sequence.html

A reader reported those problems and we discussed and solved them in the comment section of the article.

Do you know MTLookup? Do you want your articles be included? If so, contact me by private email.

Michael G. Schneider

A somewhat simpler way to clean up the numbers is to just use Tim Appnell's Faceted Categories plugin. It introduces a text filter that just removes everything up to the first colon it hits.

That's the solution I needed, Michael, thank you. Unfortunately (as is usually the case with information), it just because moot because I think I'm going to switch over to the plugin Su mentioned for simplicity's sake.

After all, I am first a graphic designer. Pragmatism is my middle name.

Great article!

A stickler for details, I noticed a minor detail... In regexp a '.' represents any single character except for a newline. If one wanted to match 2 numeric digits, you might use one of these:

\d\d
\d{2}

(Either of which would match exactly 2 digits) But what you have would work as long as you din't have a category actually named something like

C : None of the above

(http://www.nobodyforpresident.org/) [grin]

Hello,
First of all, thank you very much for this article! I just posted another example with modified regex on my blog. Hope it would be of help for all interested in the subject.

Absolutely. It was a great article Julian, thanks for the "plethora" of examples. When it comes to illustrating a point, I always say "the more the merrier".

Hi,

The easiest is to add a HTML comment in front of the title (so this is like the "Easy, Ugly Way", but without the ugly.

You just add numbering like in front and then you are done.

I have used it in my food recipes (sorry - they are in Danish) - because the alphabetic order didn't fit.

-- Jens

There is a lot of discussions off how to sort categories in MovableType in any way. MovableType only sorts alphabetic decending and this is often not what you need.

One solution proposed is to add a sortation number in front of the category names like:

01.Category one
02.Category two03.Category three

The problem is that you then will have the annoying numbers.

The solutions proposed on the net are extreemly advanced with additional plug ins required etc.

My solution is to use an HTML comment numbering, which won't be shown:

<!-- 01 -->Category one
<!-- 02 -->Category two
<!-- 03 -->Category three

So this will be very simple and do the job and will be shown like:

Category one
Category two
Category three

Nice, Jens. It's a little messy in terms of semantics, but mine wasn't too much better either. I like it.

Jens, I found a major problem with using your method. HTML comments cannot be used in the tag, so shows up in the title of any category based archives or individual entry archives on my blog.

Leave a comment