FarCry Core 6.1 Express: Ready to run

farcry-usb

FarCry Express is a "ready to run" installation of the latest FarCry 6.1 code base and the brand spanking new Fandango theme. So now you have no excuse for not checking out the latest FarCry code base!

http://org.farcrycore.s3.amazonaws.com/express/farcry-express-111125.zip

Express is not a production ready environment, but its a lot of fun to get a handle on the FarCry caper, run a few tests, do some training or just toy with an idea.  The install runs a Railo Express instance from the folder -- everything is contained in the one little directory branch. To uninstall or start a-fresh, just delete the folder and you're done. It even works on a USB!


This is a cross-post from the official FarCry Core Team blog.

Sublime Text 2 key bindings for CFML Developers

One of the first things I did when I started using Sumblime Text 2 was to set up some key bindings to emulate functionality that I was used to using in CFEclipse / CFBuilder 1. These were the usual keyboard shortcuts for inserting or wrapping selections in code like CFDUMP, CFOUTPUT, hashes, comments, etc.

To set up your own user key bindings, choose Preferences -> Key bindings - User from the menu. The configuration is an array of JSON objects, so remember to put your comma's in the right places :)

Here's my current ColdFusion / CFML related key bindings which you might find useful.

 

[
// cf tags
//
	// cfabort
	{ "keys": ["ctrl+shift+a"], "command": "insert_snippet", "args": {"contents": "<cfabort>" } },
	// cfdump
	{ "keys": ["ctrl+shift+d"], "command": "insert_snippet", "args": {"contents": "<cfdump var=\"#${0:$SELECTION}#\">" } },
	// cfoutput
	{ "keys": ["ctrl+shift+o"], "command": "insert_snippet", "args": {"contents": "<cfoutput>${0:$SELECTION}</cfoutput>" } },
// wrappers
//
	// hash
	{ "keys": ["ctrl+shift+h"], "command": "insert_snippet", "args": {"contents": "#${0:$SELECTION}#" } },
	// single line comment
	{ "keys": ["ctrl+shift+m"], "command": "insert_snippet", "args": {"contents": "<!--- ${0:$SELECTION} --->" }, "context": 
		[
			{ "key": "text", "operator": "not_regex_contains", "operand": "\n" }
		]
	},
	// multi line comment
	{ "keys": ["ctrl+shift+m"], "command": "insert_snippet", "args": {"contents": "<!--- \n${0:$SELECTION} --->\n" }, "context": 
		[
			{ "key": "text", "operator": "regex_contains", "operand": "\n" }
		]
	},
// remap sublime text defaults
//
	{ "keys": ["ctrl+alt+d"], "command": "duplicate_line" },
	{ "keys": ["ctrl+alt+m"], "command": "expand_selection", "args": {"to": "brackets"} }
]

Sublime Text 2 and Distraction Free mode

Sublime Text 2 offers a couple of different editing modes which I find useful on different occasions. The bulk of my coding is usually done in a normal window mode but there is also Full Screen mode, which - obviously - takes over the whole screen including the taskbar area, and Distraction Free mode, which just lets you view ONLY the file you're working on without any extra chrome or features or "distractions" on the screen.

