March 12, 2010

Pages


Search Site


Subscribe

...to receive future posts via email.

Topics



Archives

Entries for month: December 2007

For everyone who *wishes* they could go to CFUnited

December 19 2007 by Adam

Here's something to stick in your sidebar. I added it to mine yesterday.

I wish I was attending CFUnited

Posted in CFUnited | ColdFusion |

Tag wrapping made easy!

December 18 2007 by Adam

The other day I was in a state of head banging frustration while debugging an issue with a component invoked via a CF Gateway that was peppered with calls to the ImageCR CFX, and seemed to be failing at random points for random reasons (though through no fault of ImageCR, it should be noted). My examples will use ImageCR for reference, but this should be a method you can apply to any ColdFusion Tag, Custom Tag, or CFX.

I spent a good hour racking my brain, trying to write a custom tag that would allow me to wrap any code in a try/catch block that would email me a CFDump of the CFCatch struct, like so:

[viewcode] src="cfx_imagecr3_support1.cfm.txt" showsyntax=no geshi=cfm[/viewcode]

This would have made it very easy to wrap any block of code in a try/catch that will email me on error. As it turns out, this isn't possible without some clever use of CFFile and Regex to read the contents of the calling template and locate the block of code between the start and end tag of the custom tag. But I'm sure you're already thinking about how inefficient that would be, especially in my case where there are 20, 30, maybe more instances. And I agree with you.

Then, it hit me like a ton of bricks: Take one step back — just the one tag causing my grief, not a general code block — and write a wrapper for that one tag. And to make things even simpler: Use AttributeCollection! I can pass easily everything sent to my wrapper on to the CFX as an AttributeCollection, without knowing what it is.

So I slammed together a quick wrapper custom tag (File name: "/customtags/wrappers/cfx_imagecr3.cfm") as this:

[viewcode] src="cfx_imagecr3.cfm.txt" showsyntax=no geshi=cfm[/viewcode]

Notice that after I save the contents of my special attributes (trymailto and trysubject), I delete them from the attributes struct. Different tags and CFXes will react differently to unexpected attributes, so it's best not to include them.

After simply importing my new tag wrapper:

[viewcode] src="cfx_imagecr3_support.cfm.txt" showsyntax=no lines=1 geshi=cfm[/viewcode]

This tag:

[viewcode] src="cfx_imagecr3_support.cfm.txt" showsyntax=no lines=2 geshi=cfm[/viewcode]

Becomes this tag:

[viewcode] src="cfx_imagecr3_support.cfm.txt" showsyntax=no lines=3 geshi=cfm[/viewcode]

I can customize the to address and subject of the email per-usage, if I like, and I get an email any time one of them fails.

Posted in ColdFusion |

ModelGlueCookbook Launches!

December 17 2007 by Adam

Todd announced on his blog on December 10th that he was putting together a site called Model-Glue Cookbook, based on the same idea as Ray's ColdFusion Cookbook (and apparently the same codebase), though at the time the domain was parked and there was no content. I've been checking in on the domain a few times a day and this morning there's finally something there to be had! Go check it out!

Posted in ColdFusion | Frameworks |

ColdFusion Guitar Hero (Wii) Players Unite!

December 06 2007 by Adam

Over on ColdFusionCommunity.org, there's a group for Wii owners, and in that group, a thread for folks to share their friend codes. Considering the number of CFers that have been gravitating to the Wii lately, and the fact that almost everyone likes to play Guitar Hero, there ought to be at least a few people out there who would appreciate playing with some familiar names now and then.

So if you play Guitar Hero 3 on your Wii, come on over and get some friend codes for other CF developers. Remember to post yours in the thread, because you can't see your friends online until you've both added each other's codes.

Posted in Community | Games |

cf_rewrite

December 03 2007 by Adam

Over the weekend I was struck with the idea that implementing mod_rewrite behavior in ColdFusion should be easy as pie with a few CGI variables and a couple of lines in Application.cfm. Much to my surprise, it was even easier than I thought! Read on for the code and a demo.

Before getting into the code, it's probably best if you understand how url rewriting works in general. This Wikipedia article explains most of what you need to know, and this page from the Apache2 docs explains how mod_rewrite works in Apache — and more importantly, gives examples.

Update: It's been brought to my attention that the CGI variables will differ depending on whether you're using Apache, IIS, or another server software. It should still be possible and the concepts will be the same, you just may need to adjust the code to fit your environment. My code was developed on CF8 / IIS, and my demo runs on CF5 / IIS.

To accomplish the same thing with CF code, we need 2 pieces of information from the ever-helpful CGI scope: scriptname and pathinfo. Scriptname is everything after the TLD (.com/etc) until the end of the actual script name. Pathinfo contains everything after the TLD, including the query string. The reason we can't just use querystring is that once you convert your URLs to be /in/a/simulated/folder/format, they are not populated into querystring, only into path_info.

So for example, if my URL was http://somesite.com/Vader/isms.cfm?ism=iamyourfather, then CGI.SCRIPTNAME would have the value /Vader/isms.cfm and CGI.PATHINFO would have the value /Vader/isms.cfm?ism=iamyourfather.

For comparison, when using /simulated/folder/format, the URL would be http://somesite.com/Vader/isms.cfm/ism/iamyourfather. In this case, CGI.SCRIPTNAME is still the same: /Vader/isms.cfm, and CGI.PATHINFO is slightly different, but probably what you expect: /Vader/isms.cfm/ism/iamyourfather

Finally, the code!

What we need to do is capture the data from the URL and translate it back into actual URL variables. To do this, simply remove CGI.SCRIPTNAME's value from the beginning of CGI.PATHINFO, as well as what would now be the leading slash; then loop over the remaining value as a slash-delimited list, and assign URL variables with the values from the next list item:

<cfset newQ = right(cgi.path_info, len(cgi.path_info)-len(cgi.script_name)-1) /> <cfif newQ contains "/">     <cfloop from="1" to="#ListLen(newQ, '/')#" step="2" index="e">         <cfset url['#listGetAt(newQ, e, "/")#'] = listGetAt(newQ, e+1, "/") />     </cfloop> </cfif>  

You can see a demo page here, where I've added the above code to my Application.cfm, and the page I'm linking to will dump the URL scope.

This is a fairly simple system of name/value pairs embedded as what I call "simulated folders." It would be fairly simple to setup a more complex system using Regex and your own rules, and this should provide a good base for that. Also note that this system will break if you use an odd number of slashes — for example if you add a trailing slash to the end, or if you use the format 1/2/3, without a value for the variable name you're creating in position 3.

Update (again)!

It bothered me that the code I provided above will throw errors so easily, so I fixed that. Of course, I was lazy and didn't update this post to reflect that, but now that it's been linked by J.J. Merrick, I suppose it would be prudent.

This new code uses the modulus operator to drop off any cases where a name is provided without a value, and thus doesn't throw an error when there are an odd number of tokens in the url string. I've updated the demo to use this code, so check it out here. Notice that the demo now has 3 tokens (Vader, Rules, Dude), but that no errors are thrown and the "dude" variable isn't created.

<cfset newQ = cgi.path_info/> <cfif not len(cgi.path_info) eq len(cgi.script_name)>     <cfset newQ = right(newQ, len(newQ)-len(cgi.script_name)-1) />     <cfif newQ contains "/">         <cfloop from="1" to="#(listLen(newQ, '/') – (listLen(newQ, '/') mod 2))#" step="2" index="q">             <cfset url['#listGetAt(newQ, q, "/")#'] = listGetAt(newQ, q+1, "/")/>         </cfloop>     </cfif> </cfif>

Posted in ColdFusion |