Firefox, IE, and Why Browser Testing is Vital

OK, I made a mistake. I know, my wife will be amazed that I admit that, but it does happen. Testing another developer's code, I missed a critical error. Consider the following bit of code:

view plain print about
1cValue = $("#StartDate").val();
2cMessage += $.trim(StartDate).length == 0 ? "Start date is required.\n" : "";

Do you see it? The conditional, in the ternary operator, should be looking at cValue, but what the developer had intended to rename that variable. There is no StartDate variable in the script, so it should error out as undefined.

And, in Internet Explorer, it does error. StartDate doesn't exist. But, I screwed up. I tested this code in Firefox, and it didn't throw an error, even though that value was empty. You know why? Well, if you put StartDate in the Firebug console, instead of undefined it gives you this:

view plain print about
1<input id="StartDate" type="text" name="StartDate" />

Yes, that's right, because StartDate was an exact case match to the id of an element in the DOM, it returned the actual DOM element (which, by the way, is a valid string with a length).

Now, I'm not going to complain about who's right and who's wrong in this scenario (the value of StartDate), but it does underline the importance of testing in all browsers.

Once Bitten...

ColdFusion UI: cfwindow

Not sure why I forgot to blog this, but a few weeks back Ray Camden told everyone that he wasn't going to tell you to stop using ColdFusion UI tags anymore. Instead, he and Adam Cameron started the ColdFusion UI the Right Way project. This project is a collection of articles and demo assets to show people that you can use other methods for displaying these dynamic client-side "widgets" in your applications, without using the CFUI tags.

Why? Well, it was a nice concept, but honestly (and in my continuing opinion) ColdFusion doesn't need to do UI. Yes, cfoutput, and looping over queries is fine, but tags like <cfform>, <cfpod>, and <cfwindow> are the devil's work. There have been long running issues with letting ColdFusion write your HTML, CSS and JavaScript for you, the chief among them being that they're bloated, buggy, limited, and (ultimately) unnecessary. You have a much finer degree of control over your application, and how it functions, when you write it yourself.

The CFUI tags were provided to allow the lowest common denominator (i.e. someone who can't really write code) to crank out something that works. They are not intended for skilled developers who write web sites and applications for a living.

And so, Rey kicked off the project with an article on replacing <cftootip> with the jQueryUI tooltip plugin, and I wrote the next article on replacing <cfwindow> with Bootstrap's modal plugin. I just checked the repository, and now there are also articles for <cfajaxproxy> and <cfdiv>.

The idea of the project is to show you a) that it's possible to do these things without the CFUI tags, and b) show you examples using a variety of libraries, to reiterate that you aren't limited to a single option.

Build A Better ColdFusion App: Simple Conditionals

In really large apps, every line of processing can become critical. Every small process can add up, in terms of overall overhead. Especially in high traffic apps. Sometimes, the little things can really make a difference. Even your simple code might be...simpler. Take the following example:

view plain print about
1<cfset mySelections = "1">
2<cfif #mine# eq "0">
3    <cfset mySelections = "0">
4</cfif>

I saw something like this in code this morning. Right off, the first thing you see is that all of the variables are unscoped, forcing the server to do a scopeCheck() to find out which scope each variable is a part of. Then there's the unnecessary bits to go along with it, like setting a variable, then checking another to reset the variable based on a condition. There's also the bit where the one variable is unnecessarily hashed. On top of all of that, variable assignments are one of those things it just makes more sense to write in CFScript. Let's take a look at how this might be improved:

view plain print about
1REQUEST.mySelections = (URL.mine) ? 1 : 0;

One line of code. Less keystrokes. Clearer references, and logic.

The "mySelections" variable, in this instance, is a part of the REQUEST scope (I upper case all variable scopes, to make them easier to spot when editing code).

In this situation, "mine" was a URL variable, param'd further up the page. We've used short-circuit boolean logic in our conditional statement. For those that don't understand that, any numeric value other than "0" is evaluated to true. If the value is "0", then it is false.

