November 18, 2009

ColdFusion proxy for After the Deadline

I recently switched our CMS spellchecker on PortlandOnline from Google's spellchecker to After the Deadline. After the Deadline is a new breed of spellchecker—likely very different from the spellcheckers you're used to using. AtD offers contextual spell checking so it can detect words that are spelled correctly, but used incorrectly. It also has an advanced style and grammar checker and offers helpful explanations of all the detected issues.

After the Deadline recently became the default spellchecker in Wordpress, and it's also offered as a TinyMCE plugin. However, the TinyMCE plugin requires a server side script to proxy AJAX requests. The only proxy script currently included with the plugin is for PHP so I ported the PHP script to ColdFusion. It's a fairly simple script, but I thought I'd share it so that others don't have to reinvent the wheel. (I did send it to the AtD developers so maybe it will be included in a future release…)

Posted at 11:10 AM | Comments (3)

July 17, 2009

ColdFusion Tip: Query columns in correct order

One quirk in Coldfusion that I've had to battle before is that columns in query objects are sorted in alphabetical order. Normally this isn't too much of an issue because you just output the columns in the desired order when you're displaying the output on a page. But there are times when you need to loop over a list of the columns and you'd like them to appear in the order defined in the SQL query or DB schema.

You can use queryObj.columnList to get a list of query's columns, but as I already mentioned this list is sorted alphabetically. To get a column list in the correct order, use this simple trick:

ArrayToList( queryObj.getColumnNames() )

This method appears to be an undocumented method of the underlying Java query object.

Posted at 10:27 AM | Comments (6)

May 13, 2008

Web standards awareness among CF developers

I've been a ColdFusion web developer now for almost three years. During this time, I've attended two major ColdFusion conferences: CF United in '06 and most recently cf.Objective() of this year. While thinking about the sessions that I attended at cf.Objective() an interesting observation came to me: there doesn't seem to be much talk in the CF community about "web standards." And by web standards I mean things like plain semantic HTML, CSS styling, unobtrusive JavaScript, accessibility, and microformats, etc. Prior to joining the ColdFusion community these topics were all the rage among the various web development blogs I followed. But for some reason they don't seem to get nearly as much attention among the CF bloggers and conference speakers.

I've been thinking about this the last couple of days and have come up with a few possible reasons why there doesn't seem to be much focus on web standards in the CF community:

  1. The majority of CF developers are blissfully ignorant of web standards, or
  2. Since web standards are backend agnostic, CF developers rely on the general web development community for web standards information, or
  3. Now that it's been 6+ years since web standards entered the spotlight, the majority of CF developers are already well acquainted with these concepts and techniques and have already mastered them. Therefore further discussion is not needed, or
  4. Most CF developers are primarily backend coders. They spend their time coding CFCs, business logic, and data models, etc. Someone else does the frontend code for their applications so they aren't directly concerned with web standards.

If you're a ColdFusion programmer, I'd love to hear your thoughts on the issue. Particularly, I'd like to know:

  1. If you fall within one of the groups listed above and if so, which one(s).
  2. On a scale of one to five, what is your level of knowledge and expertise with web standards?
  3. Do you rely on the CF community for the majority of your web standards information/knowledge/training, etc or does it come from the general web development community as a whole?
  4. As a CF programmer, would you be interested in more conference sessions and/or blog articles devoted to web standards?

Please leave me a comment and let me know!

Posted at 8:19 AM | Comments (5)

April 3, 2008

ColdFusion tip: Dynamic column names in ValueList()

Today I discovered that the ValueList() function in ColdFusion only works with a static argument in the form "query.column". So you can't use this function if you need to dynamically determine the column name at runtime. Luckily there is a nice little hack to work around this problem.

The ValueList() function returns a list of values from a particular query column. You can achieve the same result with the following expression:

ArrayToList(query[column])

Posted at 3:41 PM | Comments (9)

April 1, 2008

ColdFusion spellchecker plugin for TinyMCE 3.0

