The Dopefly Tech Blog

« The Dopefly Tech Blog Main page

Should CFML have first class properties?

posted under category: ColdFusion on December 3, 2009 by Nathan

C# was the first mainstream programming language, to my knowledge, that had full language support for properties, phasing out getters and setters (accessors and mutators). The idea is simple. Here is a property:

public String Name;

This gives your object a public property that can be read and written. The process is similar in Java and ColdFusion, but when the time comes to add functionality to Name, such as calculate the value on the fly, or invalidate a cache when the value changes like I do in Pagination.cfc, you have to graduate this into a getter and setter. In C#, you just have to change the property, keeping your object's interface safe:

private String _Name;
public String Name {
get {
// some code
return _Name;
set {
// some code
_Name = value;

Properties inherit simplicity when compared to the standard getter and setter. They give you less typing and fewer interface changes.

It can actually go deeper than that, with property change event listeners and more.

In the Java world, this properties debate has raged for years, and there are opponents and proponents, both shouting angry words at the other side (they call it the JCP). I think it will never happen, Java is a mountain: basically immobile, without an act of God. CFML is a rocket, in comparison. Allaire / Macromedia / Adobe have pushed CFML hard, keeping it current. Much more so with the latest release and the CFML Scripting enhancements.

Adobe ColdFusion 9, which came out a few months ago, blessed us with near magical getter and setter generation, but I wonder if that is not enough. With this feature in place, is it now too late to move the language toward properties? I suppose this becomes a question for (or your potential answers for) the CFML Advisory Committee: how could it be implemented in CFML, the ColdFusion way?

(Discuss with Disqus!)

Thoughts on code regeneration - patterns for customizing

posted under category: ColdFusion on November 24, 2009 by Nathan

Since Mark Mandel gave his transfer presentation to the AZCFUG last June, I've been contemplating the different ways there are to work with and customize generated code, and especially re-generated code. Here are some patterns I have recognized. Please read and add your own in the comments.

Generic Scaffolding
Something I've said ColdFusion has needed for years, and we're still not there, standard scaffolding creates the model, view and controller on a single database table (not usually much more complicated than that). From there, you have to edit the HTML to make it match your UI, and edit everything else to do what you need it to do. It's rarely correct out of the box. When your database structure changes, you either have to regenerate and reapply your changes, or apply the DB changes to all of your layers by hand.

Styled Scaffolding
If your UI is clean, and the scaffolded UI code (the HTML) is as well, leave the output as is and just style it with CSS. Wrap your own layout around it and you're set. This only accounts for basic changes that you would make.

Transformed Scaffolding
To account for bigger changes, like changing form field types or turning a form into a wizard, you could try running a transformation on the scaffolded output. This works by making a tool that will change the original structure on command, for example string operations on code. It's doable, and I've done it. It works, in a pinch, but it tends to be more work than it is worth. If you end up physically injecting code into an object, there are better ways to go.

Extended Injected Stubs
Extend the generated code with your own objects (or inline includes for HTML). Replace calls to the generated code with calls to your code. It's kind of a make-or-fake-your-own-stub strategy.

Pre-generated Stubs
The Reactor ORM has a neat trick. Reactor generates stub classes that extended the framework's real generated classes. These empty stubs are placed in your playground to put in any code you want, while the tabe definition heavy lifting classes are saved inside Reactor's core file structure. Reactor can then manage the ORM while your stub files are safe. This strategy can work for you, too, except for the two big downsides that ultimately killed* Reactor: folders with potentially huge numbers of generated files and the unweildy nested object structure. CF 6 and 7 especially have trouble keeping performance with the inheritance tree, which, from memory, looks something like:

* No, it's not dead, but had a little bad press and it was hurt bad enough to end up on the outside.

injected Stubs
Mark Mandel's Transfer also generates files and saves them in the internal structure of the framework, but instead of generating a stub, you can configure it to make an arbitrary object of your own the stub. Transfer then injects its generated code into your class, making your inheritance tree very one-dimensional.

(Discuss with Disqus!)

How to get Adobe ColdFusion for FREE

posted under category: ColdFusion on November 12, 2009 by Nathan

There's always all this talk about how ColdFusion costs so much more than the competition. This has of course been debated and debunked, but still, the truth is, ColdFusion still does cost, whether we're talking about the US$1300 standard version or the US$7500 enterprise version, that's real money that you don't always have to pay. I've got two methods that will give it to you for free, and three methods that will show you how to get it for a severe discount.

Free #1- Visit, download a trial version, install it. When it asks for a serial number, tell it to install the developer version. This is literally everything that the $7500 enterprise version has, yours free forever, no license problems, no hidden fees. The only downside is it's limited to IP addresses - the local computer (for development) and 2 or 3 others for development and testing.

Free #2- Hang out at your local Adobe sponsored user group (CFUGs especially). Twice a year, they give out a software package from Adobe, anything they have for up to around US$2000. You can get your free copy of ColdFusion just by being lucky or entering whatever contests they have. This is actually more viable than it may seem. A few years ago, I won this. Months later, I brought my dad to the group and he won. Oh, and since you'll be there, take time to meet interesting people and learn some CFML.

Cheap #1- Maybe you knew this and maybe you didn't, but you really don't have to buy ColdFusion to run a web site with it. $20 or so a month will give you a great generic hosting account. Develop CF locally for free, deploy remotely for cheap, it's an easy win. Also, these hosted servers usually score the expensive enterprise version, so you can even use those cool advanced features.

Cheap #2- If you do go and buy your own copy of ColdFusion Server, you may not know about the changes to the EULA, or License Agreement, since ColdFusion 9. If you buy just one copy of the server software, that grants you the ability to use that license to install on development, testing and staging servers. That's like 4-for-1, a savings of US$3900!

Cheap #3- If you go all out and buy that US$7500 enterprise license, and there are some good reasons to do that, consider deploying to a cloud environment like Amazon EC2 or the like, because you can deploy your enterprise CF copy on 10 cloud servers. That's a savings of US$67,500! It sure does give you more incentive to try out load balancing and the new multi-server configuration tools that ship with CF9.

(Discuss with Disqus!)

Should You Go 64 Bit?

posted under category: General on November 6, 2009 by Nathan

In case you have trouble deciding if a 64 bit operating system is right for you, I give you Should I Go 64 Bit? which should finish the argument once and for all.

If you buy the upgrade to Windows 7 (which you should), you will be forced to choose - it comes with 2 DVDs, one for a 32 bit install, and one for 64 bits.

Should I Go 64 Bit? is the quick and dirty answer.

The long answer is more complicated, but I have boiled it down to your computer, if you have 2GB of memory and a 64 bit CPU, take the plunge. The only 2 caveats you may have will be software compatibility (if you have any 16 bit software, it will no longer run in Windows 7 64 bit), and hardware driver compatibility. Chances are, if your hardware is so old as to not work with Windows 7, you need to upgrade anyway, and if your software is so old, you can always virtualize.

(Discuss with Disqus!)

A few miscellaneous upkeep things

posted under category: General on September 15, 2009 by Nathan

First up, Twitter. Follow me: @nathanstrutz.

Second, Facebook: Friend me: nathan.strutz.

I guess you could have figured that out, though, if you visited Hi, I'm Nathan Strutz. Hi.Im is very cool.

Finally, MAX. I couldn't talk Boeing into sending me to the annual Adobe MAX conference. I'm not sure I will ever get them to send me anywhere. There is a chance I could hit a conference if I'm a speaker, so I'll be coming up with some kind of presentation that people would like, and maybe try out for a few next year.

There is, however, the Adobe Community Summit, which is held Sunday, October 4th, right before MAX. With the price so very right (free), and the location close enough (L.A.), I'm sure I can get there.

This ACS day happens to run only a week after I bring the family home from 10 days in Alaska. We've got a lot of friends and family to visit, wish us luck with 4 kids on a 6 hour plane ride.

Anyways, if you're an Adobe ACE or UGM, and will be in L.A. in October, make sure to meet me at Community Summit day!

(Discuss with Disqus!)

August 2009 AZCFUG Meeting

posted under category: AZCFUG on August 26, 2009 by Nathan

I always forget to blog. There's a quickly growing list of things I have to update every month when we have a new Phoenix ColdFusion User's Group meeting. I did pretty good except for the blog. You see, I have to update...

The AZCFUG Site - It was so out of date, Alan finally replaced the text with some boilerplate stuff and links to our other sites. Some day, we'll have real content here.

AZCFUG on Adobe Groups - We are using this because it's a pretty nice app, and does everything we wanted, but we hate the extra-long URL. - I update our schedule here via a shared Google Calendar.

My status on Twitter - just to pimp the event.

This Blog - which I was just saying I forget about far too often.

Then, if it's a particularly exciting meeting, I may also advertise it on various mailing lists, etc.

Anyways, sorry, where was I?

Oh man, tonight, Sean Corfield presenting Railo. I'm really excited to see what's in this new version and what's coming next. It's tonight at the UAT building in Tempe, AZ. If you're not in the area, you can tune in at 6:30 PM PST via Adobe Connect.

(Discuss with Disqus!)

IE6 No More applied to my web site

posted under category: Standards on August 5, 2009 by Nathan

Here's just a note to mention that I put the IE6 No More banner on my web site. It was dead simple, dropped it right into the top of my layout and it shows up on every page. If you have a web site, I recommend you do it too!

(Discuss with Disqus!)

Less CSS - how CSS should have been!

posted under category: Standards on July 25, 2009 by Nathan

Has anyone else seen Less - Leaner CSS? Let me sum it up for you. It goes like this:


And you can take that one to the bank.

Seriously though, Less is an app built in Ruby that lets you write CSS in a reasonable fashion, which it will compile into unreasonable standard CSS.

And what is reasonable for CSS? Where is it that the W3C has failed us so terribly? Less' feature set says it all: variables, mixins, nested rules and operations. You'll probably have to see it to believe it, but once you see it, you'll get it. Go ahead, visit the Less CSS site, just the home page shows you everything.

My only problem with it is that it's Ruby. I don't have anything in particular against Ruby, I just don't want to install it or figure out how to use it to start coding with Less.

So where does that leave me?

1) Rewrite it in a language I like more
2) Suck it up, use Ruby
3) Recompile it with jRuby
4) Run it with HotRuby (translate into Javascript)