And speaking of numeric values, you don't need to quote them. Even though ColdFusion would figure it out, a quoted value is a string. Don't quote numeric, and don't quote Booleans.

We use the URL conditional inside of a ternary operator. Ternary operators were introduced in ColdFusion 9. The basics of this are, if the conditional is true, then use the value after the question mark. If the conditional is false, then use the value after the colon.

Finally, there's no need to hash the URL variable. You only need to hash variable references as part of output, or when they are used inside of quotation marks in code.

Now comes the really fun part. There really isn't any need for REQUEST.mySelections at all. Since the value or URL.mine was param'd, further up in the code, then the variable is always available here. Rather than copying that value to another variable (which takes up more memory), we can just reference URL.mine anywhere that REQUEST.mySelections was being used.

As you maintain your applications, it's always good to take some time and read through what's been written before. Refactoring little nuggets like this one, and a little testing, can eventually go a long way in preserving the life of your app and your server.

Out with 2013, and in with 2014

2013 was Exciting! I had several side contracts, which helped us buy a house. We left Jacksonville, and moved back to the Nashville area. I finally put some health issues behind me, allowing me to get out to some user group meetings again, as well as present. I put in a new topic for cf.Objective, which has been accepted. I picked up the camera I've been waiting a decade to buy, and jumped back in to photography with both feet. And, I carved in some time there to review a few books, do a CF Hour interview, and write a few blog posts (some even a little controversial). Now, there's downside here too. Heavy side contract work is not always conducive to a happy home. Buying a house, much less from another state (and the move that goes along with it) can be very grueling and stressful. Working at this kind of pace can bring on other health issues. The financial requirements of buying a house, moving state to state, setting up a new home, etc, make it impossible to do "other things" (like conferences, for instance). And, I still have several other book reviews I've yet to write, and didn't blog nearly as much as I would've liked. Well, you do what you can with what you have, and pray for the best. The two bright points in all of that are my wife, Teresa, and my daughter, Savannah, who continually support this crazed life, and without whom it really wouldn't be worth doing it all. I can never tell them enough how much I Love Them, nor just how much they mean to me. I never got the opportunity to talk about my conversation with Rakshith, concerning the future of ColdFusion. It was a great conversation, focusing quite a bit on Adobe's commitment to the platform, the strides in the education initiatives, and a focus on giving developers the tools (and language) they need to build better products. I think one of the greatest ColdFusion bits, to come out of this past year, was the creation of Team CF Advance. This group, entirely made up of volunteers, is working to produce Open Source applications and API's in ColdFusion. While it is still getting off the ground, the team has already made some pretty big strides. This is the kind of thing that will help bring ColdFusion back out front. I have high hopes, and high expectations, for what is to come from 2014. I've already committed to taking at least one picture a day, gotten seriously started on losing a few (too many) pounds, have several topics laid out for blog series, and am about to put some spit and polish on that preso I mentioned earlier. And that should be just the beginning. So, to all of my friends, colleagues, co-workers, and family, I wish you all the Happiest and most Prosperous of New Years.

What I'd Like To See Come Out of the ColdFusion Summit

So, the very first Adobe ColdFusion Summit is being held this week in Las Vegas, NV. What started out as a small conference, originally capped to 250 participants, is now nearly twice that size, with people coming from all over the world to attend.

We've had a lot of discussions here recently about What's Wrong With ColdFusion, and things that can be done to fix those perceptions. Ultimately, there's been a lot of positive feedback, some reasonable initial response out of Adobe, and a community that's started talking again.

What I'm hoping for is for that discussion to continue, hard, at the Summit. As much as I would like to be there, due to constraints I am unable to attend. So, I'm hoping that the community will come together to ask some hard questions. What really is being done to address the concerns brought up? How does this change current development practice, timeline, and direction? How soon can we expect to see x, y, or z? When, and how, is marketing of ColdFusion going to change?

It's important that we, the community, use this opportunity to speak to some of the engineers. "Why are we doing this? (in this new version) And not doing that?" We have to tell them what we think, and why, to assist in defining new directions. They're always gathering requirements, and you are the perfect focus group. The suits (management types that buy the licenses) can tell them that it should do this or that, but you (the developer) are the ones who truly know the things that are needed.

