CounterMarch Systems

comfortably self-assured


We used to blog more before twitter came along.

Pour a little out for CFUNITED

Commingled with the fun and excitement of attending this year's CFUNITED conference was an acknowledged sadness associated with knowing it was to be the last. We've grown accustomed to seeing each other once a year (for some not often enough, for others...just the right amount) and the loss of an opportunity to reconnect is a moment we should recognize and appreciate.

Many of us can say a lot of the same things about CFUNITED: we've seen great and not-so-great presentations, enjoyed great and not-so-great food, partied into the wee hours racking up bar tabs that were impressive or simply outrageous, and met the people that we call our community. Or more accurately: our friends.

A community without a place to commune isn't complete, and simply doing it on the internet isn't enough. Michael Smith and the TeraTech/Stellr team identified the need for a physical place for our rabid online community to gather outside of DevCon/MAX and user group meetings. The creation of CFUN and subsequent evolution (and growth) into CFUNITED gave us just that place. CFUNITED became one of those few gatherings that was both technically *and* socially valuable to the full spectrum of ColdFusion developers. CFUNITED also helped other members of the community identify the things they wanted in a conference, implicitly leading to the creation of cf.Objective to cater to the advanced CF crowd with many others to follow suit in their own way. All of these things added credibility and value to our community as a whole.

It is for those reasons CFUNITED will always represent a special place and time for us all. This conference turned newbies into real developers, the fortuitous hallway/bar conversations turned intermediate developers into professionals, and creative topic selections turned quiet cube monkeys into amazing speakers and teachers. Simply being together made us all feel a little less weird for being so enthusiastic about what ColdFusion enables us to do.

So as we move ahead without another CFUNITED on the calendar, I hope we all remember that the community is more important than any one event, that none of these things that we appreciate would be here without our continued passion and participation, and that it's important for us to support the things we have and the things to come. Doug Boude said it best: "now that one of the larger trees in the forest has sadly fallen, the vacancy it leaves us with is the opportunity and catalyst to allow for the currently smaller, more focused, and/or regional conferences to flourish and fill this niche."

NCDevCon, BFusion/BFlex, cf.Objective, RIA Unleashed, D2WC, and tons of user group meetings (online and in person) happen every single year. MAX will always be there with the extremely promising CF Unconference component. Out of the collective will of the ColdFusion community new events will emerge, and as they do we'll find our new normal. We've inherited a great gift: a passionate community and proof that there is significant interest in conferences at all skill levels.

This is a fond farewell and thank you to CFUNITED for what its creation and ending have done for our community. Thank you, everyone, who ever attended and made my CFUNITED experience better as both an attendee and speaker. I look forward to the day we're all in the same place again.

Mach-II is (still) awesome

Mach-II rocks. It is one of the more "mature" surviving ColdFusion application frameworks, and as such doesn't get nearly the amount of buzz that the new (interesting, different, creative, awesome-in-their-own-way) frameworks get. If you're looking at frameworks, I encourage you to take a look at the amazingly capable Mach-II - we've had fantastic success with it!

Things I really, really like about Mach-II:

Backwards compatibility

Take an old (Mach-II 1.1 app, circa 2006) and update the framework to 1.8 (released 2009). Replace the application.cfm file with application.cfc, comment out everything in index.cfm and *boom*...you're done. I can't really assess how challenging it is for the team to maintain backwards compatibility, but I sure do appreciate how simple it is to upgrade. Instant feature add with zero headaches.

Coldspring integration

<include file="./mach-ii_coldspringProperty.xml" />

and in your listeners:

<cfcomponent name="mpListener" extends="MachII.framework.Listener"

depends="howConfigManager,mpManager,reportManager,notificationManager">

I don't think it gets much easier than that. Instant Coldspring integration for dependency injection (and more), radically simplifying the configuration of all of my listener and model cfcs. Now we've got all the power of Coldspring cleanly available to our Mach-II application.

Faster Fixes

Knowing where to find things is one of the hallmarks of any good framework. Some do it by convention, some by configuration. Mach-II falls into the latter camp but that's perfectly fine by me. Getting back into the mental model of an application months (or years) after deployment is a challenge but by simply cracking open mach-ii.xml I can see what happens where within seconds and bend it to my will. I love this.