Until then, I guess I will just be dreaming about it.

(Discuss with Disqus!)

I got the iPhone

posted under category: Life Events on July 23, 2009 by Nathan

Last month before our AZCFUG meeting, we (the UGMs and ACEs of the Phoenix area) were hanging out with Ryan Stewart (who has an adobe go link now) at Four Peaks Brewery. It became quickly obvious that only Rob Brooks-Bilson (who has his own wikipedia entry) and myself were on dumbphones. Rob picked up his iPhone that following weekend. I held out for 2 more weeks (hey, we had a baby, cut me some slack). My wife & I had planned to upgrade to something, I was leaning towards Android, but, thanks to HTC's mediocre Android devices and my employer's fantastic corporate rates with AT&T, we switched and I got an iPhone 3GS.

I've had it for a couple weeks now, and I've got to say, wow. This thing is great. Really. Everyone should have one. From the seamless phone and ipod controls to the connectivity and web browsing abilities, to the apps and games available, it's been really, really fantastic.

One thing I like the most is that it's easily a hundred devices in one. With nothing added, it's a great phone, navigation system, media player, web browser, PIM and camera. That's just brushing the surface, and of course doesn't cover the thousands of apps you can download, many for free.

Case in point: This last weekend we wanted to play mini-golf with the fam. Alanda (my wife) found an indoor place in North Phoenix - 113 is hot enough to stay indoors! Using the camera and Facebook app, I dropped an adorable picture of Aubri (1 yr, our 3rd child) owning the course. From there, we wanted food. Thanks to the iPhone, we were at in-n-out burger in 5 minutes. Finally, we had to get back to Alanda's Dad's camp trailer. Thanks to the map, we saved at least 20 minutes of driving. As we wound through Fountain Hills, I showed Alanda the Zillow application. She was having so much fun as it showed her the estimated prices of all the houses we drove by, live, as the app tracked us on a map with the iPhone's GPS.

