The amazing adventures of Doug Hughes

Archive for October, 2004

Minor Update to the AIC 2 Released

At the end of last week I posted a call for help in reproducing a bug in the Alagad Image Component. In the end no one could reproduce the bug. In the end I found and fixed two bugs and the Image Component. Version 2.11 is now available.

Description of Bug 1:

Files read by the Image Component were permanently locked. The only way to release the lock was to restart ColdFusion or the entire web server.

This was a result of having a <cfreturn> called before the one line of code which released the lock on the file. These lines of code were swapped and the problem went away.

Description of Bug 2:

Sometimes JPEG data was corrupted. In many applications the images would not display or would throw errors. In other applications the colors would appear incorrectly and the image might incorrectly appear to be CMYK

This bug was produced when creating or reading any image with transparency and writing to a JPEG. This is actually not technically a bug in that the JPEG standard allows for an alpha channel. However, almost all implementations of JPEG decoders do not support this. The problem was resolved by removing alpha channels from images before writing JPEG data.

Alagad Image Component Included on Macromedia DRK 9

Macromedia released DevNet Resource Kit 9 (DRK9) today. Included on DRK9 is a ‘lite’ version of the Alagad Image Component. Even the lite version of the AIC packs a punch with over 53 methods for editing images.

Alagad Image Component 2.0 Released

Version 2.0 of the Alagad Image Component was released today. Of particular interest in this release is the ability to control image compression settings. Additionally, there are now nearly 90 methods for working with Image data as well as lots of bug fixes. Check it out at Alagad.com.

Alagad Image Component

I just thought I’d throw out this teaser… Last night I wrote some rudimentary code to control JPEG (and other file format) compression settings with the Alagad Image Component. Watch this blog for more information!

Search Engine Safe URL How-To

A week or so ago I was asked by a reader of my blog to explain how I handle search engine safe URLs on my websites. The process I use is quite simple and has remained more or less unchanged over the last few years.

As you can see on this site my URLs tend to look like this:

http://www.doughughes.net/index.cfm/page-blogLink/entryId-44

The first part of the URL looks just like any other URL. We all know what this does. If not, don’t bother reading any further. However, after the index.cfm things begin to look a little different:

/page-blogLink/entryId-44

What I’ve done is replace the “?” and “&” characters with front slashes. Equal signs are changed to hyphens. This creates a name and value list which we can easily parse. Everything before the first hyphen in each pair indicates the variable name. Everything after the first hyphen indicates the value of the variable.

I’ve seen other solutions which have a format where every other slash indicates a variable and value. This style of URL might look like this:

http://www.somedomain.net/index.cfm/page/blogLink/entryId/44

I’m not a fan of this because it’s a little hard to read and seems like it could cause errors if, for whatever reason, a variable doesn’t have a value. In my example, if the page variable didn’t have a value it would simply look like this:

http://www.somedomain.net/index.cfm/page-/entryId-44

What would the other style look like? How would ColdFusion know what to do? It’s my opinion that my way is a little nicer and more reliable. It’s up to you how you choose to do it.

Another cool thing about these URLs is that, if need be, you can tack additional URL variables in the traditional format like this:

http://www.somedomain.net/index.cfm/page-/entryId-44?anotherVar=anotherVal

I’ve needed this capability in the past and it’s come in quite handy.

If you create any ColdFusion page and format a URL according to the way I defined them above and dump of the CGI.PATH_INFO variable you will see something similar to this:

/index.cfm/page-blogLink/entryId-44

As a note, I’m not sure if using CGI variables is the only option here. It’s the only one I know of. The biggest problem with them is that they’re not consistent between platforms and web servers. For instance, on Apache on Linux CGI.PATH_INFO would have looked like this:

/page-blogLink/entryId-44

On Windows and IIS it looks like this:

/index.cfm/page-blogLink/entryId-44

You may want to use other CGI variables to determine which parts of PATH_INFO contain the variables you want and which parts don’t. For instance, on Windows and IIS there’s a variable CGI.SCRIPT_NAME which holds only the path to the file:

/index.cfm

When I moved this site from Apache to IIS I was a bit confused because on Windows I had an extra variable named “URL.index.cfm” being set to nothing. How odd. A little debugging solved the problem.

Once you’ve isolated the portion of the URL which contains the variable names and values parsing them out is quite simple. All I do is loop over the list of name value pairs and extract them. I then split them apart and set a URL variable to the value provided.

Here’s a complete example:

