Can We Extend the ColdFusion Server

I love playing around with new toys. So, I'm ecstatic now that ColdFusion 9 has been officially released to the world, and even more so after what I'm about to tell you. Oh sure, I've been playing around with the betas, but mostly in testing the cfajax/ExtJs 3 upgrades (and I'll be posting more on that in the coming months). Time has been somewhat limited for me, so playtime has had to take a back burner. But, I wish I had gotten into this a bit sooner.

Yesterday I finally got around to working with some of the new cfscript implementations. I find these upgrades to be one of the key features for me personally. One, It's a faster coding style for me. Two, I was getting tired of bouncing between script and tags. Three, I really like the economy of code associated with script, finding it to be far less verbose. So, I'm lovin' the fact that I can write all of my CFC's, including my Application.cfc, in pure script. Now I can keep the tags with the display. But, as someone pointed out to me in a recent comment, there are still a few tags (anyone know which ones?) that haven't yet gotten script implementations. What can we do about that?

So, in diving right into playing with script enhancements, I ran into a few roadblocks. Minor errors, stemming from me not properly understanding the implementation. Now, the first place I went was to the documentation. Ray Camden keeps saying to me "Why don't people read the documentation?" I'm one of those that agrees with him. Yes, the documentation has some holes, and even bad examples, but you would be surpised what you can learn. (Read on, you'll see where I'm going with this!)

In discovering all of this wonderful new scripting, I came across Script Functions Implemented as CFCs in the new CF 9 CFML Reference. I was stepping through all of the subtopics, when I came upon this little tidbit:

Script functions are available in the following location: cf_root\CustomTags\com\adobe\coldfusion.

Ensure that you do not delete the default custom tag mapping listed in the ColdFusion Administrator (Extensions > Custom Tag Paths > Custom tag mappings).

Script functions work if they are either in the default location or web root. If you have the functions in any other location, add a /com mapping in the ColdFusion Administrator that points to the new location (for example C:\com).

I wasn't really surprised by this. Ray had recently alluded to this functionality in his recent post on Gotchas with Queries in Script. I just hadn't thought about it too much. Now, reading the above, a question had smacked me upside the head. Can we extend ColdFusion? Can we write our own "Script Functions Implemented as CFC's?" Basically create our own server plugins?

Well, of course we can. We've been able to do that since CF 6, haven't we? Written CFC's, and used CreateObject()? Placed CFC instances into persistent scopes for broad access? Yes, we have. But I wondered if someone could write a script version of cfsavecontent, and instantiate it anywhere within the application using the new content(); type of syntax? So, I decided to do a little digging, and a little testing.

Side Note: You must have access to your ColdFusion file system to do the following.

The first thing to note, is that all of the functions mentioned, in that set of topics of the CFML Reference, are represented as CFC's inside the server's default CustomTags folder.

CustomTags Folder Structure
The second thing to note, is that these CFC's all have init functions that reference the object in dot notation, according to this path:
public com.adobe.coldfusion.query function init(){
                ...
OK, simple enough. So, I wouldn't want to utilize the Adobe namespace. Separation would be important for portability. In that case, I'll just create my own: com.cutterscrossing.coldfusion. So, if I create a component called 'myComponent', it's initializer would be basically the same:
public com.cutterscrossing.coldfusion.myComponent function init(){
                ...
CustomTags Folder Structure w/ new namespace
So, I built the myComponent.cfc using the "New ColdFusion Component" menu item and wizard within ColdFusion Builder. Output never being exactly what you want, I made the necessary adjustments to get the CFC to where I wanted it: an init() method, with getter and setter functions for firstName, lastName, and emailAddr. I also added a dump() method, that would dump those variables to the screen in the standard cfdump type of layout. Then, I wrote a quick test script:
<cfsetting enablecfoutputonly="true" />
<cfscript>
    REQUEST.him = new myComponent();
    REQUEST.him.setFirstName('Homer');
    REQUEST.him.setLastName('Simpson');
    REQUEST.him.setEmailAddr('homer@duffbeer.com');
</cfscript>
<cfoutput>
<html>
    <head>
    <title>Something</title>
    </head>
    <body>
        #REQUEST.him.dump()#
    </body>
</html>
</cfoutput>
<cfsetting enablecfoutputonly="false" />
Well, I hit the page, and...it died. Well, I keep forgetting to kill the template and component caching settings in my ColdFusion Administrator (a must on your development and staging servers). After resolving all of that, I hit my template again (drum roll, please):
CustomTags Folder Structure w/ new namespace
Voila! "So," you might ask, "what does all of that mean?" Well, after some truly diligent study of the objects already in the Adobe namespace, it means that you can extend the ColdFusion server. It would be best to move the server's CustomTags folder first (adjusting the mapping), so that any additions wouldn't accidentally get wiped out with an update or anything, but it could be done.

There are many different possible applications, from writing script versions for the few remaining tags, to creating your own scripted function objects (for instance: write a scripted function object for converting video to flv format). What do you think we could do with this?

TweetBacks
Comments
Brad Wood's Gravatar Very interesting. So basically, all components in that default custom tag directory are automatically imported into every page.
# Posted By Brad Wood | 10/8/09 4:21 PM
Steve 'Cutter' Blades's Gravatar That's what it looks like. I did some pretty good testing with this, moving the directory around, redefining it, etc. I even created a new CustomTags directory in the admin, along side the default, and components for that worked as well. That said, I think great care would need to be given to the structure of any objects placed in the architecture
# Posted By Steve 'Cutter' Blades | 10/8/09 4:30 PM
Edward Smith's Gravatar I think that the "new" operator in CF9 now is just shorthand for "createObject("component",...)

Ben has a post about this:

http://www.bennadel.com/index.cfm?dax=blog:1648.vi...

In which he shows that you can use cfimport to import a set of tags, or you can also just refer to the full "classpath" of the component as well:

bob = new com.cutterscrossing.coldfusion.myComponent();
# Posted By Edward Smith | 10/8/09 5:03 PM
Steve 'Cutter' Blades's Gravatar @Edward Smith

That may be true, but it likely wouldn't be available across the entire server, unless it were tied to a server wide cfmapping. Syntax wise, I think new myComponent() is far better than new com.cutterscrossing.coldfusion.myComponent(). It's the fact that all components, within the CustomTags folders, are available with that shorthand syntax, regardless of subfolder depth, and from any application on the server.
# Posted By Steve 'Cutter' Blades | 10/8/09 5:43 PM
ike's Gravatar Very cool, thanks for posting that, Steve. :) Not sure why I'm so surprised by it, knowing that there was something similar going on with many of the tags before, where native tags had been developed as custom tags in a special folder. ;)
# Posted By ike | 12/16/09 7:06 PM
Rain's Gravatar Thanks for sharing! You've made a great explanation. Every day there is more and more info about CF 9. I like Lynda's tutorials: http://www.videorolls.com/watch/Creating-a-map-wit... . They are quite informative.
# Posted By Rain | 7/4/10 2:59 AM
BlogCFC was created by Raymond Camden. This blog is running version 5.9.3.006. Contact Blog Owner. Layout inspired by bluerobot.com., with some JQuery thrown in for fun.