I know that I've talked a lot about "Adobe" ColdFusion. I am an Adobe Community Professional, so I have to choose my words carefully sometimes. Ultimately, any positive changes are changes that push innovation, competition, and advancement of the platform. In that vain, the Team CF Advance initiative, to write, support, and contribute to Open Source software solutions written with ColdFusion, is one of the single greatest things to come out of our discussion. (Big kudos to Denny Springle [with a side of Corfield], for pulling this idea back out of the hat and getting it up and running) Any time, and assistance, that anyone can give, is a good thing. While we need people to write code, we also need people that can assist with requirements gathering, documentation, and other things. Of all of the suggestions pushed in these discussions, this is the one that we (the developers) can have the most say and control.

Why I Like, and Use, CFScript

Many, many moons ago, I began a journey to learn web development. Actually it was a re-acquaintance, as I had gotten side tracked for a few years in a poor business partnership, having to catch up on how much things had changed. During that time, HTML had moved for v2 to 4, CSS was the crazy new thing replacing font and center tags, Dynamic HTML was making JavaScript hot again, and the browser wars were making life impossible.

Back then I was on the LA Tech Edu JavaScript mailing list (sadly retired, years ago). This guy named Peter Paul Koch was a major contributor to the list, and just ramping up this little site called QuirksMode. Scripting, though somewhat nightmarish with the browser wars, was actually a lot of fun. My first shopping cart was completely JS based.

I have always pushed for full parity between cfscript and tags, because scripting is more natural to me, in terms of writing programmatic logic. Sure, cfoutput and cfloop make a lot of sense in the middle of html display code, but CFC's don't (typically) contain display code, being data access and model objects.

I have issues with the implementation of CFScript. I find that there are a lot of functions of similar actions with completely different naming conventions, and argument requirements, and more. I think these things need to be addressed. That said, if I have to call the function anyway, I prefer script to tags when it's outside of display. It's a more natural approach, to me. 99 times out of 100 I end up with less lines of code, and find the logic more defined, clear cut, and easier to understand.

It's not for everyone. There are many that just plain hate cfscript, and that's their prerogative. But I will continue to use cfscript, and my examples will show that, because I personally find it a better way to write code. If it's not your preference, that's fine, you're welcome to translate my examples to tags if you need to, but for me this is how I do it. (For the record, many of the newer functions are not identical, under the hood [base Java code], as their tag counterparts, and some scripted functions have been proven to have better performance than their tag counterparts. There are benchmarks for this out there, somewhere, if you feel strongly enough to go look for them. I just take it on my experience with using it.)

Build A Better ColdFusion App: When The Var Doesn't Exist

Author's Note: Due to some of the feedback below, I'm going to remove a bit of example regarding paraming objects (see the feedback). Some have actually benchmarked where this creates overhead, rather than improvement of performance, so I'm going to stick with simple variables as this is researched further.

So, let's kick off this round of "Build a Better CF App" with a simple bit of code that you might see quite often in an app:

view plain print about
1<cfif NOT StructKeyExists(FORM, "isactive")>
2    <cfset FORM.isactive = false>
3</cfif>

Simple, right? Probably dozens of these hanging around in your code. Now, let's look at a simpler form, that also gives us the added benefit of type checking.

view plain print about
1<cfscript>
2    param name="FORM.isactive" type="boolean" default=false;
3
</cfscript>