<!---
Make sure that the CGI.PATH_INFO var is longer than CGI.SCRIPT_NAME + 1.
If not, then we don't have any url variables.
I add one to the length of CGI.SCRIPT_NAME because of the / after the
file path. IE: "/index.cfm/"
--->
<cfif + 1 GT Len(CGI.PATH_INFO) Len(CGI.SCRIPT_NAME)>
    <!--- we have SES URL vars --->
    <cfset urlString=Right(CGI.PATH_INFO, Len(CGI.PATH_INFO) - Len(CGI.SCRIPT_NAME) - 1)/>
    <!---
urlString is now a list of name value pairs (separated by url.seperator).
loop over the list and extract them
--->
    <cfloop delimiters="#arguments.seperator#" index="varAndVal" list="#urlString#">
        <!--- grab the variable name and value --->
        <cfset varName=ListFirst(varAndVal, arguments.equal)/>
        <cfset varValue=ListDeleteAt(varAndVal, 1, arguments.equal)/>
        <!--- set the url variable --->
        <cfset "URL.#varName#"=varValue/>
    </cfloop>
</cfif>

I’ve grouped all of the code above into a CFC which can be downloaded from the attachments section below.

The CFC provides a method parseURL which accepts two arguments, the variable separator and the equals sign. These default to my preferences of “/” and “-” respectively. This allows you to change them to be whatever you want. This could easily be turned into a Mach-II filter too.

(Note: This CFC isn’t as encapsulated as it could be, but it’s simple enough for this example.)

Have fun! Good luck! Don’t come up higher than me on Google!

Search Engine Safe URL CFC

Laszlo – A Free and Open Source Alternative To Flex

I was reading fullasagoog today when I came across an entry comparing Laszlo to Flex.

I had never heard of Laszlo and decided I’d look into it a bit. Laszlo, as it turns out, is a J2EE server which processes an XML language to generate Flash content. Sounds a lot like Flex to me. One major difference: it’s open source. Cool. I haven’t yet played with Laszlo, but it’s now in my radar and I probably will, as soon as I finish the other 10,000 I’m working on. I did take a look at the demos though and they’re very impressive. Honestly, they seem a lot more impressive than some of the Flex examples I’ve seen.

LZX (the markup language) seems pretty straight forward. This is based on snippets of code I saw on the site compared to my recollections of MXML I’ve seen in the past.

One advantage I see to Laszlo is that it’s &quot;free&quot; and open source. I recently read about the &quot;free&quot; Flex licensing, but that seems awfully restricting as what I would want to develop would be intended to make me money in some way or another.

When I finally get to give this a try I’ll be sure to blog about it. Perhaps early next year. Sorry!

Discovering the JavaScript AttachEvent Method

I’m currently working on a 100% new Alagad.com website built around Mach-II. The current site uses WysiPad2 to edit the site’s HTML content. As part of the rewrite I decided to recreate some of that functionality and wrote a CFC to integrate WysiPad into the new site. The CFC has a simple display method which, based on the CFC configuration, will return HTML for displaying WysiPad.

As part of that HTML I wanted to automatically integrate WysiPad as if it were any form element into existing forms. Typically, when adding WysiPad to a form I would have to set the form’s onSubmit attribute to call a JavaScript function which calls the getContent method on the WysiPad2 and places the results into a hidden field which is then submitted as a form element. I wanted to automate that process when I used the CFC. However, I ran into a few minor problems.

First off, the easiest way to add an onSubmit handler is with some JavaScript similar to the following:

document.formName.onsubmit = myFunction()

The problem with this is that it replaces any existing onSubmit handler. This is a problem if you happen to have onSubmit handler on your form for whatever purpose. For instance, if you’re using cfform validation ColdFusion adds its own onSubmit handler.

I played around with several options, but finally was guided towards something I knew, but had forgotten all about (really!): attachEvent.

AttachEvent is an IE only method. The Mozilla equivalent is addEventListener. (Because WysiPad is IE only I’m only blogging about attachEvent.)

My solution ended up being to add some JavaScript which ascended the DOM tree till it found the form element which the CFC generated HTML was contained within. Once I had the form element I called the attachEvent method on it and attached a function call to the onSubmit method.

Here’s the resulting JavaScript:

