Posted in ColdFusion | Posted on 04-26-2007 | 3,970 views
Matt asked a question today and since I actually have gotten some work done today, I figured I'd blog about something besides Ubuntu, Hard Drives, and why I can't wait till I'm 100% Mac-ified. Anyway, here is his question:
I have a best practices question: is it bad practice to call a custom tag from a CFC, also is it bad practice to have HTML in a CFC.
First - check out the CFC Guide I have here:
I find that folks tend to miss my Guides pod to the right so I thought I'd point it out.
Is it bad practice to call a custom tag from a CFC? Not at all. You can call other CFC methods, other CFCs, custom tags, web services, etc. You may want to task if it makes sense to move that custom tag's logic into a CFC method however.
Your second question could be read two ways:
Is it ok to return HTML from a CFC method?
and...
Is it ok to have HTML in a CFC method?
The second version matches what you said - but I believe you meant the first version. In general folks almost never do this. The idea is - let the CFC handle logic (getProducts) and let you front end handle display.
That being said - I've done the second way (html in a CFC) in the past when I need to send formatted emails from a CFC, like for Ligthouse Pro's email reports. It would be possible to pass in a template of some sort, but frankly that seems like too much trouble.


Steve Bryant wrote some good articles on using CFCs in the presentation layer.
http://labs.webapper.net/projects/CFCFramework/ind...
Futher, cfcs are extensible. Most of the form cfcs I use extend a base class that generates the correct output from a simple xml definition, binds to the object for data transfer, automatically validates, and so on.
The view cfcs work similarly, and contain "helper" functions for things like automatic query list display and pagination functionality.
Futher, cfcs are extensible. Most of the form cfcs I use extend a base class that generates the correct output from a simple xml definition, binds to the object for data transfer, automatically validates, and so on.
The view cfcs work similarly, and contain "helper" functions for things like automatic query list display and pagination functionality.
Do you have a link for that article from Steve?
Steve's website has links to both articles:
http://www.bryantwebconsulting.com/articles.cfm
That being said, I can see some of the benefits to move nearly all reusable type code to CFCs IF you're developing code primarily by yourself or in a small group of like-minded developers.
Also, note that many developers just aren't aware of how powerful and handy CustomTags can be: http://cfzen.instantspot.com/blog/index.cfm/2007/4...
Ben Nadel has an excellent recent series of blog entries on CustomTags:
http://www.bennadel.com/blog/658-Creating-One-Way-...
http://www.bennadel.com/blog/657-Determine-The-Par...
http://www.bennadel.com/blog/654-Building-A-Table-...
http://www.bennadel.com/blog/650-Building-A-Table-...
Here's a snippet of code from a autogenerating form demo, much like the table generator from your example:
f=createObject('component','form').init();
f.hidden(name='id',value=456);
f.input(label='First Name', name='fn', value='mike', size=25);
f.input(label='Last Name', name='ln', value='long', size=25, required=1);
f.input(label='E-Mail Address', name='em', value='email@sample.com', size=25);
f.select(label='Gender', name='sx', value='m', size=1);
f.option(label='Male', value='M');
f.option(label='Female', value='F');
...
#f.display()#
It beats out performance-wise as well. All-in-all, cfc's are so superior in terms of packaging code that I stopped doing nested tag configurations years ago and never looked back. Pretty much the only thing I use a tag for these days is to do memory/file-based caching routines, and I think I still use the pagination one from time-to-time.
<cf_form>
<cf_formfield ..>
</cf_form>
Certainly for people coming from a non-programming background. Shoot, I come from a programming background and I still find the tag based syntax easier to work with.
Yes, Custom Tags have slower performance, but I do not believe that it is the type of concern that will impact most people. Performance is not _everything_. If it was - we would write in machine language.
if (f.process(object))
object.save();
...that the component-based version begins to show its true colors.
How about automatically marshalling data to and from your business objects, and having automatic form validation and error checking, and being able to include the previous example's form setup inside a "definition" function, such that each registration or sign-in or administration form is its own self-contained block of functionality? Was all of that included in the custom tagset?
What happens, say, when you need an special validation type? Do you dive into your cfx_form routines and patch them (problematic if a shared or public library), or do you just add a "validateMYTYPE" function to your form handler and get on with life?
From a syntax standpoint things are a little different, sure. Then again, you're already cross-training someone who knows input and select into translating select into cf_formfield type="select". Is f.select(...) that much harder? Or easier? Or just six of one, half-dozen of the other?
Again, I have to stand by the component-based approach for sheer power and functionality and extensibility and packaging and all of the other reasons I've already mentioned. And I've written a LOT of form, table, report, and database-management tagsets.
But if everyone agreed on everything, we wouldn't have horse races... (grin)
f=createObject('component','form').init();
... from experience, I'm almost certain that the custom tags will run faster (if pure performance is all we care about) under high load/traffic. You get the benefit of CFC performance mostly only when you put them in the Application or Server scope, and in some cases (if you don't have too many concurrent sessions) in the Session scope. But if you're doing createObject calls often on a per request basis (like above), then performance under very high load will decrease (trust me ;-).
The rest of my rant on the subject can be seen here:
http://cfzen.instantspot.com/blog/index.cfm/2007/4...
In the real world I'd call a manager or factory to get the form component, which in turn might come from an internal cache or pool of similar forms. You can also write form and view components such that they're "stateless" and can be cached and shared across multiple threads.
Or write them such that the definitions (which is where all of the attribute parsing and heavy lifting occur) are generated and cached, making a new form instantiation insignificant in comparison.
Further, several people have mentioned to me that Scorpio may improve component creation creation speeds quite a bit. Have to see about that one.
Translated, there are many, many ways to skin that cat. Properly designed, performance is NOT an issue. (trust me)
And to quote from your rant: "...I've been coding advanced CF for 5 years, and I've never seen..."
If someone has been coding for five years and has never run across components, factories, frameworks (Model-Glue), ORMs (Reactor), code/form generators, and so on, I'd really have to question how much "advanced" ColdFusion they've done. (grin)
And I'm also looking forward to the createObject performance increases in Scorpio, so that like creating a new object in Java, hopefully you usually won't have to worry much about performance when instantiating objects on a per-request basis. I trust you man, as it's clear you know what you're talking about and have the experience to back it up. :)
re: "...I've been coding advanced CF for 5 years, and I've never seen..." - actually, I was referring the reactions of other developers to the way this particular "architect" had designed a particular app, which was basically a complex, undocumented, spaghetti FB 2-3 hybrid, with little use of CFCs, MVC, encapsulation, best practices, or any other common ways of doing things. The design was, however, "inventive" and quite advanced (no matter your opinion of it). Unfortunately, no one else could understand what the heck he was doing until he explained it for hours (which he rarely did) or after a developer had worked with the app for at least 6 months. Finally, the CTO decided to rewrite the whole thing in Java... good idea!
That brings up a point which goes back to the original point about whether it's a better practice to use customTags for your View than CFCs: what's best practice in enterprise Java web apps? And incidentally, what's best practice in enterprise ASP .NET web apps? If you know the answer, and I'm sure you do, then you get the point.
@Ray - I don't think you necessarily meant that just because some of us prefer to use customTags for our View that it means we don't also use CFCs extensively, but I agree with your point that probably most CF developers who aren't heavy into the blogosphere are not primarily using the latest OO frameworks or design patterns. In my experience at least, most of us in the trenches are dealing with legacy apps that were originally written pre-CFMX, and therefore the code isn't always the latest and greatest. There's nothing wrong or less-advanced necessarily about these legacy architectures (in fact, many of the rake in millions or billions of dollars), but it's just different. ;-)
@Ray, I understand that many CF developers aren't using objects, much the same as most "old-school" PHP developers aren't using them either. However, many environments are object-based (java, python, ruby) or, like .NET, provide lots of functionality to the developer in terms of pre-packaged objects.
There have been many comparisons of CF to PHP, and with good reason. Both started out as scripting languages that encouraged a thorough mismash of HTML and code. Both have been extended with "modern" language features that all too few use. And both are constantly being extended with half-a-billion or so global functions and tags.
Because of that it's easy for beginners (and "advanced" developers) to start in and use both languages. Unfortunately, those habits are carried over into ever larger and more complex sites, and that's where things usually begin to disintegrate into chaos.
And that's why I tend to resist adding even more "global" functionality in terms of vast arrays of tag libraries. Because if someone is using a cf_form-style system then 9 times out of 10 I'll bet that they're plopping that tag-based form right in the middle of their page, which jumps to a hastily written xyx_process.cfm page that in all likelyhood doesn't do half as much error checking and handling as it should and cflocates back and forth as needed.
Not really what one would consider to be a "best practice".
I see our role as providing the tools needed such that using objects and doing component-based development is a no-brainer. And further, to promote "best practices" that ensure rapid development while also creating a site that's easily maintainable and scalable.
Thoughts?
Syntax wise I think custom tags really make sense in some situations. For layout it certainly does:
<cf_layout title="..">
Content
</cf_layout>
For providing complex information. Just look at Flex's datagrid. Yes you can add columns via AS but it is a lot simpler, and a lot easier to understand, in tag format.
Now if the code behind the tag is sucky - thats something else - but just the fact that it is a custom tag doesn't mean it -must- b sucky. ;)
[Add Comment] [Subscribe to Comments]