I've made no secret of my love for ColdFusion Builder extensions. To me - this is the single most important feature of ColdFusion Builder. Version 2, currently in public beta, adds additional features to extension developers, including support for views (woot!) as well as other miscellaneous features. I've developed a few public extensions myself (you can see mine and many others on the RIAForge category page) and have developed various libraries/utilities to help my development. I finally decided to formalize this with a library I'm calling builderHelper.

builderHelper is a simple CFC that abstracts out a lot of the common tasks I've run into when developing extensions. To work with it, you simply initialize it with your IDE XML info:

<cfset helper = new builderHelper(form.ideeventinfo)>

Once initialized, you get a whole set of helpful utility functions. For example, imagine you have an extension that works in both the editor view as well as the Navigator. You can quickly check to see which mode is being run:

<cfif helper.getRunType() is "projectview">

If the user did use the Navigator (labelled "projectview"), you may need to know if they selected a file or folder, and which file or folder they selected.

<cfset selection = helper.getSelectedResource()> <cfif selection.type is "folder"> <cfset files = directoryList(selection.path, true, "path")> <cfelse> <cfset files[1] = selection.path> </cfif>

Or perhaps they used the editor and you need to know the selection:

<cfset selection = helper.getSelectedText()> <!--- for now, we do the entire file, period ---> <cfset contents = fileRead(selection.path)>

Helpful, right? One of the new features in ColdFusion Builder 2 is a callback url. This callback url is - well - a url (duh) that your extension can use to send special commands to. These commands allow you to do things with Builder itself. Need to open a file? You use the callback url. Need to refresh a folder because your extension changed crap? Use the callback url. Want to know what tables exists in a datasource? Ditto.

This system has a simple XML inteface. So for example, to refresh a folder you send an XML packet containing the folder. My builderUtil makes this even easier though. Consider:

<cfset helper.refreshFile(f)>

As a full example, I've included a zip to this blog entry for an extension I wrote called "Fix Smart Quotes." I'm doing tech editing on a jQuery Mobile book and some of the code samples include Smart Quotes. (If there was ever anything more misnamed before than I don't know what it is...) I can fix those easily enough by selecting a smart quote, hitting ctrl-c, going to search, doing a replace, etc, and it takes me all of 10 seconds, but I thought - why not use an extension and do it even quicker. The code below is the full handler for this extension. Notice that I never have to deal with XML once. All the grunt work is done via the helper.

<cfset helper = new builderHelper(form.ideeventinfo)>

<cfif helper.getRunType() is "projectview"> <cfset selection = helper.getSelectedResource()> <cfif selection.type is "folder"> <cfset files = directoryList(selection.path, true, "path")> <cfelse> <cfset files[1] = selection.path> </cfif>

<cfloop index="f" array="#files#"> <cfset contents = fileRead(f)> <cfset contents = replace(contents, chr(226) & chr(128) & chr(157), """", "all")> <cfset fileWrite(f, contents)> <cfset helper.refreshFile(f)> </cfloop>

<cfoutput>Processed #arrayLen(files)# file(s).</cfoutput>

<cfelse> <cfset selection = helper.getSelectedText()> <!--- for now, we do the entire file, period ---> <cfset contents = fileRead(selection.path)> <cfset contents = replace(contents, chr(226) & chr(128) & chr(157), """", "all")> <cfset fileWrite(selection.path, contents)> <cfset helper.refreshFile(selection.path)> </cfif>

You can download this extension below. I probably will not put this up on RIAForge as it's pretty limited. The extension includes builderHelper itself obviously so you don't need to download it from RIAForge.

Download attached file.