I was especially impressed with how I could buy the device and never need to plug it in to a computer. You can download music, podcasts, movies, apps, games, everything without even owning a PC to plug it into. You'll probably want to, but you don't have to this time. This is in contrast to how my iPod Video was simply a sattelite of the media in iTunes on my desktop.

Repeated conclusion: Everybody should have one. Really.

(Discuss with Disqus!)

The Easy Super-Bean

posted under category: ColdFusion on June 9, 2009 by Nathan

With CF being OO enough, beans can have a super-type, a common base that all beans share, like genetics for business objects. It's easy to make one.

<cfcomponent extends="superbean">
But what do we put in there?

My biggest hatred about beans is the getters and setters. It's a lot of typing. If you have snippets, that helps. If you have a bean generator, that's better. It's also a big problem if you have to change them (think: adding logging, validation, etc.), or worse re-generate after you've added custom code. So the way to fix the whole lot of these is employing ColdFusion 8's OnMissingMethod.

I know we've seen it before. My favorite probably comes from Kevin Roche's Abstract Object post. That's basically what I'm playing with.

In my playing around, I've got a base bean with an onMissingMethod defined that will catch getters and setters. Here's an illustration:

Illustration of bean hierarchy - generic base bean with concrete type

The _genericGet() and _genericSet() methods were added so that any extending bean can, say, overwrite just the setter for all the properties in a bean or a parent type of another bean. In fact, I would recommend that overriding coders "decorate" the _generic methods, calling the super-action before or after any custom operations.

