Scriptaculous Droppables Tweak

Scriptaculous has some fairly slick drag and drop facilities built in, though they're clearly targeted at backing some of the other features (like Sortables). I was playing today and noticed the lack of an onUnhover callback corresponding to the onHover method of a Draggable (i.e. a drop-zone). That's not needed for Sortables, but it is if you want to give any sort of visual feedback on hover (like green/red for allowed/disallowed) that needs to be reset at the end of the hover. A quick couple lines to dragdrop.js and bingo: onUnhover Scriptaculous patch.

To use, define an onUnhover callback just like the standard onHover on, excepting that you only get passed the droppable (which is the onHover callback's second parameter).

JavaScript Prompts on IE7

Just ran into an interesting problem with IE7.  It doesn't seem to allow JavaScript prompts without confirming with the user that it should allow them – per page.  I'm not sure what the logic is, but perhaps mitigating certain types of XSS attacks?  Something to watch out for, I guess.

Weird CFLOOP Quirk

I don't use CFLOOP with the condition attribute very much, and when I do, it's usually for simple stuff like a 'while true' loop. However, I ran into a weird quirk today with it, and thought I'd share. Take this code:

[cfloop condition="count LT #config.MAX_IMAGES_PER_IMPORT#">...

Pretty simple, right? As you undoubtedly know, CFLOOP evaluates the condition expression each iteration, so any "static" things can be enclosed in hashes so they're evaluated once (as part of parsing the CFLOOP tag) rather than every iteration. I've done this with the MAX_IMAGES_PER_IMPORT constant.

While I was doing some debugging, I wanted to temporarily truncate imports to a smaller (constant) number, so I did this:

[cfloop condition="count LT #config.MAX_IMAGES_PER_IMPORT / 8#">...

Unlike what you'd expect, this throws a syntax error! Specifically, it's complaining about the slash in there. What's the solution? Change the code to this (move the hashes to use per-iteration evaluation on the expression):

[cfloop condition="count LT #config.MAX_IMAGES_PER_IMPORT# / 8">...

If you're anything like me, a big ol' WTF is probably running through your head. As near as I can surmise, the value of the condition attribute is treated unliked any other string value in CFML. More specifically, variable substitution is performed with hashes, rather than expression evaluation. As my two year old daughter would say "… kinda weird …".

DWR Rules!

I've been using DWR quite a bit on a new Java application, and WOW, it's awesome.  It's not really that different from any other JS remoting toolkit, but it is really slick.  In a nutshell, you declare "remotable" objects (mine happen to be Spring-configured services) along with what methods are remotable, and any complex data types (e.g. beans) that need to be marshalled in an out of the method invocations.  Then you just add a JS file to your page and start calling methods on your remotable objects just as if they were local.  Really slick.

I think what really sells it is the zero-config client usage.  No defining a gateway, no extra methods, just "normal" client-side code.  The only exception is the use of a callback instead of a return variable from methods (so they can run asynchronously), but still very elegant.

I'm a big fan of AJAXing HTML applications on an as-needed basis.  It lets you keep your application in HTML (which is fast to code and easy to maintain), but lets you give certain areas a richer UI, without having to go all one way or the other.  But let me tell you, over the past few weeks I've shifted my thinking and have started building basically static HTML pages and doing everything dynamic with remoting.  Very much the Flex paradigm, but realized in HTML, which is awesome because you can still go with HTML for part of the app.

I know I've not really said much (and managed to spent three paragraphs doing it), but of all the new stuff I've been using on this project, DWR has had the most WOW impact, which is surprising to me since it's band of utility is pretty darn narrow compared to something like Spring or Hibernate.

ColdSpring Presentation

Last night I presented at the Portland CFUG/ASUG about ColdSpring. There were at about 25 people in attendance, both in the room and watching via Breeze. Here's a link to my presentation files, and Sim will be posted them to the PDXCFUG site as well. He'll also put up a link to the Breeze preso (we recorded it) for anyone who missed it live.

All in all, I think the presentation went pretty well. As I started writing it, I realized that there was no way I was going to even do the slightest approximation of justice in just an hour, so I was a bit nervous going in. However, I think I managed to at least get people's eyes open to some of the stuff ColdSpring can do for them, and how it can help you write maintainable applications faster and with less fuss.

ColdSpring at PDXCFUG Tomorrow Night

Tomorrow evening I'll be presenting on ColdSpring for the Portland CFUG/ASUG. Festivities start at 5:30 with pizza and socializing, with the meeting proper starting at 6. In my mind, ColdSpring represents one of the top three events in ColdFusion's world, along with Fusebox 3 (the first "real" CF framework to enjoyed widespread adoption) and the introduction of CFCs (which opened the OO paradigm to CF developers).

In a nutshell, ColdSpring is a ColdFusion port of the core aspects of Java's Spring framework. Like Spring, ColdSpring is an Inversion of Control (IoC) or Dependency Injection (DI) container with an Aspect Oriented Programming (AOP) container built on top of the IoC container. Between these two main facets, it allows you to more easily reach the acme of good OO design: strong cohesion and loose coupling. Spring for Java, just for reference, also supplies a wide array of other services built on top of the core IoC/AOP container, most of which are irrelevant for ColdFusion.

I'll quickly be covering some basics of OO programming, then diving into what ColdSpring is and how to use it effectively, including an introduction to IoC and AOP techniques. I'll also be showing both contrived and real-world examples of how ColdSpring can help you elegantly solve complex problems that nearly every developer faces on nearly every application.

For those of you who can't make it, my presentation and all the supporting code will be made available on the PDXCFUG afterwards.

HotSpot is Hot

I've been doing a lot of Java lately, and (at least at work) moving away from ColdFusion.  I've got mixed feelings about the transition, but that's a different post.  Today I was doing some VERY primitive profiling on the application, and was amazed.

Not surprisingly, the majory of the request processing time went to data access.  We're using Hibernate, and it brings it's own overhead on top of the actual DB.  However, even with some gnarly HQL, it runs reasonably fast.  And as an aside, the Hibernate guys are friggin' nuts.  Turn on debugging some time and trace through the code.  If you don't nearly soil yourself, you're a braver man than I.

Also not surprising was confirmation that ClearSilver is ludicriously fast.  Even doing some pretty complicated multi-part renderings I couldn't get an entire request to spend more than 2-3 milliseconds running the ClearSilver engine.

What was surprising was how good of a job HotSpot does.  I don't claim to understand it's voodoo, but in a nutshell it monitors your Java bytecode as it's executing and optimizes it's execution, including converting the bytecode to native code, compiling it, and then using the compiled version if it thinks it ncessary.  There's a whole pile of things that it does, but that's how it got it's name (it finds the "hot spots" and cools them down).
I was quite demoralized after getting the first full implementation of our rendering engine working when even simple pages were costing 300-400ms each.  Note that "simple" means "a GET for a dynamic, multi-object page", so not really that simple.  But simpler than some gnarly form post.  I went back and made some tweaks to some of the problem areas, restarted Tomcat, and didn't see much improvement.  On a whim, I hit refresh four of five more times, and suddenly the execution times dropped to less than half of what they were.  A smile crossed my face as I thought "I love when technology just magically does the right thing."

I've got to do some checking, but those seven or eight requests that it took for HotSpot to kick in probably comprised several hundred executions of a particular method, so it doesn't take effect right away.  I also suspect that Hibernate will have some hot spots that will eventually be optimized as well, so I'll get even better performance once they're found.

If you're doing profiling (at least on Java), make sure you give your JVM some time to "warm up" and figure out how to best optimize itself.  I know I haven't done that in the past, but I sure will from now on.

Theme Change (Damn IE)

I swear I didn't get this blog back online just to bitch.  That being said, the theme I installed last night apparently doesn't work correctly in IE.  Snippets of text work, but the vast majority just blanks out for some reason.  So I put up one of the other themes that I'd been playing with, and this time I actually went over to Heather's PC and checked it first.

Great Quote

Saw this on Brandon Long's (the author of ClearSilver) sig line:

Don't get suckered in by the comments — they can be terribly misleading. Debug only code.
– Dave Storer

Which isn't to say comments are bad, but they are NOT a replacement for clear, readable code.  Well written code should require very few comments, as it explains itself directly.

Migration is Fun!

Not really. Fortunately, WordPress reads Movable Type exports, which greatly smoothed the moving of blog entries and comments, but that's just the tip of the iceberg. I've also added RewriteRules to automatically redirect from any of the old RSS/Atom feeds to the new feed, so aggregators/feed readers shouldn't have to be updated. All other old URLs just drop you on the homepage.

I've also written my first WordPress plugin and customized another, my first PHP projects ever. Oh. My. God. PHP is horrible. On the plus side, however, shell access is easy and fast, which means a lot of stuff can be done on the shell (like unzipping files) rather than with PHP.

I've also been using Ant for a lot of stuff.  There are seven multi-hosted sites that share the URL-space, but WordPress (at least the non-MU version) is designed with an install-per-blog paradigm.  Keeping seven copies of code is obviously foolish, so I've got a single vendor branch for WordPress in my SVN repo where I make my general tweaks, and then use Ant to apply any per-site tweaks (like layout stuff) as part of generating the actual per-site installation.  That way I only maintain separate copies of stuff where they're different from the other six sites, greatly easing customization.

Finally, FTP sucks.  Such a brittle protocol, even with good tools (I'm using Transmit).  In particular, synchronization and recursive deletion operations are painful.  What I wouldn't give for rsync, but unfortunately no SSH access on the host.  So I've been relegated to zipping the installs locally, uploading the archives, and then unzipping on the server because synchronization never manages to finish without dying.
Things are coming together though, and I've got a whole pile of stuff I want to blog about once I have some free time again.