Modularity

This wasn't in the framework back in the 1.0 and 1.1 days (when we created some mammoth apps), but by 1.5 (which came out in 2008) the ability to break up large Mach-II applications into separate modules was baked in and oh-so-handy. It's two years later and we've been able to make the easy changes to break those older apps into a collection of modularized sub-apps for much easier maintenance. Perfect example is an extranet: lots of only slightly related apps put under one common umbrella sharing security or UI components. This is easy to implement and support in a well-designed Mach-II application. All of our more recent apps make use of this feature.

The Team

The people who created and have since improved and evolved Mach-II are some of the smartest folks who are or have been involved in the ColdFusion community. Look at this list. Not only have they created something awesome, but they're incredibly responsive on the wiki, development Google group, and framework users Google group. They use this framework at their day jobs so you know that each release has been painstakingly designed, implemented, tested, re-tested, piloted and then released. Plus, they're open to new ideas (even if you personally have no idea how to make them happen!). Code is great, but the people are the best.

The View Loader

This is where some of those "convention-based" concepts have crept in to Mach-II much to the benefit of the users. Back in the "bad old days" your mach-ii.xml file would contain a block that looked sorta like this, except far longer:

<page-views>
      <page-view name="showWelcome"       page="views/showWelcome.cfm" />
      <page-view name="showHome"       page="views/home.cfm" />
      <page-view name="baseTemplate"       page="views/baseTemplate2010.cfm" />
      <page-view name="blankTemplate"    page="views/blankTemplate.cfm" />
      <page-view name="welcomeLanding"    page="views/welcome_landing.cfm" />
      <page-view name="showSendPassword"    page="views/showSendPassword.cfm" />
      <page-view name="showAppHelp"       page="views/showAppHelp.cfm" />
   (and so on)

Each page would have a page-view defined. Someone called shenanigans on it and now we have the PatternViewLoader to replace ALL of it!

<page-views>
   <!-- This would load all views with the pattern of "/views/**/*.cfm" which is the most basic and common pattern -->
<view-loader type="MachII.framework.viewLoaders.PatternViewLoader" />
</page-views>

So, so simple. Love this line of the config file more than any other.

Better apps, faster.

Take Mach-II off the shelf and use it as your "glue." Add Coldspring to manage your model. Use ColdFusion 9's new Hibernate ORM capabilities to cut the lines of code in your model by a huge factor. Redirect some of the saved time into building a better UI using jQuery, improving your cross-browser capabilities with clean CSS and making your client happier by communicating more frequently. Result: a better app, designed to be maintainable and much more in line with your client's spoken and unspoken expectations. How could any craftsman not feel good about that? Mach-II is a key component to that successful formula for us.

Try Mach-II. Need help? Talk to the team on the list. Build great things.

On conferences and venturing outside

Two years ago I blogged about having attended a conference completely outside the 'geek crowd' and how much of an eye-opening experience it was. Since then, not only have the marketers' forecasts become reality (Twitter going big and them taking advantage of it) but I've also been fortunate to attend Higher Ed Camp Philly.

Higher Ed Philly was a great experience. I was really surprised at the great blend of technical folks and educators (from both public schools and universities) in attendance. The effect this had on the sessions was tremendous and has completely changed what I want to get out of attending a conference. In short, it was nothing like what I expected...it was way better!

From the perspective of a tech person who generally attends tech conferences, the interaction among the attendees was totally different. Instead of constant hardcore technical discussion, there was a balance of talk about tools and practical application. The educators' minds worked quite differently from ours but in a really valuable, interesting way. I found myself wanting to attend more of the educator-focused sessions simply to further understand their way of looking at the things we create as the starting point for their work to take off.

Consider this: we create, sometimes in a vacuum, but always with limited feedback. The educator must somehow translate the practical utility of whatever it is we created into something that the average human can understand and then apply to their own want or need. Their entire job is to act as our forgotten intermediary; a good number of them spend most of their time trying to keep other teachers up to speed on what's possible. Their (presumptive) reason for attending was to get a head start on that process.

