Archive for the 'fusebox' Category

Software Aging

With technologists (aka "geeks"), there is often a "latest and greatest is best" mindset that pervades the psyche. I'm certainly guilty. It's worth keeping in mind that just because something is newer, more feature rich, along a defined upgrade path, etc., doesn't necessarily mean you should switch. A standout example of this is Hal Helms' site. "Why?" you ask, well let me tell you.

Hal is a guy that has done some amazing things for the CF community. He's been a driving force behind Fusebox for many years, he was a driving force behind the creation of Mach-II, he's a huge proponent of OO software design with CFCs, and he's a nice guy to boot. And guess what? His site is running Fusebox 2. Yes. Fusebox 2. Because it's perfectly adequate.

I would never recommend building a new site in FB2. Never. But upgrading from FB2? If you need to, I suppose. Every time I end up on Hal's site for some reason, I remember noticing it was FB2 back in the heyday of FB3, and always go check the source to see if it still is. A little reminder in the chaotic world we all live in that the latest and greatest isn't always the best.

Fusebox 5 is Alive!

Sean's done a great job with the Fusebox 5 cores (as if anyone had any doubt), and released Alpha 2 to the mailing list this week.  There've been a few little issues, but nothing major, and I'm happy to say I'm now running two production apps on the new version.

Both are stock _VC FB4.1 apps, with the model (the missing 'M' in _VC) entirely encased in CFCs called directly from the controller circuits.  Except for a small compatibility bug in the cores that Sean already fixed, both apps ran without changing a single line of code.  With that kind of seamless upgrade available, the adoption rate of FB5 should be fantastic, even without the cool new stuff it brings to the table.

If you're interested in following along before the first public beta, go hit the fusebox5 Yahoo! Group, and sign up for the mailing list. 

Fusebox 4.1 Lexicons

I was the presenter at the Portland, OR CFUG last week, and the
topic was Fusebox 4.1.  One of the big points of interest was
custom lexicons, so I thought I'd share a couple examples here as well.

Fusebox
4.x is based around an XML grammar (composed of individual verbs, much
like CFML is composed of CF tags) for describing your application,
separate from the actual implementation of your application.  So
the XML documents the structure and program flow, but none of the
code.  Very elegant, and very helpful, particularly when you're
designing and managing large apps.  Custom lexicons allow you to
extend that XML grammar with application-specific functionality. 
By and large this isn't needed, but there are some places where the
built-in grammar is simply insufficient, and a custom lexicon can make
your life enormously easier.

The simplest example of a custom
verb is a 'write' verb that take a 'text' attribute and simply writes
it to the output buffer.  To many people, the inability to
natively do this in FB4 is surprising, but it quickly becomes apparent
that there is almost never a need to do it, except when you're hashing
out an application structure.  First, here's how the verb will be
used:

<beb.write text="hello, world!" />

The 'beb'
part indicates the lexicon the verb is in, and is specified when you
register your lexicon in fusebox.xml.  The 'write' part specifies
the specific verb to invoke, and then the 'text' attribute is just an
attribute passed to the verb, much like a custom tag.  Here's the
implementation:

<cfset fb_appendLine('<cfoutput>#fb_.verbInfo.attributes.text#</cfoutput>') />

So
what do we have?  We've got this 'fb_appendLine' function, we've
got this 'fb_.verbInfo' structure, and we've got some raw CFML encased
in a string.  But even if you don't understand the nitty gritty, the jist of what's happening should be pretty obvious.

A little
description of how FB4 works under the hood is in order.  The core
files take your XML documents and use them to generate execution plans
(parse files) in native CFML.  Then those execution plans are
actually used to service requests.  Because that translation
happens once (and not every request), FB4 is very efficient.  On
the flip side, integrating a custom verb is confusing, because your
verb is not running as part of a request, it's running as part of the
XML to CFML translation process.  And note that this is all
exactly the same for the PHP version too, just it's XML to PHP.

So
what does that mean to our custom verb?  It means we can't
actually output anything while we're being processed, instead we have
to add some CFML to the execution plan for later execution as part of
handline a request.  Oof.  However, the core files make it
really easy, just use the fb_appendLine function, and pass it a string
containing the CFML you want to add to the plan.

That takes care
of the first and last items from the example, but what about the
fb_.verbInfo structure?  That structure is a dedicated "scope" for
your verb instance to do it's thing in.  If you've written a
plugin for FB4, it's similar to the dedicated plugin scope within the
myFusebox structure.  When your verb is processed, all the
attributes for the verb will be stored in that structure, along with
the lexicon and verb names that are currently executing (should those
be of value).  So that's how you get your attributes, but there is
another piece of the puzzle.