What? Huh? Yeah, this makes sense. See, a checkbox type formfield doesn't actually get passed on form submission if it isn't checked, so chances are you're running this same code, in one way or the other, to default that value for you. Utilizing the param here (cfparam in tag form, but who's using tags outside of display stuff anymore? [hint, hint]) is really the better way of handling this.

  1. You get a default value for the variable
  2. The default is overridden, if the variable actually occurs
  3. If the variable does exist, the param ensures that it is of the proper type
  4. But wait, let's throw in another similar bit of code for good measure. How many times have you seen something like this?:

    view plain print about
    1<cffunction name="getUser" output="false" returntype="User">
    2    <cfargument name="firstName" type="string" required="true">
    3    <cfargument name="lastName" type="string" required="true">
    4
    5    <cfif NOT StructKeyExists(ARGUMENTS, "userID")>
    6        <cfset ARGUMENTS.userID = 0>
    7    </cfif>
    8
    9    <!--- More code --->
    10    <cfreturn LOCAL.User>
    11</cffunction>

    Just doesn't feel right, does it? Especially when ColdFusion already gives us a way to handle this scenario:

    view plain print about
    1public com.mysite.User function getUser (required string firstName, required string lastName, numeric userID=0) {
    2    // More code
    3    return LOCAL.User;
    4}

    You can apply a default value to any argument of a function, utilizing your arguments just as you would a param.

    Now, there may be some valid reason for not paraming a variable, and using conditionals in some way similar to those above. They're few and far between, but there are exceptions to most every rule, so you'll need to evaluate that when the time comes.

New Series: Build A Better ColdFusion App