Every session I attended included elements of show and tell, the educators talking about what they see as useful, and the techies trying to offer suggestions on the spot. We live to solve problems, and the challenges put forward by our fellow attendees were some of the most creative, interesting ones I got to think about all week. I think that's awesome and should stand as a strong message to all of us that we have to get out of our niche and spend more conference (unguarded, relaxed, non-work) time in a similarly blended community.

I bet we could have taught some of those teachers and instructional technology people at Higher Ed Philly a couple lines of CFML and made them dangerously powerful. I bet they could teach us a few things about how to understand methods of learning and made us dangerously effective communicators and trainers. Together we were kicking around ideas that wouldn't have naturally evolved from either camp alone and improved ourselves in ways we never expected.

...

Later today, the final CFUNITED conference will get underway. I'll miss it for all of the reasons that the attendees from any year share. But in retrospect, and through the lens of this new outlook on conference participation, I realize that the best learning I ever did there was from the informal chatter of people talking about their challenges, their daily realities, in a group of people we'd all like to consider colleagues. We talk about problems that are technical (solvable) and political (not always). We bring differing skills but a common understanding of CFML to the table and have a great time learning from one another.

CFUNITED has served us well as the table around which we gather, but tables also make us focus inward. In its absence next year, I hope to see the regional events (like CF.Objective, RIA Unleashed, NCDevCon and BFlex/BFusion to name a few) continue their excellent growth right alongside unconferences and meetups that blend our technical proficiency with people from other disciplines in the same space. We can't lock ourselves up in our own tech-specific shows all the time and expect to grow our community and grow our skills in a career-savvy way. The ColdFusion community, while awesome, will need to look outside the realm of those who work with competing technologies and instead turn towards people with complementary skills and interests to evangelize CFML as a platform.

Use the end of CFUNITED as a reason to expand your participation in new directions. Show off what your CF skills can do while scratching someone else's itch. And once you've done it, come back and share with everyone else. It's a big world, and we're all students of everyone else.

See you in Virginia!

Mobile Apps for Alumni Relations - Cornell Compass

We recently had the privilege of working with Andrew Gossen in Cornell's office of Alumni Affairs on a sweet little mobile project.

The Cornell Compass web application uses geolocation features exposed through mobile browsers to determine the distance and bearing from where you're standing to the center of Cornell's campus. It's fun! It would be way more fun if the orientation of the device was exposed as well (then we could make the compass dynamically spin in real time).

Once your location is determined you have the opportunity to "Check In" and drop a marker on a map with your name and class year (both optional). The map is visible both on the mobile device and via the website (we do some browser sniffing so the content is device-appropriate). All visitors are encouraged to share the link to the site via Facebook and Twitter.

The Compass app is optimized for iPhone, but is functional on both Blackberry and Android devices as well. The backend (which is trivially simple) is ColdFusion with Microsoft SQL Server. The bulk of the front end work was done using jQuery and a few assistive javascript libraries for doing the bearing calculations.

We're working with Cornell to design the next version of this application with more features that make it useful to Cornellians all over the world looking to deepen their relationships with each other. Interested in learning more? Please drop me an email! We're interested in working with other organizations to enhance the usefulness of the app including integration with alumni online communities and CRM systems.

Flash Player 10.1 for Mobile

Today's the day! The long-awaited release of Flash player for mobile devices has finally arrived.

For those of you with Android-based devices, once you've upgraded to FroYo (2.2) you'll be able to install the player. Looks like Adobe has also released it to the companies behind Blackberry, webOS and Windows Mobile phones as well. Those of us with Apple devices, well, we're going to just have to stare at that little blue brick until mommy and daddy stop fighting.

As for what makes this release special, consider that Adobe (and before that Macromedia) has been promising a viable Flash runtime for mobile for what feels like forever. 10.1 is the first full Flash runtime built from the ground up for mobile devices, taking into account their inherent limitations (processor power, screen size, battery life) and still providing what early reviews say is outstanding performance. Short version: you can now watch more videos, play more games and access more rich internet applications on your mobile devices than ever before.

There's a lot here for the developer community too. Until today we were stuck building web based applications (as it turns out, mobile devices aren't immune to browser implementation quirks either) or going fully native (thus incurring the cost of building new for every targeted platform). Now, we can build modern, web-friendly, high-performance applications that will run on a wide variety of devices from all but one of the top-tier mobile device manufacturers once and only once.

