I updated my Spry demo, again, this time with a few fixes. First, the URL:
http://ray.camdenfamily.com/spry/blog3.cfm
Just in case it isn't obvious, this is an AJAX front end to this blog. The only thing different from the "real" blog is that I limit the total amount of entries per category to 100.
So what changed? First, there was a bug in paging and sorting. If you sorted, it only applied to the current page, and not the entire set. This was fixed thanks to Adobe. The fix will be in the next release of Spry. (Lucky me, I know all the right people. :)
The second fix was more interesting. I noticed that the HTML data wasn't being rendered right. My HTML was being escaped. Turns out this made sense as my CFC was xmlFormatting the result. Kin Blas of Adobe (one of the Spry folks) pointed out that I need to CDATA wrap my result. Let me show you how I did that in my CFC:
<cffunction name="queryToXML" returnType="string" access="private" output="false">
<cfargument name="data" type="query" required="true">
<cfargument name="rootelement" type="string" required="true">
<cfargument name="itemelement" type="string" required="true">
<cfargument name="cDataCols" type="string" required="false" default="">
<cfset var s = "<?xml version=""1.0"" encoding=""UTF-8""?>">
<cfset var col = "">
<cfset var columns = arguments.data.columnlist>
<cfset var txt = "">
<cfset s = s & "<" & arguments.rootelement & ">">
<cfloop query="arguments.data">
<cfset s = s & "<" & arguments.itemelement & ">">
<cfloop index="col" list="#columns#">
<cfset txt = arguments.data[col][currentRow]>
<cfif listFindNoCase(arguments.cDataCols, col)>
<cfset txt = "<![CDATA[" & txt & "]]" & ">">
<cfelse>
<cfset txt = xmlFormat(txt)>
</cfif>
<cfset s = s & "<" & col & ">" & txt & "</" & col & ">">
</cfloop>
<cfset s = s & "</" & arguments.itemelement & ">">
</cfloop>
<cfset s = s & "</" & arguments.rootelement & ">">
<cfreturn s>
</cffunction>
This method, queryToXML, translates a query to XML. (Duh.) There is a method for this already at CFLib, but I wrote mine from scratch because I like doing that. My fix today was to add a new optional argument, cDataCols. This lets me specify which query columns will contain HTML and should be CDATA wrapped instead of xmlFormatted. All I did then was to simply change my call in getEntries:
<cffunction name="getEntries" returnType="xml" access="remote" output="false">
<cfargument name="category" type="uuid" required="true">
<cfset var s = structNew()>
<cfset var q = "">
<cfset s.maxEntries = 100>
<cfset s.byCat = arguments.category>
<cfset q = variables.blog.getEntries(s)>
<cfcontent type="text/xml">
<cfreturn queryToXML(q, "entries","entry","body")>
</cffunction>