Out of the box, Distraction Free mode can feel a little bit limiting because word wrap is turned on at 80 characters. I like the way the code is "centred" on-screen but I prefer to increase the word wrap to at least 120 characters (Sublime Text's word wrapping is quite good with automatic intending of wrapped lines) and also to hide the menu bar and enable the mini-map (the mini view of the code on the right side of the screen).

 

sublimetext2-distraction-free

 

To do this you can simply add some settings to your "Distraction Free User Preferences" file, via the Preferences -> File Settings - More -> Distraction Free - User menu item. You can also toggle the menu bar and mini-map in the View menu and your preferences will be saved for all Distraction Free mode sessions.

 

{
	"gutter": false,
	"line_numbers": false,
	"word_wrap": true,
	"wrap_width": 120
}

 

Note I have gutter and line numbers disabled (as they are out of the box), but you can enable them if you wish. I'm not yet used to having the line numbers and gutter appear all the way to the left side of the screen when the code is centred, it feels slightly wrong, but I've also found that when concentrating on a single file I'm really not worried about line numbers. They are a must at almost all other times though :)

It's also worth noting that you could turn on tabs if you wanted to, or any other number of features - whatever works for you.

Vote for CFML tag literals in cfscript on the CF Bug Tracker

This is just a short post. I've added an Enhancement Request to the Adobe ColdFusion Bug Tracker for adding XML and CFML tag literals to cfscript. If you like the idea then please go ahead and vote for it :)

http://cfbugs.adobe.com/cfbugreport/flexbugui/cfbugtracker/main.html#bugId=86199


If you missed my previous blog entries about CFML tag literals (C4X) you can read them here:

CFML proposal: XML and CFML tag literals for cfscript (C4X)
Using CFML tags in cfscript (C4X prototype)


There has also been some discussion on Ben Forta's blog about cfscript and ActionScript. Check out these two posts:

Ben Forta: Justin Carter On CFML In CFSCRIPT
Ben Forta: I Am Not A Fan Of CFSCRIPT


I'm a fan of cfscript and I'd prefer Adobe to keep refining it rather than trying to provide new scripting language options - but that's another post for another day :)

Using CFML tags in cfscript (C4X prototype)

Update: I've added Enhancement Request #86199 to the Adobe ColdFusion Bug Tracker. Please go there and vote for it if you would like to see this considered in a future version of ColdFusion!

About 8 months ago I wrote a blog entry which discussed the concept of using XML and CFML tag literals in cfscript, dubbed C4X for want of a better title. (If you missed that entry you might want to read it first before continuing with this one). A few weeks later I wrote some proof of concept code in the form of a function that would let me use this C4X style of syntax in cfscript.

The following code has only been tested on ColdFusion 9, and since it uses the virtual file system along with included virtual files it requires a mapping for the logical path /ram pointing to ram:// (this should also work on Railo though I haven't tried it). The function itself is just 40 simple lines of code:

function c4x(string tagInput)
{
    var c4xResult = "";
    var c4xFilename = "c4x_#createUUID()#.cfm";
    var tag = listFirst(arguments.tagInput, " #chr(9)##chr(10)##chr(13)#<>");
 
    if (left(tag, 2) eq "cf") {
        if (tag eq "cfquery") {
            // query: inject name attribute
            arguments.tagInput = replace(arguments.tagInput, "cfquery", "cfquery name='c4xResult'");            
        }
        else if (tag eq "cfxml") {
            // xml: inject variable attribute
            arguments.tagInput = replace(arguments.tagInput, "cfxml", "cfxml variable='c4xResult'");            
        }
        else {
            // other: capture output using cfsavecontent
            arguments.tagInput = "<cfsavecontent variable='c4xResult'>" & arguments.tagInput & "</cfsavecontent>";
        }    
        // write code to ram disk, execute, clean up
        try {
            fileWrite("ram://#c4xFilename#", arguments.tagInput);
            include "/ram/#c4xFilename#";
        }
        finally {
            fileDelete("ram://#c4xFilename#");
        }
    }
    else {
        if (isXML(arguments.tagInput)) {
            // xml: parse and return xml object
            c4xResult = xmlParse(arguments.tagInput);
        }
        else {
            throw(message="C4X: Invalid syntax. Root tag must be a valid CFML tag or well-formed XML. Application framework and flow control tags are invalid.")
        }
    }
         
    return c4xResult;
}


Essentially this lets us pass some CFML to the c4x() function in a string and we'll get back a result such as a query, XML object or some other type of output (or, in this prototype, nothing if the CFML tag has no output). This method could also handle custom tags, although not custom tags that have bee imported into a namespace from a tag library.

What does C4X look like again?

If C4X support existed natively in CFML, a simple query against the cfartgallery database could look like this in a script-based CFC or <cfscript> block:

artists = <cfquery datasource="cfartgallery">
		SELECT firstname, lastname, email, city
		FROM app.artists
		WHERE
			city IN (<cfqueryparam cfsqltype="cf_sql_varchar" list="true" value="New York,Washington">)
	</cfquery>;


If the C4X proof of concept function above was available in the variables scope then we could use it like this:

artists = c4x('<cfquery datasource="cfartgallery">
		SELECT firstname, lastname, email, city
		FROM app.artists
		WHERE
			city IN (<cfqueryparam cfsqltype="cf_sql_varchar" list="true" value="New York,Washington">)
	</cfquery>');


This code works now, in CF9. The artists variable will now contain the query object resulting from the <cfquery> tag. The only difference between the two pieces of code is simply the function wrapping the CFML code; the 7 unnecessary, but necessary, characters of c4x(' ')...

How do the current script equivalents compare?

Below I have three example pieces of code; a simple query, a dynamic query with logic, and a query of a query. Each of these examples will be compared using code from ColdFusion 9, Railo 3.2, and the mythical C4X :)

As we well know the CF9 script version of performing queries is more verbose than the way CF developers have traditionally done things, with the <cfquery> tag.

What some people might not know is that with Railo 3.2 there is another way of doing queries in script which is different to the CF9 implementation. In my opinion, it seems to strike a nice balance, but perhaps still isn't ideal due to the need for using writeOutput() to build up your SQL statements.

So, on to the comparisons!

A simple query

// CF9 query
qs = new Query(datasource="cfartgallery");
qs.setSQL("SELECT firstname, lastname, email, city
	FROM app.artists
	WHERE
		city IN (:cities )");
qs.addParam(name="cities", cfsqltype="cf_sql_varchar", list="true", value="New York,Washington");
artists = qs.execute().getResult();
 
// Railo 3.2 query
query name="artists" datasource="cfartgallery" {
	writeOutput("SELECT firstname, lastname, email, city
		FROM app.artists
		WHERE
			city IN (?)");
	queryparam cfsqltype="cf_sql_varchar" list="true" value="New York,Washington";
}
 
// C4X query
artists = <cfquery datasource="cfartgallery">
	SELECT firstname, lastname, email, city
	FROM app.artists
	WHERE
		city IN (<cfqueryparam cfsqltype="cf_sql_varchar" list="true" value="New York,Washington">)
</cfquery>;

A dynamic query with logic

// CF9 query with logic
qs2 = new Query(datasource="cfartgallery");
qrySQL = "SELECT firstname, lastname, email, city
	FROM app.artists
	WHERE
		city IN (:cities )";
qs2.addParam(name="cities", cfsqltype="cf_sql_varchar", list="true", value="New York,Washington");
if (myartMember) {
	qrySQL &= " AND email LIKE :email";
	qs2.addParam(name="email", cfsqltype="cf_sql_varchar", value="%@myart.com");
}
qs2.setSQL(qrySQL);
artists2 = qs2.execute().getResult();
 
// Railo 3.2 query with logic
query name="artists" datasource="cfartgallery" {
	writeOutput("SELECT firstname, lastname, email, city
		FROM app.artists
		WHERE
			city IN (?)");
	queryparam cfsqltype="cf_sql_varchar" list="true" value="New York,Washington";
	if (myartMember) {
		writeOutput(" AND email LIKE ?");
		queryparam cfsqltype="cf_sql_varchar" value="%@myart.com";
	}
}
 
// C4X query with logic
artists2 = <cfquery datasource="cfartgallery">
	SELECT firstname, lastname, email, city
	FROM app.artists
	WHERE
		city IN (<cfqueryparam cfsqltype="cf_sql_varchar" list="true" value="New York,Washington">)
		<cfif myartMember>
			AND email LIKE <cfqueryparam cfsqltype="cf_sql_varchar" value="%@myart.com">
		</cfif>
</cfquery>;

A query of a query

// CF9 query of a query
qs3 = new Query(dbtype="query");
qs3.setAttributes(artists=artists);
qs3.setSQL("SELECT firstname, lastname
	FROM artists
	WHERE
		lastname LIKE :lastname");
qs3.addParam(name="lastname", cfsqltype="cf_sql_varchar", value="T%");
artistsQoQ = qs3.execute().getResult();
 
// Railo 3.2 query of a query
query name="artistsQoQ" dbtype="query" {
	writeOutput("SELECT firstname, lastname
		FROM artists
		WHERE
			lastname LIKE ?");
	queryparam cfsqltype="cf_sql_varchar" value="T%";
}
 
// C4X query of a query
artistsQoQ = <cfquery dbtype="query">
	SELECT firstname, lastname
	FROM artists
	WHERE
		lastname LIKE <cfqueryparam cfsqltype="cf_sql_varchar" value="T%">
</cfquery>;

Comparison results

As you can see from the code above and the table below, the C4X version of the code is a bit more concise than the Railo 3.2 version and significantly more concise than the CF9 version.

  Simple query Dynamic query Query of a query
CF9 276 chars (100%) 435 chars (100%) 269 chars (100%)
  7 lines 12 lines 8 lines
Railo 229 chars (83%) 350 chars (80%) 179 chars (67%)
  7 lines 11 lines 7 lines
C4X 217 chars (79%) 329 chars (76%) 167 chars (62%)
  6 lines 9 lines 6 lines


Better yet, there isn't really any new syntax to learn to be able to write code this way; simply remove the name attribute from the <cfquery> tag, place a variable and assignment operator before the tag and a semicolon after the tag. It's just the same old CFML you've always had to write, used in a new way inside script-based CFCs or <cfscript> blocks.

Why C4X?

As I mentioned in the previous blog entry, the main reason for implementing CFML tag literals is flexibility. It provides access to existing native tags that might not have script equivalents (yet). It's a potential solution for integrating custom tags into script based CFCs. It provides code reuse options. If you think about it, CFML tags and custom tags are now the outcasts in script based CFCs (i.e. they cannot be used), whereas previously cfscript was limited in its functionality compared to the possibilities with CFML tags.

I do like the direction Railo 3.2 has taken, but is it ideal?

To finish, here's a bunch of tweets which show a few reasons why cfscript still needs to be improved:

CFML proposal: XML and CFML tag literals for cfscript (C4X)

Update: I've added Enhancement Request #86199 to the Adobe ColdFusion Bug Tracker. Please go there and vote for it if you would like to see this considered in a future version of ColdFusion!

This is a feature proposal for the CFML standard and for ColdFusion 10. It's reasonably long so you might want to grab a coffee or a cold drink before settling in for the ride. You can't say I didn't warn you :)

Almost a year ago Sean Corfield called for comments to help the CFML Advisory Committee decide on how some parts of cfscript should be implemented in future versions of ColdFusion. Full script based components were mostly under control, the only real sticking point was how to handle the script equivalent of nested CFML tags that also include body text - such as cfmail, cfquery and custom tags - which I'll call the "problem tags". A month later, after reviewing the 145 replies in the discussion, Sean made his recommendation to the committee to introduce a set of objects for the "problem tags". The use of objects was a logical, straight forward solution which would not introduce any new syntax and would therefore have no direct impact on the learning curve of the language or on the compiler(s). It was definitely the right step for bringing the capabilities of cfscript into line with the capabilities of CFML tags.

ColdFusion 9 was released in October 2009 and brought with it the much desired enhancements to cfscript, including full script based components, implicit getters and setters, many of the missing functions that developers have typically created UDF wrappers for, script equivalents of newly introduced tags, and the new "problem tag" objects which Adobe called script functions implemented as CFCs.

The CFML Advisory Committee and Adobe have finally brought cfscript up to the point where, in most cases, there is no need to chop and change between script and tag based approaches because the majority of code can now be written successfully either way. Which brings us to today...

Can cfscript be further improved?

At the moment cfscript is in good shape but I think most developers would agree that there are still things that could be done to improve our productivity and help with code readability and maintenance.

There are some CFML tags that still do not have script equivalents such as cffeed and cfldap (as noted by Chris Peters in his post on Full script CFCs aren't yet where they need to be), cfcontent, cfheader, cfschedule and cfsetting. We could continue to write UDF and CFC wrappers for these tags but of course it would be nicer if the language specification and vendors had clear rules about providing a consistent implementation for all tags and their equivalent functions or objects. Consistency and coverage are important.

There are also some things about the script functions implemented as CFCs which are not quite optimal. For tags like cfmail and cfquery the script equivalent tends to be slightly more verbose than the tag based approach - which in itself isn't a problem, more like a potential target for optimisation. Ben Nadel has also found a couple of issues* with the Query.cfc implementation, one of which is a bug in the parsing of named parameters and the other which can potentially expose a SQL injection vulnerability that wouldn't exist when using the cfquery tag. Ben does note that this is only a problem "when you are using horrible SQL to begin with" but you could say that any code which exposes a vulnerability is horrible. Ben also concluded that some of the cfscript "tag operators" are inconsistent in the way they are implemented (with/without named arguments, with/without parenthesis, etc). So there may be some opportunities for improvement in this area. (*Please note: one or both of the above Query.cfc issues may have been addressed after the RC or Gold release of CF9 but I have so far been unable to confirm it).

Finally, cfscript doesn't yet attempt to tackle support for custom tags. The main reason for this, and any tags which use body text and nested tags, is that trying to morph the syntax into something that looks like script - and yet will actually work - is difficult. Sean was the first to admit this, and it became evident after many attempts that there isn't really a nice "scripty looking" way to do it. Vince Bonfanti says that we shouldn't even try to solve the problem, and that we should ban the use of cfcomponent and cffunction tags and the writeOutput() function as soon as is feasible. Personally I couldn't disagree more. Banning tag based CFCs is pretty extreme, but there is also nothing wrong with allowing developers the flexibility to build something the way they want to build it - after all that is what we've been fighting for in regards to cfscript! Let's leave the choice of syntactic optimisation up to the developers and not dictate it in the language. (As a side note, Railo supports component based custom tags which I think are also quite exciting for CFML and cfscript).

Overall these issues aren't show stoppers though and I'm sure the tag to script coverage will push further towards 100% in future releases.

However, there is one more important issue to recognise with the balance of tags versus script. You can use cfscript anywhere you like within a tag based component or page, but you cannot use CFML tags within a script based component. You might ask, "Why would you want to do that anyway?" Well, the answer, as I alluded to above, is simply: flexibility.

What is cfscript for XML (C4X)?

If you are not familiar with ECMAScript for XML have a quick read of the E4X entry on Wikipedia. There are a couple of ways that the addition of E4X-style syntax could benefit CFML so I want to describe them in incremental steps. I'll call this concept C4X meaning "cfscript for XML".

The idea of having something like C4X in cfscript is not mine. I saw it first mentioned by Rick Osborne in Sean's call for comments where it received some good support by a number of people. Rick then went on to expand on his ideas in a blog entry titled CF9 + E4X + C4X. Even more interesting is that 3 months prior he had already suggested that cfscript should have E4X-like support (and commented that it was already too late to get it into CF9):

"There's no way we're going to see something E4X-like with XML fragments built into CF9. If we scream loud enough we might see it in CF10. Maybe." -- Rick Osborne

This is my attempt to get the conversation going again, and if enough people are interested then we can all "scream" together. So, on to the actual examples...

XML literals

The first and most obvious benefit of C4X is the ability to declare XML literals. When XML is treated as a primitive type it means you could assign a chunk of XML directly to a variable, i.e. there is no need to create a string and then use the xmlParse() function to parse it into an XML object.

Creating an XML object in cfscript without C4X:

person = xmlParse("<person>
  <firstname>Ben</firstname>
  <lastname>Forta</lastname>
</person>");

Creating an XML object in cfscript with C4X:

person = <person>
  <firstname>Ben</firstname>
  <lastname>Forta</lastname>
</person>;

This is the most basic example and as you can see it saves a dozen keystrokes and makes the code slightly cleaner and easier to read. It's not ground breaking but it's an improvement.

XML literals would also support variable / statement evaluation and could be useful for working with XML-compliant chunks of HTML. You could build fragments of HTML from a data set and then do further processing on them as XML (using the existing functions of the language) - something which would be difficult to do with strings - before finally using / rendering them.

Creating an XML-compliant HTML fragment including variable evaluations with C4X:

article = <div class="article">
  <h2>#qArticle.title#</h2>
  <p>#qArticle.teaser#</p>
</div>;

A full E4X-style implementation would also include filtering, manipulation via operators (e.g. using + for appending nodes) and a bunch of other stuff, but at this stage I am a little hesitant to suggest taking it that far (though this is up for debate). The main thing I wanted to do was explain XML literals and their benefits so that I could introduce the next C4X concept.

CFML tag literals

This is where we get to the meat of the proposal. C4X could overcome some of the issues raised above by allowing us to write declarative code where it makes the most sense: when dealing with nested CFML tags and tag body text. I'm not sure that "tag literals" is the right term but I'll run with it.

Since the cfquery and cfmail (and other) tags now have a script equivalent in CF9 we can begin to look at ways in which our cfscript code can be further enhanced. I'll demonstrate this by showing CF9's script version followed by the proposed C4X version.

Executing a query in cfscript without C4X:

qry = new Query(datasource="myDSN");
qry.setSql = "SELECT * FROM users";
qUsers = qry.execute().getResult();

Executing a query in cfscript with C4X:

qUsers = <cfquery datasource="myDSN">
  SELECT * FROM users
</cfquery>;

The first thing you'll notice is how tidy the C4X version is, at around 70% of the keystrokes of the script equivalent. The second thing is that the (usually required) name attribute is omitted from the cfquery tag because the assignment implies that the cfquery tag will assign the resultant query object directly to the qUsers variable. This implied attribute assignment could also work for all other tags that typically have a name or result attribute (note: since it's not quite consistent across all the built-in tags the actual attribute name will vary from tag to tag - I haven't done a full analysis but in most cases the implied attribute should be a single, obvious attribute).

So those query examples were pretty trivial. Let's beef it up a little with some logic and a parameterised value.

Executing a query in cfscript without C4X:

function getUsers(userID="0") { 
  var qry = new Query(datasource="myDSN");
  var sql = "SELECT * FROM users";
  if (arguments.userID neq 0) {
    sql += " WHERE userID = :userID";
    qry.addParam(name="userID", value=arguments.userID, cfsqltype="cf_sql_integer");
  }
  qry.setSQL(sql);
  var qUsers = qry.execute().getResult();
  return qUsers;
}

Executing a query in cfscript with C4X:

function getUsers(userID="0") { 
  var qUsers = <cfquery datasource="myDSN">
    SELECT * FROM users
    <cfif arguments.userID neq 0>
      WHERE userID = <cfqueryparam name="userID" value="#arguments.userID#" cfsqltype="cf_sql_integer">
    </cfif>
  </cfquery>;
  return qUsers;
}

With the slightly more complex query the C4X example is around 80% of the keystrokes of the script equivalent and a couple of lines of code shorter. I think at this point it's becoming clearer how workable this solution could be.

So which tags could be used as a CFML tag literal? Pretty much any CFML tag except for flow control tags I think. If it's a tag that "returns" a value like cfquery then definitely. If it's a tag that just does some processing and doesn't return anything then there's no reason it couldn't return "true" if no exceptions were thrown. If it's a tag that outputs something to the response stream then the output could either be assigned to the variable or we could use the cfsavecontent tag as a wrapper to capture it (the latter would probably be better).

How does a compiler handle C4X?

I don't think C4X is a difficult thing for a compiler to deal with. If the root node is a CFML tag (or a custom tag) then it's clearly a block of CFML code. Otherwise, it's assumed that it's a chunk of XML that could contain some variables or statements that need to be evaluated, and invalid XML should throw a compile time error. And, obviously, for this to work the XML or CFML literal would have to have a single root node / tag.

Internally, CFML engines may choose to treat XML literals as a subclass of their existing XML classes if that provides some benefit during compilation or for any future additions to C4X (such as full E4X-style filtering syntax and other operations, if they were deemed feasible; again, I'm still on the fence). I don't know enough about how the engines work under the hood to make any further suggestions here though.

One more consideration is how do IDE's handle C4X? Well, if an IDE can handle E4X's XML literals then C4X support should be somewhere in the same ball park, and so I'd be hopeful that it's within the realm of possibility for the IDEs that we use today.

Final thoughts

Personally I think it only takes a glance to see that C4X could be quite nice to work with, and the beauty of it is that it's not the only way to write the code - if you want to use a purely object based scripting solution then you can, because it already exists. On top of that, this is just the same as existing code that we have always had to write in CFML, just used in a new way (with a variable name, assignment operator and a semi-colon - definitely not rocket science!). There is barely any learning curve at all.

I'd be very interested to hear the thoughts of the ColdFusion community, staff/members of the CFML Advisory Committee, Adobe, Railo and OpenBD, and especially from those who thought E4X-style syntax was a bad idea 12 months ago. Now that a pure, object based solution exists, is there room for an improvement like C4X, and if not is there a better reason than "I just don't like tags inside script", even though in most cases the code could be considered cleaner and easier to read?

I think C4X could be another step in the right direction for CFML. Let us know what you think!

ColdExt RC 1 released!

Now up on RIAForge is the first Release Candidate of ColdExt. ColdExt is a ColdFusion tag library which makes it easier to build rich user interfaces using the amazing Ext JS library. ColdExt supports multiple CFML engines including CFMX 7, CF8, Railo 3.0.1 and OpenBD 1.0.

This release provides support for ExtJS 2.2.1 plus 6 new demos and 2 new user extensions - fileUploadField and gridSearch.

The main enhancement in RC 1 is to allow the JS and CSS resources for User Extensions to be loaded up front on the calling page, meaning that UX components can now be used in remote pages loaded via Ajax. This can be configured on the onReady tag using the uxLoad attribute, by specifying a comma delimited list of the extensions to load (based on the folder name of the extension in the /ext/ux folder) or by specifying "all" to load the resources for all extensions. For e.g.

<ext:onReady loadingMask="true" uxLoad="all">

Check out the latest demos for a bit more of a taste of ColdExt, and be sure to view the source of each demo to see how easy ColdExt is to implement.


coldext-rc-1


In other news, Kevin Roche wrote a nice series of blog posts on ColdExt back in December documenting some of the issues he faced in implementing some components. ColdExt also got a mention in Episode 2 of the CF Hour podcast by Dave Ferguson and and Michael Sean Becker â€" cheers guys :)

Also be sure to mark your calendars for April 14-16 2009 as the first ever Ext Conference will see the release of Ext JS 3.0! Expect a ColdExt release to follow during April.


If you have any feedback or feature requests for ColdExt please get in touch by leaving a comment here, using the contact form on the ColdExt project page or emailing me directly (my email address is in the readme.txt file in the downloadable zip!)

Running CF7 and CF8 Services with a batch file menu

As a follow up to my previous post on Running CF7 and CF8 simultaneously on IIS7 I thought I would share the batch file I use to manage the starting and stopping of the ColdFusion services and some other tips. Note that this mostly Vista specific stuff, including the batch file itself (it uses the 'choice' command which is different in Vista compared to previous versions of Windows).

When running both CF7 and CF8 on the same development machine I generally set all the services to Manual start-up and set only one of the ColdFusion Application Server services to Automatic (Delayed Start). Delayed Start is a new option in Vista that aims to keep your system snappier at boot up, so any services that are set to Delayed Start won't be started immediately during the boot process and will instead execute later when other services have had time to start and finish using time-critical resources.


cf-services


To manage the starting and stopping of the ColdFusion services I wrote a simple batch file that has a menu for selecting which service you want to start or stop. If you save the batch file as User\Documents\scripts\cf.bat it is easy to have quick access to the file by hitting the windows key and typing 'cf.bat'. You can then right click on the file and choose "Run as administrator" so that the process will have permission to start and stop services.


cf-batch-file


When the script is running you will be presented with a simple, straight forward menu.


cf-service-menu


Below is the full script if you would like to use it. It could be customised to add any other services you might want to start and stop such as MS SQL Server, MySQL, PostgreSQL, IIS, Apache, etc. Note: use the "view plain" or "copy to clipboard" links to easily copy the code, paste into Notepad, and save as cf.bat.

Enjoy!


@echo off
REM ColdFusion Services helper batch file, by Justin Carter
REM http://www.madfellas.com
REM 
REM This script is provided as is, with no warranty of any kind.
REM Use at your own risk :)
 
:menu
echo.
echo. 1) Start ColdFusion 8
echo. 2) Stop ColdFusion 8
echo.
echo. 3) Start ColdFusion MX 7
echo. 4) Stop ColdFusion MX 7
echo.
echo. Q) Quit
 
echo.
choice /c 1234Q /n /m " Choose a menu option:"
echo.
 
if Errorlevel 5 goto quit
if Errorlevel 4 goto stopcf7
if Errorlevel 3 goto startcf7
if Errorlevel 2 goto stopcf8
if Errorlevel 1 goto startcf8
goto quit
 
:startcf8
echo.
net start "ColdFusion 8 Application Server"
REM net start "ColdFusion 8 .NET Service"
REM net start "ColdFusion 8 ODBC Agent"
REM net start "ColdFusion 8 ODBC Server"
REM net start "ColdFusion 8 Search Server"
cls
echo.
echo. ColdFusion 8 Services started
echo.
goto menu
 
:stopcf8
echo.
net stop "ColdFusion 8 Application Server"
net stop "ColdFusion 8 .NET Service"
net stop "ColdFusion 8 ODBC Agent"
net stop "ColdFusion 8 ODBC Server"
net stop "ColdFusion 8 Search Server"
cls
echo.
echo. ColdFusion 8 Services stopped.
echo.
goto menu
 
:startcf7
echo.
net start "ColdFusion MX 7 Application Server"
REM net start "ColdFusion MX 7 ODBC Agent"
REM net start "ColdFusion MX 7 ODBC Server"
REM net start "ColdFusion MX 7 Search Server"
cls
echo.
echo. ColdFusion MX 7 Services started.
echo.
goto menu
 
:stopcf7
echo.
net stop "ColdFusion MX 7 Application Server"
net stop "ColdFusion MX 7 ODBC Agent"
net stop "ColdFusion MX 7 ODBC Server"
net stop "ColdFusion MX 7 Search Server"
cls
echo.
echo. ColdFusion MX 7 Services stopped.
echo.
goto menu
 
:quit

Running CF7 and CF8 simultaneously on IIS7

Recently I started work at a new job in London and found myself needing to do some local development with CFMX7 while still keeping my existing CF8 installation available for local development as well. One option — which is what I did initially to get up and running quickly — was to run CFMX7 in stand-alone mode using the built-in web server, but eventually I needed to be able to switch between multiple projects (web roots) easily because I could be working on more than one project at a time.

Since we use IIS in our production environments it makes sense to use it in a development environment as well, rather than playing with Apache or another web server, and I also wanted to keep everything under a single web server instance so that I didn't have to worry about fiddling with port numbers and and multiple web server services. Thankfully IIS7 makes per-web site configuration really easy with it's web.config files, as you will see below.

Installation

I started with an existing CF8 installation that was originally set up to apply to all IIS web sites. I also store all my data on D: and so the the CFIDE and CFDOCS folders for CF8 were initially installed to D:\inetpub\wwwroot.

When it came time to install CF7 I chose to install it in server mode using the built-in web server. This places the CFIDE and CFDOCS folders for CF7 in C:\CFusionMX7\wwwroot, so you won't have to worry about overwriting the CF8 files.

ColdFusion Configuration

To allow IIS to talk to ColdFusion we need to make sure the JRunProxyService isn't deactivated which you can do by editing C:\CFusionMX7\runtime\servers\coldfusion\SERVER-INF\jrun.xml. To do this just follow the first step in the Adobe TechNote titled ColdFusion MX: Manually configuring the web server connector for ColdFusion MX Standalone. This simply changes the deactivated value from true to false. (You can also use this opportunity to deactivate the JRun built-in web server by editing the same flag just above in the WebServer service config).

Next we need to make sure the web connector DLL's and configuration files are available. These files won't have been installed and/or created when we chose to use the built-in web server so we will have to extract and configure them manually. We could follow the rest of the above TechNote to get up and running, but it has been summarised much better (and specifically for IIS7) on page 6 of a Community MX article called Getting ColdFusion MX 7.0.2 Running on Vista and IIS. Following steps 1 to 7 you will extract the IIS related DLL files from C:\CFusionMX7\runtime\lib\wsconfig.jar and create two configuration files to go with them. Give the ColdFusion MX 7 Application Server service a restart now for good measure.

IIS7 Configuration

In IIS Manager create a new web site as you would normally, with a new web root and using host headers to differentiate between web sites (e.g. create the site in D:\inetpub\cfmx7, give it the host header cfmx7.local and edit your hosts file to alias 127.0.0.1 as cfmx7.local).

The new site will be created with the Handler Mappings from the top level web server configuration which will be pointing to the CF8 files (meaning if you were creating a new site using CF8 then it would be ready to go without any configuration). To get this site to work with CF7 we just need to change each of the ColdFusion-related mappings to use the web connector that we just extracted and configured above.

 
IIS7 Handler Mappings for ColdFusion MX 7


Select the newly created site in the site tree, double-click on the Handler Mappings icon, and set the executable for each CF-related mapping to C:\CFusionMX7\runtime\lib\wsconfig\1\jrun_iis6_wildcard.dll. The most important ones will be the wildcard (*), *.cfm(l), *.cfc and *.cfr, though it only takes a few seconds to configure the other 4 or 5 while you're at it.

That should be it, you will now have an IIS7 site running CFMX7! Create a new .cfm file and use <cfdump var="#server#"> to confirm :)

Creating additional CF7 sites

The beauty of IIS7 is that site-specific configuration is written to an XML file in your web root called web.config. This means no more stuffing around with the IIS metabase as in IIS6, and the benefit we get here is that you can keep a copy of this file (like a "template") and then next time you create a new web site that will use CF7, simple copy and paste the file into the web root and you are ready to rock without any additional configuration! This is what my own web.config file looks like:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <handlers>
            <remove name="AboMapperCustom-75808" />
            <remove name="AboMapperCustom-75807" />
            <remove name="AboMapperCustom-75806" />
            <remove name="AboMapperCustom-75805" />
            <remove name="AboMapperCustom-75804" />
            <remove name="AboMapperCustom-75803" />
            <remove name="AboMapperCustom-75802" />
            <remove name="AboMapperCustom-75801" />
            <remove name="AboMapperCustom-75800" />
            <add name="AboMapperCustom-75800" path="*" verb="*" modules="IsapiModule" scriptProcessor="C:\CFusionMX7\runtime\lib\wsconfig\1\jrun_iis6_wildcard.dll" resourceType="Unspecified" requireAccess="None" responseBufferLimit="0" />
            <add name="AboMapperCustom-75801" path="*.jsp" verb="*" modules="IsapiModule" scriptProcessor="C:\CFusionMX7\runtime\lib\wsconfig\1\jrun_iis6_wildcard.dll" resourceType="Unspecified" requireAccess="Script" responseBufferLimit="0" />
            <add name="AboMapperCustom-75802" path="*.jws" verb="*" modules="IsapiModule" scriptProcessor="C:\CFusionMX7\runtime\lib\wsconfig\1\jrun_iis6_wildcard.dll" resourceType="Unspecified" requireAccess="Script" responseBufferLimit="0" />
            <add name="AboMapperCustom-75803" path="*.cfm" verb="*" modules="IsapiModule" scriptProcessor="C:\CFusionMX7\runtime\lib\wsconfig\1\jrun_iis6_wildcard.dll" resourceType="Unspecified" requireAccess="Script" responseBufferLimit="0" />
            <add name="AboMapperCustom-75804" path="*.cfml" verb="*" modules="IsapiModule" scriptProcessor="C:\CFusionMX7\runtime\lib\wsconfig\1\jrun_iis6_wildcard.dll" resourceType="Unspecified" requireAccess="Script" responseBufferLimit="0" />
            <add name="AboMapperCustom-75805" path="*.cfc" verb="*" modules="IsapiModule" scriptProcessor="C:\CFusionMX7\runtime\lib\wsconfig\1\jrun_iis6_wildcard.dll" resourceType="Unspecified" requireAccess="Script" responseBufferLimit="0" />
            <add name="AboMapperCustom-75806" path="*.cfr" verb="*" modules="IsapiModule" scriptProcessor="C:\CFusionMX7\runtime\lib\wsconfig\1\jrun_iis6_wildcard.dll" resourceType="Unspecified" requireAccess="Script" responseBufferLimit="0" />
            <add name="AboMapperCustom-75807" path="*.cfswf" verb="*" modules="IsapiModule" scriptProcessor="C:\CFusionMX7\runtime\lib\wsconfig\1\jrun_iis6_wildcard.dll" resourceType="Unspecified" requireAccess="Script" responseBufferLimit="0" />
            <add name="AboMapperCustom-75808" path="*.mxml" verb="*" modules="IsapiModule" scriptProcessor="C:\CFusionMX7\runtime\lib\wsconfig\1\jrun_iis6_wildcard.dll" resourceType="Unspecified" requireAccess="Script" responseBufferLimit="0" />
        </handlers>
    </system.webServer>
</configuration>


Though I haven't tested it, you could probably use a similar procedure for older releases of CF such as CFMX 6.1, or maybe even future versions such as CF9 ;)

Happy configuring!

Blog redesign, Twittering, OS X and more...

About a week or so ago I gave my blog another redesign :D This time I've gone a bit more minimalist by using just a couple of gradients and some old-school pixelated design elements for the logo and edge of the content area. In my search for an image to go in the header I thought of using the CF logo somehow but didn't quite know what to put with it; then I stumbled on Kai Koenig's "coolest CF t-shirt ever" photo on Flickr featuring the (slightly modified) CF dude from the AIR Launch Party poster by eboy. <boratVoice>Great success!</boratVoice>

Next, I've begun using Twitter on a regular basis now and you can see my last few messages on the madfellas home page or follow me if you're also using Twitter. I'll mostly be twittering about CF and tech related topics with the usual funny web stuff thrown in. At the moment I'm using the TweetDeck client and I'm finding it quite good.

Over the course of the weekend I'll be playing around with setting up my development environment in OS X along with replacements for my frequently used Windows apps. So far everything is going well and the only things I am really missing are a Windows Media Player 11 which I'm replacing with VLC, and Windows Live Writer which I am running (and composing this blog entry with) using VMware Fusion's Unity feature :)


os-x-live-writer


I've also got a few updates to make to ColdExt in regard to user extensions and some other new features to investigate.

And last but not least... I'll finally be starting work in London next week! More on that to follow later ;)

Rolling with a new design, settling in to London life

It's been almost a year since I've given madfellas.com a redesign so I've rolled in a bit of grungy stuff while still keeping a similar colour scheme and layout. I've used a large background image with a gradient on purpose so that I can switch it out easily, at any time, to change the mood of the site. It's not exactly a designer-quality layout, but hey, it's not bad for a nights work :)

We're all settled in to our new place in Shepherds Bush (yes, yes, I know, that's where all the Aussies live!) and have had a relatively quiet week; except for the couple of times we have been to the new Shepherds Bush Westfield shopping centre, that place is nuts!

My girlfriend Monique is finding it a bit tough on the web design job front, even though she has a nice portfolio and plenty of experience. On the CF job front it's pretty quiet too but I'm hoping to get some good news before the end of the week about possible interviews - fingers crossed. We'll see how things go for us in the coming days/weeks.

I'm also off to the UKCFUG tonight which should be cool. It'll be the first CFUG meeting that I've had the opportunity to attend, and hopefully not the last :) Maybe I'll see you there...

More Entries