The mobile market is changing rapidly. HTML5 is years away from an official standard. Mobile browser-based applications will always have to work around implementation quirks, even if the feature set is striving towards parity with what Flash player has had for years. I'm excited to have the option of building an app once, having it available everywhere and knowing that it'll "just work."

ColdFusion 9 Security Lockdown Guide

Adobe published the work of Pete Freitag today - a 35 page guide to secure installation and configuration of ColdFusion. Even if you feel like your ColdFusion server(s) are tightened up, it's always a good idea to take a moment to do a review.

While the guide does not go into detail on building secure applications, Pete's PDF is a step-by-step tutorial that even someone not familiar with ColdFusion administration could follow. Grab the PDF and spend the 15 minutes to check up on all of your servers (including your local development environment) - it's well worth it.

When you're done with that, check out the Security section of the ColdFusion Developer Center on the Adobe Developer Connection for lots of articles on how to write safe and solid code too!

CS5, Adobe, Flash and (sigh) Apple

While CS5 is going to be a fantastic release, one feature in one product of the suite was perceived as sufficiently threatening to actually get a reaction from Steve Jobs. So if one feature was that awesome, consider what else is going to be in that box on Monday! But I digress...

Adobe is doing what it does best: release tools that make designers and developers more productive. This has little to do with Flash and everything to do with unleashing the collective output of the web development community. Flash is merely an enabler for the most dynamic, engaging and portable web-connected software experiences we have. But Dreamweaver, ColdFusion Builder, Flash Builder and the upcoming Flash Catalyst are the tools that make it all possible. They're not sexy but it's what we get to look at all day long.

The ability to develop an app using a language and IDE you're comfortable with means that you, the developer, can focus more on the creative and innovative aspects of your product instead of getting tripped up on syntax or negotiating the quirks of a new platform. That's just good business sense and makes for a happy, productive development team. Apple doesn't see it that way and would prefer that we do it their way, using their tools or just stick to web development.

It's not about getting Flash on the iWhatever; it's about getting developers working on apps for the iWhatever using Adobe tools. Really. Apple has plenty of specious reasons for not allowing Flash on their mobile hardware and only one legitimite one. Adobe's not out to decimate ITMS or the App Store (even if that might be fun) - it's looking to increase the size of the Flash developer market and thus sell more tools (which also includes our server-side favorites like ColdFusion and Flash Media Server). Flash isn't perfect (and if you actually read posts from Adobe folks, they're not arrogant enough to assert otherwise) but it's really fantastic for what it did for rich media delivery and standardizing the delivery of application experiences in the browser, a task that the major browser vendors continue to struggle with. Performance will never be as good as native apps - so what? Adobe continues to throw resources at optimizing the player and now that they have (at least in this one area) help from Apple on hardware acceleration the OSX crowd should be somewhat placated.

The blowback from the developer community on the latest SDK changes is the sound of people ticked off that the iPhone/iPad will remain mostly inaccessible without learning Objective-C. Not everything we'd want to do is exposed through the browser. It's an inferior platform and forever relegated to second class citizen status on the device. Why do developers like Flash in a desktop/laptop/netbook browser? Because it gives back a lot of things that the browser takes away. These things Apple wishes to keep for itself and a small cabal of trusted (or at least solid revenue generating) developers. HTML5 does not restore them - that seems to have been conveniently forgotten - despite Steve's assertions that the browser is all we should be paying attention to.

This will still be a great week for Adobe. It's also a great week for the web development community. One sentence in one document tells us where to shift our attention - away from Cupertino and towards a more open future.

Fine. I didn't want to pay your rent anyway, Steve.

Adobe wins, with or without you.

 

CASE Benchmarking Toolkit featured on Adobe Flex Showcase

One of our systems has been included in the Adobe Flex showcase on the newly relaunched Flex.org website: the CASE Benchmarking Toolkit.

The toolkit is a Flex and ColdFusion application used by CASE and select member 'communities of practice' to develop, collect and report on common performance metrics for fundraising and alumni relations in the world of higher education. This system is used by decision makers in thousands of institutions worldwide. You can read more about it in the Benchmarking and Analytics Toolkit for Higher Education post I put up a few months ago. Needless to say, this is very exciting!

