Script based version of CFWDDX

This post is more than 2 years old.

A couple of days ago I wrote a blog post talking about how to deal with things you couldn't do in ColdFusion scripting. As one of the examples I mentioned WDDX. For some reason I've seen multiple people in the last week or so bemoan the lack of support for a script based WDDX implementation so I thought I'd whip up the code for it.

WDDX is one of those things that - like many others - ColdFusion (and Allaire) do not get proper credit for. Did you know WDDX was introduced in 1998, at the same time as XML-RPC and before SOAP and web services? (Reference - Wikipedia entry) At the time the concept was pretty darn cool. You take any form of data, serialize it, and you can then syndicate it to the world. This was before Ajax really took off so the use cases were more HTTP/remote focused. So a news site, for example, could offer their news feed in WDDX and another site could read it remotely and present it on their own site. There were multiple implementations of WDDX - including libraries for PHP, Ruby, Python, Java, Perl, and others - all of which were open source and free for developers to use. This would allow a PHP site to easily aggregate content being served up from a ColdFusion site - or vice versa.

You have to admit - that's pretty cool. ColdFusion was definitely ahead of the curve here and once again did something complex in an incredibly simple fashion. While I'm not sure I'd recommend this now (I think JSON is the best format for complex data), as I said above, some people still actively use it and therefore would like to be able to use it within script based CFCs. I wrote the following component in about 5 minutes. In order to use it within your own model files you will need to inject it (ColdSpring would make this easy), or you could use something like the Helpers feature of Model-Glue.

<cfcomponent output="false">

&lt;cffunction name="toWddx" access="public" returnType="string" output="false"&gt;
	&lt;cfargument name="input" type="any" required="true"&gt;
	&lt;cfargument name="useTimezoneInfo" type="boolean" required="false" default="true"&gt;
	&lt;cfset var result = ""&gt;
	&lt;cfwddx action="cfml2wddx" input="#arguments.input#" output="result" useTimezoneInfo="#arguments.useTimezoneInfo#"&gt;
	&lt;cfreturn result&gt;

&lt;cffunction name="toCFML" access="public" returnType="any" output="false"&gt;
	&lt;cfargument name="input" type="any" required="true"&gt;
	&lt;cfargument name="validate" type="boolean" required="false" default="false"&gt;
	&lt;cfset var result = ""&gt;
	&lt;cfwddx action="wddx2cfml" input="#arguments.input#" output="result" validate="#arguments.validate#"&gt;
	&lt;cfreturn result&gt;


And here is a simple example usage. I didn't actually use cfscript, but you can see how it would work:

<cfset s = { name="Ray", age=38, foo=[1,2,3,{x="1",y="2"}]}> <cfdump var="#s#" label="original data structure">

<cfset wddx = new wddx()> <cfset encoded = wddx.toWddx(s)> <cfoutput>#htmlEditFormat(encoded)#</cfoutput> <p> <cfset data = wddx.toCFML(encoded)> <cfdump var="#data#" label="After to wddx and back again...">

And the result...

Please consider the following code licensed under Apache License V2.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA

Archived Comments

Comment 1 by todd sharp posted on 4/21/2011 at 9:47 PM

What about something even simpler Ray?

Comment 2 by Jon Hartmann posted on 4/21/2011 at 9:47 PM

I realize this is a 5-minute implementation, but haven't you limited the scope of the cfwddx tag with this implementation? I'd just make single function that calls cfwddx with attributecollection="#arguments#" and be done with it. Maybe define the arguments, all with required="false" so people can pass them in my order as well as name... Thats pretty much how I implemented a UDF to get spreadsheet data (

Comment 3 by Jon Hartmann posted on 4/21/2011 at 9:48 PM

Todd beat me to the punch.

Comment 4 by Raymond Camden posted on 4/21/2011 at 9:52 PM

I think those are fine - but - you can do it even simpler with mine if you are just serializing.

foo = wddx.towddx(x)

T me, that's simplest, versus

foo = wddx.towddx(input=x)

Comment 5 by Raymond Camden posted on 4/21/2011 at 10:01 PM

I do think perhaps the methods could be renamed to encode/decode.

Comment 6 by Sean Coyne posted on 4/21/2011 at 10:16 PM

If you added this CFC to the CustomTags/com/adobe/coldfusion folder would ColdFusion treat it as it does the other new "component based" script equivalents? That way we can future proof a bit when Adobe uses this in CF X.

Comment 7 by Raymond Camden posted on 4/21/2011 at 10:21 PM

CF doesn't treat _any_ of those guys special. If you open them up (they are unecncrypted) you will see they are just vanilla code. So sure - if you copied mine there you could do:

cfset foo = new com.adobe.coldfusion.wddx()

Comment 8 by Sean Coyne posted on 4/21/2011 at 10:28 PM

I was thinking more along the lines of <cfset test = new wddx() /> (without the dot path). Which does work. (Tested on CF 9.0.1).

I guess I was referring to the specialness of the customtags path rather than the actual files inside them.

Isn't that how your feed.cfc came to be part of CF9?

Comment 9 by Raymond Camden posted on 4/21/2011 at 10:31 PM

Ah, I keep forgetting you can leave the full path off. Personally, I recommend keeping the full path so you always know you are working on one of the files in that directory.