Benefits of this design, other than the obvious lack of need to type getters and setters, is that the concrete bean can hold any property, plus, I can rename the getters and setters to obj.Name("Nathan").name(); which would return Nathan - somewhat of a jQuery style trick. Another cool thing is that if you wanted to create your own getter or setter for a property, the _generic methods will search for your function and call that instead.

To illustrate:

(in component user, extends BasicGenericBean)
function getName(){return "Bob"}

(Outside, calling methods on the object)
user.getName(); // returns Bob

Also, I added an init() constructor method that will populate the bean's properties with any arguments passed in.

Taking the design further, I wanted to let the developer specify what properties the bean has via the cfproperty tag.

<cfcomponent extends="GenericBean">
<cfproperty name="Name" type="string" />

user.setNumberOfGoats(16); // throws error: NumberOfGoats does not exist in User.

Then, I thought about adding some optional subtypes for the generic bean. What if I want to track the history of changes to the bean, so it would be easier to do a database update? What if I wanted to put the database update right in there, in a very generic way? This is completely possible.

Illustration of bean hierarchy - base bean, history tracking bean, database enabled bean, with concrete types

So there's my design, something to play with at least, and maybe base your model on too. Download the files all together in 1 zip with some test front-ends just to see them in action. CF8+ only! Download Nathan's Super Beans.

(Discuss with Disqus!)

Where is the ColdFusion+Java application model?

posted under category: ColdFusion on June 6, 2009 by Nathan

What happened to the early days of using Java as the model for a ColdFusion-based MVC application? We used to talk all about CF w/Java but I don't hear it anymore. At best, it's rare. I like to keep my ear to the ground in the CF world, and this one has quietly slipped off the radar.

I guess there are only a few likely demises:

  1. The buzz has faded and we all forgot about it
  2. It's being used everywhere and no one talks about it anymore because it bores us
  3. Java is too hard to write for the average CF programmer
  4. The integration is too bothersome, the gain is not worth overcoming
Regardless, it probably comes down to the fact that some shops have done it, and are now quiet about it, the rest ignore it completely. So in order to spur on the conversation a little, to see what went wrong, see if it's worthwhile anymore, and dream about what it could be, let's think for a bit...

OO ruined my business
A good amout of the conversation lately has been that OO is too hard and CF's implimentation of it is too awful to use realistically. I don't actually think so, but it does limit us some. Hal Helms's main argument is that the computation costs of instantiating CFCs is too great, and I agree, it slows down after a few dozen objects, and crawls after a few thousand. Multiply times 5 if you have execution time debugging on. Obviously Java's implementation of objects doesn't have this issue, especially with POJOs, the simpler the better.

So what if the solution to Hal's problem is partially using Java? Even if it's just for those objects that we might create thousands of instances of, the improvement could be huge.

That's possible today, but it's not as simple as we need it to be.

We know that in CF, createObject("component","com.myCFC") will make ColdFusion to check a variety of locations for that object. First one it finds, wins. What if you could just create a .java or .class file and call it in the exact way you call a cfc using CF's smart path finding senses. I'm honestly surprised that we can't do this yet. For me, personally, this would quickly and easily bridge MOST of the gap.

The problem actually runs much deeper even. Say I want to use my CFCs to run queries. I don't want to hunt down JDBC drivers. I don't want to script my sql calls. I don't want to worry about a thread pool and persistent connections. I don't want to work too hard. I just want to say <cfquery>select * from my_table</cfquery> and have it work every time. CFQuery is and always has been the killer feature of ColdFusion.

So I like my data access layer in CF, but maybe I want my services or beans or what have you in Java, for speed. I want to call myService.getMyData(). The service calls a cfc to get the data, then populates a bean or returns a query or whatever. Problem is, Java can't call methods on a CFC! No, I'm not kidding. Try it. Oh, and yes, I know about the cfc gateway, an asynchronous method for Java to call CF - and no, that doesn't count. Yes it's great and powerful, but that's just not it.

So it looks like the only way to truly integrate Java into our CFC model is to either replace, package-by-package, entire areas of your model-or the entire model-, or only provide one-way objects, that is, Java objects that will never need to call a CFC or anything in CF at all.