I wish I could give you a direct link, but I'll give you directions instead. Flex.org -> What's Possible -> View Full Showcase. We're in there somewhere. There's plenty of design inspiration to be taken from the other apps listed as well.

CFSpreadsheet presentation and samples

I'd like to thank Adam Tuttle and the Philadelphia CFUG for inviting me to speak last night on CFSpreadsheet. While the thought of listening to someone talk about spreadsheet generation from an hour would only make a true techie's heart race, I think those who were there got a good overview of what this new functionality can do for them. If anything I hope that I lowered the bar for many in attendance while simultaneously increasing pressure on their bosses to buy those licenses!

My preso focused on the basics (here's the tag, here are the functions) up front and followed up with 6 examples of how these new functions can be used to manage spreadsheet creation and editing no matter how mangled or ugly. If you want the CFSpreadsheet presentation assets and (commented) sample code, feel free to pull this ZIP. I will be updating it this weekend with Derby databases so you can just unzip and run everything. For now, unpack the zip into a folder in your webroot. You may need to comment out the ORM settings in Application.cfc to make it run. Ping me with any questions either here or via twitter (@scrittler).

I also had the opportunity to touch (very lightly) on the new ORM features of ColdFusion 9 during the presentation. One of my demos (not in the zip file) is the start of an app that is intended to replace a spreadsheet with a web app. After 90 minutes of work I had the spreadsheet imported to a db using Hibernate, a quick add/edit form put together and a re-export (since the end users still cling to Excel) of the current db. If I had to write all that SQL it could have easily taken far longer. Finishing the app should be trivial from here, so props to Adobe for putting all the right pieces in the box for me to play with!

It's pretty clear that the whole concept of using an ORM engine is very, very new to most of the ColdFusion world and is definitely holding back adoption. You don't need to know terribly much to use Hibernate with ColdFusion but letting go of having to write SQL is certainly showing to be more difficult than expected. It's a different way of thinking, one that the user group community can definitely help to encourage. The time savings and maintainability improvements alone are well worth starting the trip. I know the Philly CFUG calendar is pretty well packed, but I hope we can put together some talks on this topic (preferably hands on) soon.

Again, thank you to the CFUG for inviting me to speak. I look forward to seeing everyone at the next meeting on Feb. 25!

CFSpreadsheet and Conditional Formatting

CFSpreadsheet pretty much rocks the house when it comes to simplifying the task of creating spreadsheets (Excel and Open Office compatible) from ColdFusion. On Thursday January 14 I'll be giving a talk at the Philadelphia CFUG meeting on this topic, but something I was working on last night has me particularly excited and requires a blog post.

Several of the spreadsheets we currently generate for clients have some degree of pretty formatting associated with them. The way we've typically done it is to export a decorated "source" Excel file in Excel's XML spreadsheet format, chop it up and jack the appropriate data into the document, setting style attributes on the cell tags appropriately based on server-side logic. But what if you wanted to create the spreadsheet such that the conditional logic was built in to the spreadsheet itself? The people that use these spreadsheets like to play with the data and it would be awesome if the conditional formatting (highlight in some color, change font size, whatever you like) would apply to their edited data.

It didn't seem immediately possible using CFSpreadsheet or any of the 37(!) functions exposed in ColdFusion...but then I remembered that this functionality is built on top of Apache POI, so there had to be a way to get down and dirty with the Java internals. It's not hard to get there, but whoa the code to implement conditional formatting is definitely verbose.

What I want to do is set up a conditional formatting rule on the 6th column (F) such that if the value is greater than 10 the background is set to yellow.

<cfset objSS = spreadsheetNew("faculty") />
   
<!--- get a handle on the underlying POI object --->
<cfset objWorkbook = objSS.getWorkbook() />

<cfset objSheet = objWorkbook.getSheetAt(objWorkbook.getActiveSheetIndex()) />
   
<!--- get a handle on the conditional formatting property of the sheet --->
<cfset objCF = objSheet.getSheetConditionalFormatting() />
   
<!--- now add the format rule that we want on the doc --->
<!--- formatting rule:
<cfset HSSFConditionalFormattingRule = objCF.createConditionalFormattingRule(
                                                      5, <!--- org.apache.poi.hssf.record.CFRuleRecord.ComparisonOperator.GT --->

                                                      "10", <!--- the value i want the cell to be greater than for the format to kick in --->
                                                      javacast("null", "") <!--- 2nd formula is not used for GT/GE --->
                                                      ) />


<!--- Create yellow background format definition --->
<cfset HSSFPatternFormatting = HSSFConditionalFormattingRule.createPatternFormatting() />

<cfset HSSFPatternFormatting.setFillBackgroundColor(createObject('java', 'org.apache.poi.hssf.util.HSSFColor$LIGHT_YELLOW').getIndex()) />

<!--- Define a region that only impacts the "tenure" column (which we know to be the 5th (zero based)) --->
<cfset regions = arrayNew(1) />
<cfset regions[1] = createObject('java', 'org.apache.poi.ss.util.CellRangeAddress').init(1,1000,5,5) />
<!--- CellRangeAddress(firstrow, lastrow, firstcol, lastcol) --->
   
<!--- Apply Conditional Formatting rule defined above to the regions --->
<cfset objCF.addConditionalFormatting(regions, HSSFConditionalFormattingRule) />

Then it's just a matter of inserting the spreadsheet contents as usual.

<!--- generate the new worksheet --->
<cfquery name="qFaculty" datasource="#application.datasource#">
   select
         facultyID, pidm, loginID, firstName, lastName, startYear, department, title
   from
          coe_faculty
   order by
         lastName
</cfquery>


<!--- headers are considered friendly --->
<cfset spreadsheetAddRow(objSS, "ID,PIDM,Login,First Name,Last Name, tenure, startYear, title, department") />

<!--- i hate columns that show up as #### or truncated --->
<cfset spreadsheetSetColumnWidth(objSS, 2, 13) />
<cfset spreadsheetSetColumnWidth(objSS, 3, 8) />
<cfset spreadsheetSetColumnWidth(objSS, 8, 20) />
<cfset spreadsheetSetColumnWidth(objSS, 9, 25) />

<!--- loop over the data - calc the tenure and style accordingly --->
<cfloop query="qFaculty" startrow="2">

   <cfset excelFormula = "(year(today())-G" & qFaculty.currentRow & ")" />

   <cfset spreadsheetSetCellValue(objSS, qFaculty.facultyID , qFaculty.currentRow, 1) />
   <cfset spreadsheetSetCellValue(objSS, qFaculty.pidm, qFaculty.currentRow, 2) />
   <cfset spreadsheetSetCellValue(objSS, qFaculty.loginID, qFaculty.currentRow, 3) />
   <cfset spreadsheetSetCellValue(objSS, qFaculty.firstName, qFaculty.currentRow, 4) />
   <cfset spreadsheetSetCellValue(objSS, qFaculty.lastName, qFaculty.currentRow, 5) />
   <cfset spreadsheetSetCellFormula(objSS, excelFormula, qFaculty.currentRow, 6) />
   <cfset spreadsheetSetCellValue(objSS, qFaculty.startYear, qFaculty.currentRow, 7) />
   <cfset spreadsheetSetCellValue(objSS, qFaculty.title, qFaculty.currentRow, 8) />
   <cfset spreadsheetSetCellValue(objSS, qFaculty.department, qFaculty.currentRow, 9) />

</cfloop>

<!--- append the worksheet to a new spreadsheet file --->
<cfspreadsheet action="write" filename="#request.rootDirectory#\sheets\faculty_style_cf.xls" name="objSS" sheet="1" overwrite="true" />

The end result:


Checking the conditional formatting panel in Excel we see that it's legit and not hard coded.

I'll post more as I dig in and build more complex examples. This is a simple expression, but it should be enough to get you started if you need to do this kind of thing with ColdFusion and a generated spreadsheet!

More Entries

About the blog

Celebrating our 5th year!

CounterMarch Systems is a professional consulting firm specializing in Adobe technologies with a special focus on higher education.

2771 Red Oak Circle
Bethlehem, Pennsylvania 18017
610.280.3455
Contact Us