We use TinyMCE as a WYSIWYG editor for our CMS at work. Version 3.0 of TinyMCE was recently released in which most of the application has been rewritten. Because of this rewrite, any plugins written for version 2.x have to be updated to be compatible with version 3.

The main third-party plugin that we use is a spellchecker plugin for ColdFusion servers. Since the plugin hasn't been updated, I took it upon myself to port the PHP spellchecker plugin provided with TinyMCE 3.0 to ColdFusion.

My ColdFusion spellchecker plugin is a complete port of the PHP plugin and supports both the Google spellchecker and Pspell/Aspell engines.

[Download the TinyMCE 3.0 ColdFusion spellchecker plugin]

Posted at 10:33 AM | Comments (16)

February 21, 2008

ColdFusion IsDate() gotcha

I must be a slow learner because I've been bitten by the following gotcha in the ColdFusion IsDate() function more than once. So I'm writing this here mostly for my own sake, but it may be of value to others also.

I've used IsDate() many times in form validation logic to verify that a user entered a valid date into an HTML field. Usually, I need to verify that the input is something like 02/21/2008 or 2-21-08, and this function has saved me from writing a regular expression to validate the correct format.

But it turns out that IsDate() is pretty liberal in it's definition of a "date". According to the ColdFusion documentation, IsDate() returns true "if [the] string can be converted to a date/time value." This means that the following strings are all considered valid dates according to this function:

It's the dd/mm/yyyy format that's caused me trouble before. If I'm expecting a date in mm/dd/yyyy format and IsDate() allows the user to enter 21/02/2008 then strange things start happening in my applications.

My solution is to replace IsDate() with IsValid("USdate", string_value) which will only return true if the string is a valid date in the mm/dd/yy format (with 1-2 digit days and months and 1-4 digit years).

Posted at 3:49 PM | Comments (4)

August 27, 2007

ColdFusion is the next FrontPage

Web professionals around the world rejoiced when Microsoft recently announced that they were discontinuing their infamous FrontPage WYSIWYG web authoring program. FrontPage, which was designed to make web site creation as easy as word processing, was scorned by web professionals due to the non-standard, proprietary Microsoft spaghetti HTML code that it generated. Many people could identify a web site created with FrontPage at first glance and the program and the sites that it created quickly became synonymous with amateur, wannabe web designers.

Unfortunately, the old FrontPage is now being replaced with a new “FrontPage.” Only this time it’s called Adobe ColdFusion 8. With the recent release of version 8, ColdFusion is being trumpeted as the quickest and easiest way to web applications. Sound familiar? Just replace “web application” with “web site” and you’ve got almost identical product slogans. What FrontPage attempted to do for static web sites, ColdFusion is trying to do for dynamic web applications. But this slogan doesn’t necessarily make ColdFusion a bad thing. Let me explain a little bit…

I use ColdFusion every day at work as a web application developer for the City of Portland. And I love ColdFusion because I honestly do believe that it is the quickest and easiest way to build powerful web applications. So when version 8 was recently released I was thrilled to learn about the new Ajax features designed to make building Ajax enabled applications easier than ever before. Having already built a couple of Ajax enabled web apps “the hard way” I was curious to see how well ColdFusion was able to simplify the process.

So after downloading and installing the developer edition on my computer, the first thing I did was experiment with some of the new Ajax features. I was pleasantly surprised to discover that Adobe had fulfilled their promises and kept to the ColdFusion tradition of abstracting typically difficult tasks into dead-simple and easy to use tags. In just a few lines of CFML code I was able to add an Ajax auto suggest text box. With a few more lines of CFML and little ColdFusion component, I was able to create a “live HTML data grid” complete with automatic paging, dynamic on request record loading, and edit-in-place functionality. Not once did I even have to know a thing about JavaScript or how Ajax functionality works—ColdFusion magically took care of all those details behind the scenes for me.

“Wow!” I said to myself as I hit the view source button in my browser, “Let’s see how they did it…”