<script>
addWp2OnSubmitHandler();
function addWp2OnSubmitHandler(){
    // grab the wp object element by Id
    var wp2 = document.getElementById('wp2WysiPad');

    // find the containing form tag
    var parentForm = findParentForm(wp2);

    // attach the wp2GetContent event to the
    // form onsubmit event
    // this does not overwrite any existing events
    parentForm.attachEvent('onsubmit', wp2GetContent);
}

function wp2GetContent(){
    // grab the wp object element by Id
    var wp2 = document.getElementById('wp2WysiPad');

    // grab the hidden text field which will be used
    // to submit the html content
    var wp2FormField = document.getElementById('WysiPad');

    // set the hidden field's content to the wysipad html
    wp2FormField.value = wp2.GetContent(0);
}

function findParentForm(object){
    // check to see if the current object's tag name is "form"
    if(object.tagName.toUpperCase() != 'FORM'){
        // if not, check the parrent element
        return findParentForm(object.parentNode);
    } else {
        // if so, return the object
        return object;
    }
}
</script>

This works quite well. I am pleased. I may some day release a demo of WysiPad implementing Mach-II. Any interest?

Follow up to Bug Found When Looping Over Query In the Application Scope

Last week I blogged about a bug I found in ColdFusion MX when you loop over queries in the application scope. Perversely, the standard behavior of ColdFusion MX is to store the CurrentRow variable in the application scope along with the query. This means that two people looping over the same query in the application scope will run into a race condition.

One of my coworkers has been working with Macromedia support to resolve this issue. According to my coworker (and not to me) Macromedia is developing a HotFix for this issue. To the best of my knowledge this is not yet released. However, my coworker has tested it on the site where we found the problem. At least in the beta of the hot fix the behavior will change somewhat. The following code will continue to be susceptible to the bug:

<cfoutput query="application.myQuery">
#application.myQuery.currentRow#<br>
</cfoutput>

The reason this code will be susceptible to the problem is because it pulls currentRow directly from the application scope. You can think of this as the way to find out the current row in any loop in your site.

However, if you want to find the current row of your loop be sure to only reference it as currentRow as follows:

<cfoutput query="application.myQuery">
#currentRow#<br>
</cfoutput>

After the HotFix is applied currentRow does not exist in any of the standard scopes and exists only in cfoutput and cfloop tags. This is not the behavior in the unpatched version.

So, look for this HotFix on a macromedia.com site near your home.

Firefox Bookmark Keywords Tutorial

Ever wished you could search any site you wanted to without first going to the site, finding the search box, typing in the search? Ever wish you had a quick and easy way to go directly to a word on dictionary.com or thesaurus.com? Ever wish you had something like the Google Bar for any website? Now you can! I just discovered a nifty feature in Firefox called Bookmark Keywords.

What Bookmark Keywords let you do is create a bookmark which you can access by typing a keyword into the address bar. For instance, I might make the keyword “doug” pull up my blog. I addition to that I can create a special bookmark which allows me to use that keyword to search the site by typing something like “doug coldfusion”. That would spawn a search of DougHughes.net for the keyword “coldfusion”. Like most everything in Firefox it’s a hidden feature, but it’s easy to use when you know how.

To create a Bookmark Keywords go to a search results page on any website and add a bookmark. For instance, I went to my blog, ran a search, and bookmarked the search results page. The bookmark ended up being a for this url:

http://www.doughughes.net/index.cfm/page-search?query=coldfusion&Submit=Go%21

After creating the bookmark I open up the properties of the bookmark using the Bookmark Manager. I replace the text which I searched for with “%s” and assign the keyword “doug” to the bookmakr. I used “doug” as the keyword. The “%s” tells Firefox to insert the text you type after the keyword where the “%s” is the URL. My bookmarked URL now looks like this:

http://www.doughughes.net/index.cfm/page-search?query=%s&Submit=Go%21

After saving the updates to my bookmark I can now search DougHughes.net for coldfusion by typing the following into my address bar:

doug coldfusion

Some great uses I’ve found for this are to setup keywords for dictionary.com and thesaurus.com. This lets me easily look up synonyms for “vociferous” quickly and easily or to find the definition of the word “cudgel”.

The one thing I don’t think you can do, which I’d love to be able to, is chain a set of keywords to search across multiple sites and open the results in new tabs. That would allow me to assign the keyword coldfusion to lots of coldfusion sites and I could easily search across all the sites with one query. Ah well, maybe I should suggest that to the Firefox guys. (Hell, maybe you already can do this!)

Here’s a link to some more detailed instructions and where I learned about Firefox keywords.

Tag Cloud