How do I sort on a Calendar field?
A Calendar field's value, distinct from a Date/Time field, is formatted MM-dd-yyyy. Sorting on that string directly doesn't work, so convert it to a numeric timestamp first and sort on a lookup table.
With the XPath Tool
Velocity
#set ($pages = $_XPathTool.selectNodes($contentRoot, "/system-index-block/system-page[system-data-structure[calendar-field != '/']]"))
#if ($pages.size() > 0)
#set ($lookupTable = [])
#foreach ($p in $pages)
#set ($date = $_DateTool.toDate("MM-dd-yyyy", $p.getChild("system-data-structure").getChild("calendar-field").value))
#set ($dateTimestamp = $date.getTime())
#set ($_void = $lookupTable.add({
"timestamp": $_MathTool.mul($dateTimestamp, 1),
"page": $p
}))
#end
#foreach ($page in $_SortTool.sort($lookupTable, ["timestamp:desc"]))
#set ($timeStamp = $page.get("timestamp"))
#set ($item = $page.get("page"))
#set ($itemDate = $_EscapeTool.xml($item.getChild("system-data-structure").getChild("calendar-field").value))
#set ($dateFormat = $_DateTool.getDateFormat("MM-dd-yyyy", $_DateTool.getLocale(), $_DateTool.getTimeZone()))
#set ($itemDate = $dateFormat.parse($itemDate))
#set ($itemTitle = $_EscapeTool.xml($item.getChild("title").value))
$_DateTool.format('MM/dd/yyyy', $itemDate) - ${timeStamp} - $itemTitle
#end
#end
With the Cascade API
Velocity
#set ($pages = $_.query().byContentType("path/to/Content Type").execute())
#set ($removed = $_ListTool.removeNull($pages, "structuredDataNode(calendar-field).textValue"))
#if ($pages.size() > 0)
#set ($lookupTable = [])
#foreach ($p in $pages)
#set ($date = $_DateTool.toDate("MM-dd-yyyy", $p.getStructuredDataNode("calendar-field").textValue))
#set ($dateTimestamp = $date.getTime())
#set ($_void = $lookupTable.add({
"timestamp": $_MathTool.mul($dateTimestamp, 1),
"page": $p
}))
#end
#foreach ($page in $_SortTool.sort($lookupTable, ["timestamp:desc"]))
#set ($timeStamp = $page.get("timestamp"))
#set ($item = $page.get("page"))
$item.getStructuredDataNode("calendar-field").textValue - ${timeStamp} - $item.metadata.title
#end
#end
Note the removeNull call in the API example — pages without a Calendar value would otherwise break the sort. See Comparison method violates its general contract for what that failure looks like.