It was at this point that the music suddenly stopped, the lights began to dim, and the smile quickly faded from my face. I’m a big advocate of standards-based web development and I usually try to create pages that conform to the XHTML Strict doctype. The first thing that I noticed was that while the HTML code that I’d used was valid, there were several validation errors in the ColdFusion generated code.

What’s worse is that they were all simple, easy to fix errors that could have been avoided had the ColdFusion engineers taken a little more pride in their work and taken the time to verify that they were generating valid code. Maybe you don’t think it’s a big deal if there are minor validation errors “so long as the page looks okay and functions correctly.” Here are two reasons why I feel that it is a big deal. First, if you want to serve your XHTML pages as XML documents (as they are supposed to be served) instead of as “text/html”, the page must be valid. Otherwise the browser will just show the user an ugly XML parse error. Second, due to its ease of use, ColdFusion is used by a lot of novice developers. For these users ColdFusion is often their introduction to HTML, CSS, JavaScript, server-side programming, and all of various technologies that go into creating a web application. Do we really want them using the ColdFusion generated code as a learning tool? Adobe should strive to set a good example by following the industry standards and best practices in their code so that developers using it as a learning tool will learn good habits and learn to do things “the right way.”

The next thing I noticed when looking over my page’s source code was that ColdFusion automatically included a bunch of Yahoo YUI and Ext JS JavaScript files based on the specific requirements of the particular CFML tags used on the page. I think it’s great that the ColdFusion engineers chose to take advantage of some of the great open source JavaScript libraries out there. But this brought up an interesting question to my mind. What if a ColdFusion developer wanted to use those same libraries to develop custom JavaScript functionality in their web application? And let’s say for the sake of this example, that not every page on the web site uses one of the CFML tags that automatically includes the JavaScript libraries. The developer would need to ensure that the libraries are included anyway on those pages to support their own custom JavaScript functionality.

So the developer manually hard codes in links to the JavaScript libraries in an application wide template so that they will be included on every page regardless of the CFML tags used on the page. But what happens on the pages that do use the CFML tags that automatically include the JavaScript libraries? Well, it turns out that the libraries get included twice—once by the developer’s template and again by the ColdFusion tags! This is not good! At the very least the browser will make two HTTP requests for each script file, possibly resulting in many redundant requests. (At least the second time the script should get loaded from the browser’s cache). In the worst case scenario, it could potentially cause the scripts not to function property because each one will get run/initialized twice by the browser. Now, how hard could it be for ColdFusion to verify that the JavaScript libraries are not already being included on the page before automatically including them again?

It seems that when it comes to creating a web site, whether it’s a static web site or a dynamic web application, if you want it done right you’ve got to do it yourself. This includes hand coding your HTML and handling the nitty-gritty details of Ajax enhanced web sites. This brought me to the conclusion that ColdFusion is just the next FrontPage. No doubt the new Ajax features will get used and abused by the less knowledgeable developers looking for the quick and easy solution. But smart developers who care about web standards and take pride in creating clean, semantic, valid HTML will do things the way they’ve always done them in the past—by hand. So the next time your tempted to use on of the new ColdFusion features that magically does everything for you, take a look behind the scenes at what’s really going on and evaluate if it’s really the best way to accomplish your task. You may find yourself joining me and doing it the hard way. But at least it will get done the right way!

P.S. Adobe, if you’re listening, it’s not too late! I’d love to be surprised by the next ColdFusion update to discover that you’ve fixed these issues that you’re putting forth an effort set a good example and do things the right way. If so, I promise I’ll never mention ColdFusion and FrontPage in the same sentence again!

Posted at 8:12 PM | Comments (10)

March 9, 2007

Cfoutput group tip

Yesterday I experienced a problem with my first attempt to use the group attribute of the cfoutput tag. I was trying to use multiple nested cfoutput tags with the group attribute to create a table whose rows were grouped together by one column of a query. Within those groups, I wanted to group the rows by a second column value.

The problem I was having was that ColdFusion wasn’t grouping my 2nd level rows like it should. I assumed that cfoutput sorted the query appropriately in order to perform the necessary groupings. What I failed to realize was that you have to manually sort the query with the SQL order by clause.