One common complaint, among opponents of ColdFusion, is the poor code that's out there on the web. I would counter that there's a ton of bad code out there in most any language (I know, I've written some of it), but I do "get it". ColdFusion, as powerful a language as it can be, also has an extremely low barrier of entry. It was created in such a way that anyone who could write HTML could turn around and write an application in ColdFusion (hence the language design decision to use a tag syntax).

Well, just because you can write code in one way, that doesn't necessarily mean that you should. There are thousands upon thousands of blog posts, articles and books out there showing people how to do various things in ColdFusion. Many (not all) are cobbled together rather quickly, offering up functional examples on how to do this or that. And, while awesome that someone bothered to take that time and share that knowledge, they didn't always consider best practices in their examples. After all, it was just a quick example, right? You wouldn't just copy and paste it into your editor. You'd tailor it to your application's needs, right?

Well, no. Many of us have copied some bit of code and just dropped it in without revision. And often it just stays like that, until it causes some sort of issue. To top it all off, chances are you copied and pasted the same bits of code into other areas of your app, or even into new applications, again without revision.

So, I want to start a new series here at Cutter's Crossing. I'm going to call it "Build A Better ColdFusion App", and in each article I want to highlight some small bit of best practice advice, with some code examples that match up accordingly. It won't be a "Tip of the Day" bit or anything, and the articles may come at any time, but they'll all get a common header, and I'll try to group them together so they're easy to find. If you have suggestions for some of these tips, or topic areas you think would be a good fit, please fill out the Contact Form and drop me a note with your suggestions.

By The Way: I'm not perfect. I might put up something and it's hosed too, or you might have suggestions on how to do it differently and/or better. Please, call me on it. We're a community of professionals, and want to put out info of value for any and all.

Are You Running ColdFusion on a Mac?

Yes, Apple is a fantastic company, making really nice products that work very well. If someone gave me one of those nice Macs with the 27" screens today, I'd probably switch. I wouldn't buy one myself. Nice as they are, I can't justify the expense when I can buy a machine twice as powerful for half the money, and actually repair it myself when I need to. But, that's my decision. I choose the imperfections of Windows on a PC architecture as a counter to the affordability and maintainability of the platform. And, it's done really well by me.

I watched Andy Matthews accidentally spill orange juice on to Aaron West's 17" MacBook Pro once, several years ago. Aaron finally got it back from the Mac Store about two weeks later. I can't afford that kind of productivity loss. No thanks.

Again, this is just me. Many others still use a Mac, and love it, and I get it. It's a fantastic operating system, and Apple does make pretty stuff.

But I wouldn't load ColdFusion server on a Mac. Not really. Not on to OS X directly. Yet, I've heard this complaint recently. About how buggy the ColdFusion install is, and what a hassle it is to get up and running.

You're running it on a Mac? On OS X? Why?

The web doesn't run on a Mac. Yes, there are OS X servers, but have you seen that market share? The web runs on *nix and Windows. And, if you're writing code for the web, then your environment needs to match. Load up a VM, and install ColdFusion on the VM, in *nix or Windows. That makes sense.

Is that where you're having trouble? I get CF up in about 20 min on my Windows Server VM, and that includes the download time.

Now, should the ColdFusion server install easily on a Mac? Sure, I think it should. There are way too many developers out there trying to do exactly what I've described, and they're in pain. Go badger the Adobe CF team to get it straight.

But, again, what's your site running on?

You can post comments if you like, but I'm not taking the bait.

What's Wrong With ColdFusion? Round 1 Response

Last week I raised the question, and Wow! Have people responded? Yes. There's some fire in the belly, and a lot of people have a lot of opinions. More importantly, they have a lot of great ideas as well. So, what I'd like to do here for a minute is break down all of that feedback, to get down to the meat. We've attracted some attention, with our little discussion, so I think it's important to focus on all of the core points. From there? Good question. People are listening. Maybe we help to blaze a new trail in the wilderness.

Make It Better

First and foremost, there was an overwhelming call to "get with the times". Among complaints about stability, setup, and pricing, the key take away was that the server needs some retooling. Smarter people than me have talked about the pitfalls of CF running as a servlet, issues with context roots, and (continuing) issues with object instantiation, and all of these things should be addressed. Take that feedback and couple it with the two largest suggestions in the bunch: Modular feature deployment/package bundling and management, and a Command Line Interface (for multiple reasons).

A modular approach can absolutely open a lot of doors, both for developers and Adobe. It can allow someone to deploy a server with only what they require for their application, or upgrade that server's capabilities as required as well. These cut out the cruft, allow the system to be smaller/faster/better, and possibly provides a new (and ultimately more profitable) way for Adobe to handle the licensing of their product. Strip 'er down to her core, then provide deployment packages for things like cfform, orm, office and exchange integration, etc. This modularity also would allow Adobe to laser focus on updates to key areas in a more timely fashion as well (like bringing SharePoint or Exchange support up to the current version in a productive way, etc).

As a broader part of that picture, many asked for the removal of features (UI cruft, cfform, all tags, etc). This isn't really practical, considering the thousands of applications running and supported on ColdFusion today. Adobe needs that licensing revenue. That said, the revenue goes away if they (insert business names here) start switching languages. This modular approach opens new licensing models, better tailored to larger business (and developer) needs, and can address key concerns on the cost of scale. The comparison to the current cloud offerings are a prime example of how this model could truly be a more effective tool for everyone.

The next major suggestions all revolved around core language improvements. The tag model does have it's place, especially with the templating aspects of ColdFusion (generating output), but CFScript, and associated core "functions", require some overhaul. There's a lot of inconsistency in naming conventions, argument order and treatment, lack of member functions, core output, etc., and there's some serious call to correct that. CFScript should be more ECMAScript compliant, and Adobe already has serious experience with this with their development of ActionScript. How they do all of that, and maintain backwards compatibility at the same time, is a question for folks smarter than me, but it absolutely makes sense. Working in ColdFusion should feel native to anyone who writes HTML, CSS, and JavaScript for a living, and right now it's a little off the rails there, especially when it comes to script.

True Issues To Address

Aside from the suggested improvements, there was a lot of conversation about things that truly are broken, and require attention. I'm not just talking about the list of bugs in the bugbase, but some core process issues. Adobe ColdFusion is a paid product, and that licensing includes "enterprise" support. As such, a common complaint is that the support is unknowing, uncaring, or unresponsive. When I call in for support on install issues with Creative Cloud, I was able to get quick and solid resolution, and follow-up. Why should ColdFusion be any different? And why, when a true issue is brought up (like some of the recent security issues), should it take weeks and months to admit the problem, allocate resources, and write/test/deploy fixes?

I, and everyone else, understand that ColdFusion server development is a closed ecosystem, being that it is a corporate product. It does not have the benefit of rapid development that an Open Source project might have, with a large community behind it. That said, considering the costs involved in licensing the product, the turnaround model on identified issues actually ranks a higher priority. How you interact and respond to your customers is critical. This is just business sense, as the customer you keep happy is the one that you retain and keeps buying your product (and tells others how awesome it is).

The other addressable issue, brought up in the conversation, is marketing and education. ColdFusion isn't being taught (or it is, but very little), and new developers aren't coming in to the fold. Some of this is marketing, some of this is perception, and some of this is ... Well, what is it? Why isn't every high school and college in America (or the world) given licensing for ColdFusion? Not ed licensing to dev on, but actually running their university sites, and student unions and such? Why aren't there coding challenges being sponsored in classrooms, to help create the next round of rockstar open source applications? And why aren't there timely, up-to-date, curriculums being developed for these markets? Materials that help teach the language, with focus not only on the language and the server but also development as a whole and best practice?

OK, so all of these "issues" require resources, in an age when things have been scaling down. We've identified them as issues. We've identified their importance. Now it's up to someone to decide the value of addressing those issues.

Where's Our Community?

ColdFusion has, for me, always been a great community. There are hundreds of developers out there who have worked at this stuff for a long time, tripped over good code and bad, and attempted to provide their own brand of support through blogging and answering StackOverflow questions, and just sharing in general. They've done these things, usually, on their own time, with their own money, and at the sacrifice of other things.

But, it's easy to fall off that wagon when you're trying to help others and someone else just tells you "you're doing it wrong". A great case in point here is the OO debate: should you or shouldn't you. First, I'll say "yes, you should", for a thousand little reasons, but then I'll also say "you don't have to, but you should." Second, I'll say that there's no one way to approach development, and that each approach provides it's own pluses and minuses. The single greatest thing that you can do, as a developer, is to read other peoples' code, and realize that it might not be the best approach, or that it might be a much better approach. Each of us has something to learn from someone else, as each of us has a different perspective. Yes, sometimes that perspective may be wrong, and it's good for us as a community to police one another, in our examples, to help promote better code. It's how we have those conversations that will change us. "This Sucks," is not a productive response. Sure, I hate getting called out on my crap code, and then I learn from it (thanks Ray ;) ) [For the record, go read the code for FW/1. Outstanding! The things I learn from Sean...]

The other side to that coin is the framework debate. We have a lot of "mine's bigger than yours" going on, still. The thing is, these are tools, each of them written differently and from different points of view, and if all of these framework developers were to collaborate, instead of pulling out the yard stick, we could really move mountains. You people are smart, and you're dedicated, and you have great ideas. Please work with each other instead of against one another.

And this comes down to the final area of discussion, in round 1, and that's our community's willingness to share their work. There are many people out there that write thousands upon thousands of lines of fantastic code that never sees the light of day outside of a firewall. One great comment I saw said something like "What if every CF project were out there and you could just drop it in and it almost worked?" How many user management modules have you written? Permissions systems? Rudimentary document management? Can't you put anything on GitHub? RIAForge? Every small bit of code we contribute, as a community, adds to the overall ecosystem. We have to start helping each other solve common problems. These other communities, that so many developers are turning to? That's what they've been doing right. And that's where we, as a community, have been failing. There were a lot of fingers pointed toward Adobe, in the comments to my post, but I'll remind you that every pointing hand has three fingers pointed back. We have brought a good bit of this upon ourselves as well, and only we can change that.

I, for one, do not think the battle is over. I, for one, still think there's a life for ColdFusion and ColdFusion development. Yesterday Matt Gifford and Scott Stroz and I sat down for the CFHour podcast, and Scott said "If JavaScript can have such a resurgence, then why can't ColdFusion?" And he's right.

So, this recaps (very high level) all of the comments on my last post. The discussion has begun, now where do we take it? Can we define a path for ColdFusion's future? Is Adobe part of that discussion? (I hope that they are) I would like to hear from you again, dear reader. What are your thoughts on what's being said today? Throw out the negative, focus on solutions, and tell me what you believe can/could/should be done for us, as a community, to move forward and thrive.

More Entries