Sorting objects and lists in Velocity

A shameless reprint of my answer on this Community thread. As Marketo user TR pointed out, the docs claim custom objects are sorted by last updated timestamp, descending from newest to oldest, but nope: they're actually sorted by create date, descending.

Re-sorting by last updated is as simple as:

#set( $sortedList = $sorter.sort($customObjList,"updatedAt:desc") )  
The most recently updated is ${sortedList[0]}

But this post isn't about the “last 10 objects” bug/feature, it's about sorting in Velocity in general — which is incredibly easy. And it has applications beyond custom objects. You can sort a list of lead fields to find the max cost or score, or simply alphabetize a list of product interests so the email looks neater, whatever you want.

As you can see from the snippet above, the Velocity SortTool — the $sorter object in Marketo VTL — can easily sort a list of objects by one or more of the objects' internal property values.

So say you had a list like this:

[
  {
    "maker" : "Beechcraft",
    "purchaseDate" : "2016-08-26"
  },
  {
    "maker" : "Cessna",
    "purchaseDate" : "2016-07-20"
  },
  {
    "maker" : "beechcraft",
    "purchaseDate" : "2016-09-25"
  }
]

You can sort by maker in ascending order and then by purchaseDate in descending order:

#foreach( $obj in $sorter.sort($objList,["maker:asc","purchaseDate:desc"]) )  
${obj.maker} - ${obj.purchaseDate}
#end

Here's the output:

beechcraft - 2016-09-25
Beechcraft - 2016-08-26
Cessna - 2016-07-20

Notice a couple of details:

  • Velocity uses a case-insensitive sort for Strings: “beechcraft” and “Beechcraft” are considered identical here.
  • You can sort date-y Strings in yyyy-MM-dd format without converting them to Date objects, since they're designed to alphabetize properly. Same for ISO datetime-y Strings (yyyy-MM-ddTHH:mm:ssZ) and for almost-ISO-y Strings (yyyy-MM-dd HH:mm:ss).
  • You can't use a dumb alphabetical sort on localized date-y Strings like “December 1, 2016”. Those would have to be converted to Dates first. You'd have to loop over the $objList once and add a new Date property to each object. Then it would become possible to do $sorter.sort($objList,"trueDate:desc").

That's it for SortTool! I'm sure you'll find more fun things to do with it.