Because custom verbs are not run as custom tags, they don't have their own private 'variables' scope, so you MUST
place any local variables in that same fb_.verbInfo structure to avoid
them "leaking" out and potentially interfering with other parts of the
application.

Here's a slightly more complex example that illustrates this point:

<beb.dump var="#attributes#" />

Basically it's a CFDUMP tag, but usable within FB4.  However, there is some
trickery we can do because of this whole "building an execution plan,
not actually executing" paradigm.  Here's the code:

<cfset fb_.verbInfo.v = fb_.verbInfo.attributes["var"] />
<cfif structKeyExists(fb_.verbInfo.attributes, "label")>
    <cfset fb_.verbInfo.l = fb_.verbInfo.attributes.label />
<cfelse>
    <cfset fb_.verbInfo.l = replace(fb_.verbInfo.v, "##", "####", "all") />
</cfif>
<cfset fb_appendLine('<cfdump var="#fb_.verbInfo.v#" label="#fb_.verbInfo.l#" />') />

This
time we're using a couple local variables ('v', and 'l', for var and
label, respectively), and carefully constraining them to the
fb_.verbInfo structure.  But if you look carefully, we're actually
using the textual value of the 'var' attribute as the default for the
'label' attribute.  Because the 'var' attribute isn't being
evaluated until the execution plan runs, the verb can actually read out
the textual value of the attribute, something that's impossible with a
CFML custom tag.  If you've ever done something like this:

<cfdump var="#attributes#" label="attributes" />

then you'll quickly see the value of letting the custom verb do take care of the 'label' attribute for you automatically.

So
that's a very brief primer on custom lexicons in FB4.1.  I have to
mention that custom lexicons are a 'preview' feature in FB4.1, not an
official part of the framework.  They definitely aren't going
away, but it's possible they will change.  In particular, real XML
namespaces will be used at some point, rather than the dot notation
currently in use.  That was a stopgap meature, because CF6.x
didn't have namespace support, but CF7 does.  But that's
definitely not a reason to avoid them; they're far to useful to wait.

Fusedocer Updated

A long while ago, I wrote a utility called Fusedocer that parses a Fusebox 3 application and generated per-fuse documentation similar to the way JavaDoc works. It was quite useful at the time, but since I moved to Fusebox 4, I'd almost forgotten about it. Turns out people are still using it though, since I got an email this morning from a guy in the Netherlands saying it didn't work on CFMX. More specifically, that it wasn't detecting any of the fuses in the circuits, so it wasn't actually generating anything. He'd also isolated the problem: I was using a filter on a cfdirectory call that CFMX wasn't handling correctly.

The filter was [a-zA-Z]{3}_*.cf*, which apparently worked on CF4.5 (what I was running when I wrote the app), but no longer works on CFMX. The fix was simple, just change it to *_*.cf*, and everything started working. I've uploaded a new version of the utility to the Fusedocer page, so you can get the CFMX-compatible version if you want it.

Update: Since my server crashed last year, the /go/ URLs have been broken, and the links above haven't worked. The ZIP file can be downloaded here.

Architecting FB4.1

Architecting with Fusebox 4.1 is a very wide arena. There are lots of ways to do it, but I think I found one that is particularly well suited to the framework, especially when combined with CFCs for a backend. My presentation at the 2004 Fusebox Conference hinted at much of the principles, but I can say that after having written a couple more FB4.1 apps from scratch, that they make for a very nice little package.

There's a few main points:

  1. Separate 'pages' from 'actions'
  2. Separate the UI from the application proper
  3. Separate the markup from the presentation
  4. Reuse code everywhere it makes sense, and nowhere else

For point #1, a legit question might be "what's the different between a page and an action?". My definition is that a page renders content to the user, while an action performs an action and redirects to somewhere else. The definitions are mutually exclusive, so if you're doing an action, you HAVE to redirect to a page in order to render content; you can't do both on a single request. There are a few exceptions (for instance, marking a message 'read' - an action, when you open it - a page), but they are few and far between.

I opted to have all my fuseactions that generate HTML be named as you'd expect (addEntry, viewComments, etc.). All my fuseactions that do actions start with 'do' (doInsertEntry, doDeleteComment, etc.). In my presentation at FBCon04, I'd recommended separating the pages and actions into separate circuits. Upon further reflection, I'm retracting that recommendation in favor or just separating the pages and actions in your circuit.xml file. One block has all the pages, and another block has all the actions (commented appropriately, of course).

Point #2 is accomplished by the use of a 'service' CFC. It is a singleton CFC that is instantiated into the APPLICATION scope of the app, and it contains all the business operations and data recall for you app. Each business operation has a defined method name and set of parameters. How it's implemented (inlined SQL, a mess of BOs, DAOs, and gateways, magical pixie-powered light-based storage, whatever) is irrelevant, and that's exactly the idea. You should be able to change your presentation layer without changing your service object, and you should be able to reimplement your service object (maintaining the method signatures, of course) without changing your presentation layer.