Replacing your model is doable for some shops, especially with large Java teams, and is probably indispensable for a handful of them. For the rest of us, we just love our precious cfquery! I think the real heros in this space seem to be Barney Boisvert, who is always blogging about integration with hibernate and groovy, and Mark Mandel with his JavaLoader project.

The one-way objects may work pretty well, but then we've got the classpath and instantiation annoyance still.

The way I see it, integrating Java with your CFC back-end is broken, and it's going to take a lot of "brilliant" (yes, a dig at Adobe marketing) to make it work.

(Discuss with Disqus!)

Microsoft is on fire

posted under category: General on June 4, 2009 by Nathan

Somehow, Microsoft is the new hotness, hitting nearly every shot they throw out there. According to my favorite game (well, from 1994) NBA Jam, the're on fire.

Windows 7
It's Vista. It just is. It took like a year for them to make it, which is nothing in comparison to Vista's decade dev cycle. They didn't re-do anything, and it's not faster, but the fact is, it's what people want, and they're loving it. The only negative things I've heard are from those who are trying to run it on their macs. Hah!

Stealing, err, rebranding basically everything from Live Search, Microsoft comes through with a word that people like ("Let me Live Search that for you") and a searching experience that, for some unknowable reason, people like. Google may have the first competition since destorying Yahoo all those years ago. Personally, I'm not convinced, but people are talking.

.NET becoming superior
The programmers have been the core of Microsoft for a long time, but it wasn't until the recent .NET framework 3.5 (and service pack 1) that they gave them Linq and MVC. These tools are finally something on par and superior to the competing Java platform. The quick movement of both C# and VB.NET have thrown these languages much closer to the top of the "cool" stack.

XBOX 360
Ok, second to Nintendo's invincible Wii is a fantastic place to be. The recent exclusive content is a real winner, and the games are head and shoulders above anything from Sony, aside perhaps from Little Big Planet. Further, their just-announced Natal project, which essentially gives you the Minority Report interface for your TV, is just, well, "Ka-boom" (in my best NBA Jam announcer voice).

Of course Microsoft has a number of smaller successes, things that have really started to go right but aren't as big. The XBOX update with mii-like avatars, Netflix on the XBOX and Media Center, and the re-invigoration of the browser war, giving us IE8, which, if nothing else, sucks less than IE7 and 6.

That doesn't mean everything they do is the bomb. I'm not about to go out and buy a Zune or a Windows Mobile phone, I'm just making observations.

(Discuss with Disqus!)

Calling functions with a dynamic name

posted under category: ColdFusion on May 28, 2009 by Nathan

For a while now, the CF community has been stumbling around the concept of calling a dynamic function. Well, as it turns out, ColdFusion is more functional that it may seem on the surface. Let’s have some fun with what, at first, seems like a difficult problem.