In other words, any column used in the a cfoutput group attribute must be in the SQL order by clause (in the order that the cfoutput tags are nested).

Here’s a code sample:

<cfquery name="q">
	SELECT Year,Month,Col1,Col2,Col3
	FROM table
	ORDER BY Year,Month
</cfquery>

<cfoutput query="q" group="Year">
	<h3>#Year#</h3>
	<cfoutput group="Month">
		<table border="1">
		<tr>
			<td colspan="3">#Month#</td>
		</tr>
		<tr>
			<td>Col1</td>
			<td>Col2</td>
			<td>col3</td>
		</tr>
		<cfoutput>
			<tr>
				<td>#Col1#</td>
				<td>#Col2#</td>
				<td>#Col3#</td>
			</tr>
		</cfoutput>
		</table>
	</cfoutput>
</cfoutput>

Posted at 10:51 AM | Comments (3)

May 4, 2006

Clearing a cached query in ColdFusion

The ColdFusion cookbook has a couple of recipes for dealing with cached database queries. In theory it's relatively simple. You can instruct ColdFusion to cache a query for a specified amount of time using the cachedWithin attribute of the <cfquery> tag. You can clear a cached query by calling the same query again, but setting the cachedWithin attribute to a past time. But I recently discovered an interesting issue regarding clearing cached queries…

It turns out that not only must the SQL query and <cfquery> attributes be identical (with the exception of the cachedWithin attribute), but both queries must also have identical whitespace formatting. In other words, the following will not work:


<cfquery name="myQry" datasource="myDS"
cachedwithin="#createTimeSpan(0,1,0,0)#">
select *
from users
order by last_name
</cfquery>
<cfquery name="myQry" datasource="myDS"
cachedwithin="#createTimeSpan(0,0,0,-1)#">
select *
from users
order by last_name
</cfquery>
Because the 'clearing' query is indented more than the original query the cached query will not be cleared. So this is one time when whitespace really does matter.

Posted at 2:21 PM

February 8, 2006

Enabling web services over SSL in ColdFusion

I recently ran into a problem while trying to access a web service from within ColdFusion on our new testing server. It took me a while to get it working because the ColdFusion error messages weren’t very descriptive or helpful in pointing me to the cause of the problem. While searching for a solution, I came across a lot of unanswered forum posts from others who appeared to be experiencing the same problem so I thought I’d share my problem and the solution I finally found.

The Problem

The <cfinvoke> tag that I was using to call the web service was returning this error message:
“Could not generate stub objects for web service invocation.”
I tried to use the administrative console to add the web service, and it returned this error message:
“Error creating web service. Please ensure that you have entered a correct Web Service name or URL.”
As I mentioned earlier, neither error message provided me with much insight as I know that there was nothing wrong with the web service itself (or the URL) because it was working fine from our development server. I discovered that I could not manually access the WSDL URL from within a browser due to a firewall restriction. After getting the firewall issue resolved I was still was getting the same error messages. So I began doing Google searches on the error messages. I discovered that these error messages seemed somewhat common, but I couldn’t find any solutions that seemed to apply in my case.

The Solution

Finally I found a link that hinted that ColdFusion could not access any secure URLs (beginning with HTTPS) unless it contained the server’s SSL certificate (or the certificate’s issuer’s certificate) in its certificate store. Bingo! My web service was indeed located at a secure URL and the server’s SSL certificate was issued by an unknown certificate authority. After inserting the certificate authority’s certificate into the key store and restarting ColdFusion, everything magically worked. So how do you import a certificate into the key store? Well, instead of going through the effort to explain that here, I’m just going to point you to a few of the links that helped me figure it out: ColdFusion MX: Configuring Secure SSL Connection with LDAP Directory Server Enabling SSL SSL and the trusted keystore in Java

Update

There is a custom administrator extension named CertMan that allows you to view, add, and delete SSL certificates from within the ColdFusion administrator. This GUI is way more user friendly than using the command line.

Posted at 10:53 AM | Comments (11)