Sorting Categories in Movable Type: Three Solutions
template recipes | 14 June 2007 |
If you want to sort your categories in some customized order — i.e., not alphabetically, which is the MT default — there are some solutions. I’ve tracked down three different solutions.
(Note that I am now running MT 3.35, and I’m not sure Solution #3 below works in anything below version 3.3x.)
Option 1 : Use the RegEx Plugin
Here’s what you do:
- Grab the plugin (here), and install it. If that link is broken, I’ve got the same thing locally, here.
- Rename your categories 1FirstCat, 2SecondCat, 3ThirdCat. Note that you can also do 01FirstCat, 02SecondCat, etc. This may actually be preferrable, given the way these things are sorted if you have more than 10 categories. In that situation, the sequence will be 1, 10, 2, 3 …; while, with the double-digit numbering, it goes correctly 01, 02, 03.
Somewhere in your code, add this:
<MTAddRegex name="RemoveSortNumber"> s|^([\d\.]*\s*)|| </MTAddRegex>
Now, when you use the <MTCategories> tag, add the following argument:
Basically, this is stripping digits from the start of the line.
- Easy to implement
- Requires minimal ‘treatment’ of categories
- Does not work with dynamic publishing — returns a smarty error.
- You have to know your way around regular expressions to modify the code.
Note that much the same thing can be done with the superb MT-Macros plugin. That’s really a three-and-halfth solution, because, as I see it, it’s only a refinement of the RegEx solution.
Option 2 : Use Arvind Satyanarayan’s CustomFields Plugin
- Grab the plugin (here), and install it. Use the latest release, 2.0 RC1. This will not work with the earlier release.
- Add a custom category field. Call it something like CategoryNum or some such. Check the required box — this prevents creation of a category without filling in a category number. The category type should be a single line text field so that you can add categories easily later.
- I’m not going to get into how you get the custom fields to appear — Arvind’s documentation is exemplary, and bears close study.
- Note this, though: the custom category fields do not change the entry editing screen, but the category creation screens.
- Now when you create a category you should see a box at the bottom with your custom category. Give it a number (something like 01, 02, etc), in the sequence in which you want your categories to appear.
Now here’s the trick. Over at his own plugin forums at Movalog, there’s a thread where Arvind tells of an undocumented sort feature in Version 2.0RC1 of CustomFields. You can add an argument to the MTCategories tag and force a sort by a custom field. Here’s what Arvind says:
this is a new feature (that I haven’t publiciszed or documented at all for lack of time) introduced with v2.0. To resort by a custom field (called “Foo Bar”), the following syntax is used (on MTEntries, MTCategories or MTEntries):
sort_by="CUSTOMFIELD:Foo Bar" sort_order="ascend|descend"
So supposing you wanted to resort categories by the Foo Bar field in descending order:
<MTCategories sort_by="CUSTOMFIELD:Foo Bar" sort_order="descend">
So in our case, with the CustomField CategoryNum, the code would be:
<ol> <MTCategories sort_by= "CUSTOMFIELD:CategoryNum"& sort_order="ascend" show_empty="1"> <li> <b><$MTCategoryLabel$></b> <$MTCategoryDescription$> </li> </MTCategories> </ol>
Essentially, all you are doing is sorting by the custom field, and then displaying as normal.
- Very easy, flexible, endless possibilities
- Doesn’t require processing of a string.
- Demands no special knowledge of reg-ex syntax.
- None that I can tell, but it is a Release Candidate and — so the discussions on the plugin forums say — sometimes quirky. I’ve had no problems whatever.
This one’s sort of homegrown. Here’s what you do.
- Name your categories as in Option 1 above, 01FirstCat, 02SecondCat, etc.
- In the category editing screen, unlock the category basename field. It will default to the category label and has the numbers you’ve just given them (if you’re starting from scratch, that is; otherwise skip this step, the basename won’t change).
- Strip the numbers from the basename and lock the field.
- Remember to change your archive file path specifiers and mappings in the Settings - Publishing - Archive Maps so that your category archives are built with the basename rather than the label.
Now, instead of using the <MTCategoryLabel> tag, you use the <MTCategoryBasename> tag, passing it through any formatting filters (for upper/lower case, etc). For example:
<ol> <MTCategories show_empty="1"> <li> <a href=<$MTCategoryArchiveLink$>"> <$MTCategoryBasename$> </a><br /> <Does this work?></li> </MTCategories> </ol>
Basically, you’ve swapped the category label and the category basename. Now MT sorts categories by the label, in the numbered sequence you’ve set up, but uses the basename of each category for display.
- Simple and basic. Requires no plugins, downloads, installations
- Publishing-mode neutral; it makes no difference whether your pages are static or dynamic. MT is just being forced to read another field altogether.
- Inherently limited and restrictive — it forces you to a given syntax in your basenames and labels. The basename can’t have spaces, just underscores and numbers. So if you have a multi-word category label ("01 My Favourite Things") the basename, after stripping the numbers, would be
my_favourite_things. That’s really ugly. So you’d have to either limit yourself to one word categories, or run MT-Macros or the Regex plugin to get rid of the underscores.
- Requires fiddling the archive mapping and file path specifiers.
- Horrendously inelegant as a solution.
My choice? Option 2, without a doubt. Arvind rules!