Let’s say we have a method that receives the name of another method as an argument: myStaticFunction("myDynamicFunction"). Now what? First, here’s the methods (I haven’t checked any of this, so let’s call it pseudo-code.

function myDynamicFunction(){return true;}

function myStaticFunction(methodName) {
    methodName(); // fails for calling a string like a function
    variables[methodName](); // fails for a syntax error - []() = bad cfml!
    // umm, now what?

So here we are in the same old spot. First, the old school method, the one easily turned to in time of need, the cfinvoke tag. Personally, I dislike the cfinvoke tag. It seems to take me out of my flow. It ruins my mojo. It’s like longhand syntax for CF - it’s somewhat of an oxymoron. Nevertheless, here’s what you would do:

<!--- First, note that we have to rewrite it in tags. Not awful, but I dislike the switch. --->
<cffunction name="myStaticFunction">
    <cfargument name="methodName" />
    <cfset var methodResult = "" />
    <cfinvoke method="#methodName#" returnvariable="methodResult" />
    <cfreturn methodResult />

This works, but there’s got to be a better way! There has to be a less cheap way, something without all the #'s and stuff. And there is:

// back to cfscript, yay!
function myStaticFunction(methodName) {
    var method = variables[methodName];
    return method();

That’s much more like it! Of course this assumes we’re in a cfc or something, where the method is in the variables scope. Now, what other magical things can we do?

Well, I wasn’t going to share this one until the next entry, but since you’re talking me into it, here it is with onMissingMethod, dynamically calling a method with dynamic arguments. This onMissingMethod attempts to call a getter when you just call the property - in other words, will be automatically translated into user.getName(), to give you a nice jQuery type of syntax:

function onMissingMethod(missingMethodName, missingMethodArguments) {
    var f = 0;
    if (structKeyExists(variables, "get" & arguments.missingMethodName)) {
        f = variables["get" & arguments.missingMethodName];
    } else {
        // choke!
(Discuss with Disqus!)

Cheating with the 'ol dynamic language function alias trick

posted under category: ColdFusion on May 8, 2009 by Nathan

One of my favorite little tricks to play with CF, and with other dynamic languages like it, is aliasing function names.

Let’s say you have a component, User, and a method, getIsUserNameValid(). It’s a “getter” in order to satisfy some other kind of style requirement, but writing it out is verbose and feels wrong:

if (user.getIsUserNameValid()) {...}

You have to leave it as is so you don’t break any existing method calls, and to keep the basic style guidelines, but what if you could cheat a little? Consider this:

<cfset variables.isNameValid = variables.getIsUserNameValid />
<cfset this.isNameValid = this.getIsUserNameValid />

In ColdFusion, this creates an alias in the private "variables" scope as well as the public "this" scope to the old method. Now you can change your call to:

if (user.isNameValid()) {...}
(Discuss with Disqus!)

Start Eclipse faster with -initialize

posted under category: IDEs and tools on April 10, 2009 by Nathan

There was some good discussion today on the CFEclipse Users email list about getting Eclipse to start up faster, and I offered this suggestion:

Run this command when you log in to your workstation:

eclipse -initialize

According to the most complete reference I could find on Eclipse's command-line arguments, the initialize command:

Initializes the configuration being run. All runtime related data structures and caches are refreshed. Handy with shared installs: running Eclipse once with this option from an account with write privileges will improve startup performance.

The emphasis was mine, and for good reason. It really works!

In a very cheap experiment, using the windows clock as my stopwatch, I closed my open Eclipse (version 3.5, galileo M6), waited about a minute, then started it again. My PC took a full 60 seconds to load my workspace again.

I closed it, and called eclipse with -initialize through a windows shortcut. The initialize command doesn't really seem to do anything, and it took about 5 seconds to complete. After that, I waited 30 seconds and started Eclipse again, this time it took 16 seconds! Closed it, started it, 16 seconds again!

I guess I would have to reboot to get a cold start time, which is more than I'm prepared to do for today's little blog post. I really don't know what -initialize does under the hood, but wow, what a difference it can make.

(Discuss with Disqus!)

Managing your application's emails

posted under category: General on April 3, 2009 by Nathan

Here's a recurring problem I've discovered. Many, if not all, of my applications send email, and they tend to do it in an unmanaged, un-object oriented type of way. For instance, if you comment on this blog entry, I and other subscribers are sent an email. The template for this email is tucked away inside a CFC, right below where I insert the record into my database. This, of course, is a problem that can be solved in a repeatable, managed fashion.

I have actually solved this problem before at a previous company I worked at. Obviously all of that code is under lock and key, unusable due to NDAs and basically unethical anyway, so instead, I am planning on recreating something like it, but better, from scratch. Hey, if nothing else, I'll just use it on this blog. Of course I'm talking about open sourcing it - why would I tease readers with a cool toy, and not share it?

Overarching idea: A reusable open source library and API for both the management and sending of emails via templates.

Basic requirements:

  • Manage storage of email templates (CRUD basics, consider varying storage options)
  • Allow dynamic variables in email templates (Dear #user#)
  • Create basic administrative UI, key on easy integration
  • Create simple API for sending email

Groupthink questions: Does anyone else do this? How do you solve it? Why have I not heard of anyone else doing it?

Final thoughts: Sending email from your application is a scenario that I see often, and can be handled by an administrative managed, reusable application. Move your email templates out of your code and reduce the complexity of your application.

Oh, and I don't have a name for it yet. I'd hate to call it the Email Template Manager or something stuffy and boring.

(Discuss with Disqus!)

My experiences working with Google Docs Presentations

posted under category: General on March 5, 2009 by Nathan

I gave a recent presentation for the AZCFUG on Ant and Groovy. One interesting point about it was that I used Google Docs to do the whole presentation, including creating it, presenting it and publishing the slides the next day. Here are my thoughts, weighed out in a pro / con table.

The BadThe Good
Lack of fancy special effects or animations, only a single text fade in effect.No eye-gouging awful effects, the text fade looks nice.
Somewhat slow editing, just due to the fact that it's online instead of local, and it's HTML and Javascript instead of a native desktop application.Not so slow that it matters, will improve with the faster javascript engines coming in 2009.
Also, the features keep coming as the tools improve, no need to wait for the next $900 release of MS Office, incremental changes are just weeks away.
Have to be online to use it.Collaborative editing, collaborative viewing (I didn't use either of these, but may, in the future). Can access the presentation from anywhere on the internet.
Presentation mode has awful white lines on the top and right side, and a black utility bar at the bottom (I was using Firefox).The fact that it even has an online presentation mode is great.
The utility bar is very handy, not terribly in the way.
Can't control the presentation next/previous from the presenter's screen (when presenting with dual-screens). Controlling the presentation on the primary screen requires clicking on the slide, where the cursor gets in the way, or by clicking on the arrows in the lower left corner. These arrows can get in the way of the content. Either way, I would rather not have the cursor on the presentation screen at all.Speaker notes pop up in a separate window for dual-screen presentations.
Unlike Flash's full screen mode, it doesn't go back to the embedded size when it loses focus.
Unlike QuickTime or other embedded media players, it is very predictable.
Published slides required an iframe tag on my HTML Strict doctyped web site. Would have liked to foce visibility of my speaker notes on the published embedded slideshow.Published presentation was 1 line of HTML and was all HTML based (as opposed to Flash). Can publish on a web page, but viewers can get closer and use the full-screen view, see the speaker notes and even download it.
Exporting to a PPT file lost my gradual loading effects (eg. show 1 bullet at a time).It can export to PDF and PPT with fair enough quality. I had done this for a just-in-case-the-internet-fails backup. Plan B would have been degraded, had I needed it.
Less features than PowerPoint.Less annoyance than PowerPoint.
Had all the features I needed, not much more to get in my way.
It was evident, in stark opposition to PowerPoint, that this was about content and presentations, not about useless frustration, lining up pixels or worrying about fonts.
Limited design templates.Current template selection was adequate, I found one I liked.
Minor UI annoyances:
  sometimes wonky box selection
  smallest font size too large
  limited link type selection, no linking to slides, documents
  no shift-drag for straight line object moving
Great UI examples:
  drag & drop slides
  context menus always had the right actions
  so solid and easy, I didn't even consider using the help system
Interface was not customizable like MS Office, move toolbars, etc.Not bothersome, as it felt so good that I wouldn't want to change it around.

Overall, I had a great experience. Google Docs is constantly moving forward and this latest version of their presentation system was fantastic. I will definitely be using it in the future.

(Discuss with Disqus!)

Run Eclipse from your portable USB drive

posted under category: CFEclipse on February 28, 2009 by Nathan

I've got to admit that running basically everything from my USB drive is really nice sounding. Portable everything. I love Let's talk about running Eclipse portable.

Step 1: Download Eclipse, extract to portable drive
Step 2: Download Java, extract or install to portable drive
Step 3: Make a new workspace folder on the drive
Step 4: Rig up a batch file or shell script to run it all together. Here is what it needs to have for windows:

@echo off
cd eclipse
start eclipse -vm ../java/bin/javaw -data ../workspace

You'll see it may take only a few seconds longer to start than running it off your HDD.

Once started, you can import your projects into the workspace, add plugins and do your work from right there, all completely self-contained.

I did this initially for my Ant/Groovy presentation. I had my presentation online with Google Docs, and my demos from the flash drive. The idea was to use somebody else's PC, come with nothing to install and leave with nothing to clean up. It worked almost perfectly -- Alan had warned me about his PC, but when I ran the live demo anyway, Ant froze, Eclipse crashed, and I was out of time. Bummer! Anyways, not to detract from the subject, it did work on 3 other PCs. I'm just giving out creative ideas here.

Of course, if you're like me, to use this as your main IDE, you'll want a web server and something that runs CFML. I'm not there yet, but I know some other folks are doing just that.

(Discuss with Disqus!)

The SQLSurfer build process

posted under category: Software Quality on February 20, 2009 by Nathan

I have this open-source toy project I've been playing on, SQL Surfer. It's a little web-based SQL IDE with an amazing build process. How could I not share it with you?

The idea was pretty simple. When I work on my program, I want to see it like a normal program, multiple files, separate CSS and JS, included cfms, conditionals based on the server version, but when I release it, I want it in one, single file: easy to distribute, easy to throw on a server, no install, no folder structure to preserve, no dependencies to remember. It seems that basically no one has ever done this, but it's not too difficult.

The way it works, is, when I get to a point of wanting to make a release, I just run the Ant build file. One click. Ant does what it does best, preps the build, cleans out the output folder, in the end, it zips the results and whatnot, but I couldn't pull off the dynamic file embedding with plain Ant XML, so that's where Groovy comes in. I've got Groovy searching for included files (cfinclude, script, style, etc) and embedding the files in place of including them. Plus, while I was mashing files together, it seemed logical to compress them, even if just a little.

The result is a mashup of my entire application, nearly obfuscated into a single, gigantic, single-file, working application.

Actually, it goes a little further still. I wanted to have a version to take advantage of ColdFusion 8's new <cfdbinfo> tag, which, by the way, is awesome, but I also wanted to stay compatible with CF 6 and 7, even with a lesser experience. When you type a new CF tag into an older version, you get a compile error. That makes it hard to develop and hard to release. My solution was to drop in <cfif left(server.ColdFusion.productVersion,1) GTE 8>, followed by a cfinclude, css or js reference, then, Ant makes 2 files for 2 releases and my Groovy build file has 2 functions, removeCF8 for removing the if blocks, and removeIfCF8 for just the if statements and embedding the files.

The actual result is 2 files, all mashed up and working perfectly for different server versions.

Going overboard, I also embed EditArea, for the code editor. Of course EditArea doesn't care about an all-in-one-file project. I use Groovy to insert EditArea into the main file as well as change EditArea itself, at build time, to point to the embedded parts in the CF application instead of its own directory structure.

Taking it beyond reality, I realize now that I could probably include a framework like Barney Boisvert's excellent FB3 Lite, and then potentially images in b64. The only challenge that this approach leaves me with is CFCs. I love my objects, but I haven't figured out how exactly to embed them.

Ouch. Even just typing that last sentence makes my head explode with ideas. Taking it way too far, I could probably embed the components I use onto the main file, stripping out the cfcomponent tags, then to recreate them, create instances of the generic coldfusion component, WEB-INF.cftags.component, and re-constitute them with duck typing and method injection... Yeah, maybe some day, if I get really into it.

You can check out the source code right now and compile it yourself, but to hear about it first hand, visit the AZCFUG Feb meeting, 2/25/09, where I'll be showing it off. If you miss it, don't sweat it, I'll have the slides out by the next day. I'm undecided on having a connect meeting for it. If we choose to, I'll post it up here.

(Discuss with Disqus!)

AZCFUG - February 2009 meeting - Skills Month

posted under category: AZCFUG on February 17, 2009 by Nathan

Yes, it's a week from tomorrow. Alan & I have had some trouble getting speakers, but we need to have some get-togethers still, so let's do it.

Wednesday, February 25, 2009 6:30 PM, UAT main theatre room.

We're calling this "skills month."

Presentation #1:
Alan Rother, AZCFUG Manager: Intro to XPATH
Alan is a Senior Applications Developer at Interactive Sites in Scottsdale, juggling the application development of dozens of high profile sites for the hospitality industry. Also, he is insanely smart, so this will be good (no pressure here, Alan). Alan's presentation will run around 30 minutes and will take you from little-to-no knowledge of XPath to some actual applicable knowledge that you will want to use.

Presentation #2:
Nathan Strutz, AZCFUG Manager: Build Automation with Ant & Groovy
Nathan is a serious coder at The Boeing Company in Mesa who hacks on internal web 2.0 style applications, usually with his headphones on and nose buried in CFCs. Nathan's 25 minute presentation will discuss build automation with Ant, and some creative ways to use it. You'll like it.

We have a potential speaker for next month, but would love to fit in another short presentation if anyone wants to give it. As I said before, it doesn't have to be anything cerebral, and it doesn't even have to top 5 minutes. We'll be bugging you all about this, pretty much forever, so you might as well give in now :) Also, remember, presenting for the user group is a great resume item, and a great way to get your name out there.

As usual we've got the typical schwag giveaways (Somebody, please take our CF8 posters!), and we will most likely meet up at Aunt Chilada's after the event. Check the UAT map here.

More information is online at the Phoenix ColdFusion User's Group site and the AZCFUG Adobe Groups site.

Immediately following the AZCFUG presentations, the AZFPUG (Flash) group has a presentation lined up with Jason Crist, who will talk about the Facebook AS3 API, starting at 7:30 PM. You're invited to stay, but I will probably hit Aunt Chilada's before that.

(Discuss with Disqus!)
Nathan is a software developer at The Boeing Company in Charleston, SC. He is essentially a big programming nerd. Really, you could say that makes him a nerd among nerds. Aside from making software for the web, he plays with tech toys and likes to think about programming's big picture while speaking at conferences and generally impressing people with massive nerdiness and straight-faced sarcastic humor. Nathan got his programming start writing batch files in DOS. It should go without saying, but these thought and opinions have nothing to do with Boeing in any way.
This blog is also available as an RSS 2.0 feed. Click your heels together and click here to contact Nathan.