Point #3 is the standard "use (X)HTML and CSS" line. Make sure you pages are designed from a semantic perspective. Build all the pages before you ever write a single line of CSS. Not going to be pretty, but they do need to be functional in that fashion. Then whip out your CSS magic wand and make it all pretty. This really has nothing to do with FB4.1, but it does have to do with good architecture, because the more divorced your markup is from your presentation (CSS, in this case), the easier it will be to make changes (visual or functional) down the road.

And at last, number 4. Two clauses, and the latter is the more important one. I've seen a lot of people (myself being one) who try to squeeze every last drop of reuse out of a bit of code. Reuse is good, but there are definite times when it's simply a foolish goal to strive for.

In this particular app, most of my display templates (roughly analogous to views in Mach-II) are in their own fuseactions. Again, I opted to not use a separate circuit, but rather name them starting with an underscope (i.e. _entryForm) set them as access="internal", and group them all in their own section in circuit.xml. They include everything needed to render the view, except for designated parameters for reuse (such as the XFA to submit a form to). That means they might include calls to the service object for a recordset, might set their own XFAs, might do basically anything, as long as it's bound directly to rendering that specific view file.

So, in a nutshell, what do I have? A single circuit, broken down into three sections (pages, views or pagelets, and actions). An abstracted service object that encapsulates all the business and persistent operations behind a known interface. Markup that is independant of it's presentation. An app that is both enormously flexible and easy to work with.

Future updates can apply to single sections of the app without affecting other sections if they don't need to, greatly reducing the subsequent testing needed. Poorly implemented sections (of which there are a couple because of time constraints), can be transparently reimplemented without affecting the app.

What I've described isn't quite MVC, at least in the traditional sense. It's subtly different, and while only time will tell, I think those differences result in a much better end result.

Fusebox Moving Ahead

I'm happy to say that the Fusebox development effort is at long last using version control. Yee-Haw!! After much persuasion and a few hours of work, I've set up a CVS repository and gotten everything squared away for it's continued use. Currently, both read-only and read-write access are both restricted to specific users, but in the future, anonymous access may be allowed, and/or development snapshots may be available for download.

FB & CFCs Presentation and Example code

After numerous requests, I finally got my presentation from the FB conference, along with the example code, zipped up and available for download. It should also be posted on the conference web site, but I'm not exactly sure where.

More from the Conference

While I was at the conference, I also had the opportunity to work with John Quarto von Tividar on some fundamental changes to the way the FB core files work. The mods will make the guts of the core files much simpler, make the new custom lexicon features that are being demoed in the 4.1 series amazingly more powerful, and also let us (the core developers) "eat our own brand of dog food", so to speak.

Some of the changes will make their way into a future 4.1 beta, but some of them won't be made available until the next release of the cores. Suffice to say, there are some really neat things coming down the pipe over the next year or so.

2004 FB Conference

I went to the 2004 Fusebox Conference over the weekend, and had a good time. It was held in Rockville, MD, which is somewhere around 20 miles northwest of Washington DC. Nice to see everyone face to face again, and meet various people who I'd not met before.

I also had the privilege of speaking on FB and CFCs. It was both enlighting and enjoyable, and reconfirmed my inner desires of one day ending up as a teacher. I was somewhat nervous beforehand, not from stage fright so much as fear that the topic was hard to compress into 50 minutes. But it all turned out well. The audience seemed engaged and interested, and from the positive response afterwards, it seemed that my expectations of people were too low. I guess that's the price I pay for being eternally surrounded by idiot clients. ; )

Also at the conference, Steve Nelson, Rey Muradaz, and I decided to try and jump start the community into being formal content producers to the CF community at large. Most Fuseboxers have more than a slight fanatical bent, and many (like Steve) are absolute zealots. However, the community as a whole doesn't have a large voice in the greater CF community, other than the periodic discussions about FB (and frameworks in general) on various mailing lists.

Steve, Rey, and I committed to writing/gathering four articles each on any topic even remotely related to Fusebox, and we'll publish them over the course of next year, initially as an email newsletter, and possibly included in CFDJ. Anyone who would like to participate, please let one of us know what you'd like to write about, and get us an article as soon as you can. One to two pages is totally sufficient.

Fusebox Conference

The annual FuseBox Conference is coming up September 18 & 19. Once again, I will be attending. I'd hoped to go to CFUN as well, but that didn't work out. Should be an informative and enjoyable couple days, including the release of FB4.1, and the announcement of Team Fusebox (whatever that is ; ).