CFCUnit Documentation Updated - How To Write A Unit Test
I'm not sure when Paul Kenney posted this, but I know a lot of people have been waiting for it... The CFCUnit web site has been updated with documentation on writing unit tests. If you aren't already writing unit tests for your CFCs, you should be. Paul's framework is the most complete I've seen for CF yet, and is definitely worth taking a look at. Now that there's documentation on how to write tests, there's no excuse!
My team has been doing a lot of work with the Mach-II framework lately, and we're extremely heavy users of CFCs. On top of this, we're busy making sure our SDLC complies with the requirements of the Sarbanes Oxley Act. One of the areas of special interest is documentation. The nice thing about CFCs is that they are [relatively] self documenting, provided you populate the various cfcomponent, cffunction, and cfproperty tag attributes. While ColdFusion MX comes with two tools for examining the CFCs on your system. The CFC Explorer can be invoked by entering the URL to any CFC accessible via a URL on your server. In our case, the majority of our CFCs are NOT accessible via URL as they are located in a directory outside of our web root. In this case, you can use the Component Browser that comes with ColdFusion MX. This tool can be accessed like this:
Using this tool, however, requires that you use either the RDS or CF Admin password to access the browser. This may or may not be an issue depending on your local setup and policies. In any case, the auto generated documentation created by the CFC Explorer and the Component Browser is identical. It's a good start, but there are an increasing number of third party tools that take the basic concepts in these tools and extend them. I'm going to share the three that I'm aware of and have used in various capacities to auto-generate documentation on my CFCs. If you are aware of other tools, let me know!
Two new CFCs have been posted to the site in the past few weeks. Check out checkEquality by Qasim Rasheed and queryTool by Joe Rinehart on the CFC page.
Macromedia DRK 8 Now Available With DevNet Subscription
I didn't see an announcement on the Macromedia DevNet DRK site yet, but when I logged into my subscription tonight, DRK 8 was available for download. Here are the CF highlights incase you can't wait for the official release...
New forums application by Ray Camden
Assert API - Custom tags for adding special checks in your code.
WSDLerator - Tool for discovering and testing Web Services for use within ColdFusion.
By popular demand, Paul Kenney has provided an early release of his much awaited cfcUnit testing framework. It's basically a port of the jUnit framework and performs the same basic functionality.
If you aren't familiar with testing frameworks, or why you should be considering one, Paul provides a good explanation here (an excerpt from an article published by Christian Cantrell).
Right now, there's basic setup instructions, with more detailed documentation on writing test cases to follow soon. A big thanks to Paul for creating the suite - it's going to go a long way in making development and testing of CFC based applications easier for ColdFusion developers.
Now, if only someone would create a cfcUnit plugin for integration with the CFEclipse!
With all the current buzz over Blackstone (the next version of ColdFusio MX), I decided to shoot an email over to my editor at O'Reilly to gauge their interest in having me write the 3rd edition of my book Programming ColdFusion MX.
Well, I heard back from him today, and it looks like they are going to pass on a new edition. I'd like to say that I was crushed by their decision, but honestly, I'm a little relieved. It was hard work turning out two books over the past few years, each as the sole author while maintaining a full-time job, National Guard service, and a marriage (maybe a bit of a social life too). The first edition of my book ended up selling about 9,000 copies after the majority of the returns were in. Given that an author pulls in 10% of what the publisher sells the book to retailers for, this translated to apprx $2 a copy. Do the math and $18k looks like a nice bit of pocket change - until you also realize that the taxes on that come to apprx 40%. Then take the 1500+ hours I put into the first edition and you can see it didn't amount to much more than minimum wage! I'm fine with that, though, as I didn't write the first edition to make money. I wrote it because I used ColdFusion every day, and I loved sharing my enthusiasm for web application development with CF.
When O'Reilly asked me to write the 2nd edition for CF MX, I was a little hesitant because of the amount of time it took to do the first edition (almost 2 years). I relented and managed to squeeze it out after the 6.1 release after investing about 1000 hours (yes, I'm rounding a bit). It was a fairly major rewrite as CFMX was a huge improvement over CF 5. Lots of new features and revisions added about 250 pages to the book, bringing it in at around 1100 pages.
That brings me to today. Programming ColdFusion MX, 2nd. edition is the second best selling ColdFusion MX book (at the register as it goes), behind Ben's CFMX WACK. Given that it's only sold around 5,000 copies or so in the past year, that's pretty sad, and I can see why O'Reilly isn't interested in doing a third edition. It isn't that the book isn't good (it's gotten many positive reviews), and I realize that the market for technical books is saturated and not in the best of shape, I guess I'm just a little sad (not bitter) that the ColdFusion community is losing the backing of O'Reilly given their reputation in the technical community. I always felt that having an O'Reilly book for a particular technology (even if I weren't the author) put some weight behind it.
So, it's on this note that I'd like to thank all of you who have purchased and read my book. I've recieved many kind emails over the years and have enjoyed corresponding with each and every one of you. I'd also like to take this opportunity to urge all ColdFusion developers to support the other authors of ColdFusion books out there. If we really want ColdFusion adoption to continue to spread, there has to be good material available for the developers who want to learn it.
I know several people have already blogged CF MX 7 (Blackstone) feature requests, but I figured I'd share the list of features I've been compiling. This list represents enhancements that I along with many other developers have been asking for, some of them going back several versions of CF. I've submitted this entire list to Macromedia, but I wanted to see what others out there think. I realize that some are much more doable than others, and that some of my requests fall within the category of "niche" feature, but I thought I would share nonetheless:
tag for spawning multiple threads for asynch processing
As mentioned by others, event based session/application/server functions: onSessionStart(), onSessionEnd(), onApplicationStart(), onApplicationEnd(), onServerStart() and onServerEnd(). Along these lines, I'd like to see an XML based config file that runs when the server is restarted. This XML file could contain info on queries to automatically run and default variables to be assigned for the server/applications
Add functions to programmatically list all current sessions/applications on a server (without the Java workarounds we're currently using). Include info such as when the session/application was started, how long until expiration and whether or not it has already expired. Examples are getSessions(), getClients(), getApplications(), getSession(), getApplication(), etc
Enhance the CF Scheduler so that it can operate in a cluster. I want to synchronize events between servers in a cluster so that you can setup a scheduled task on any server, and it would replicate out to all the other servers (similar to the buddy server concept), but the event would only fire on a single server, not on all of them at once
Further enhance the cf scheduler to use its own thread count (as opposed to the one that's defined in the CF Admin now). This would allow the scheduler to use a different threading model than "active" applications on the server
Add interfaces to CFCs
cfconstructor tag for use in CFCs and deprecate the pseudo constructor area
Deprecate cfscript and add ActionScript 2.0 support. You could easily do this by adding a new attribute called "language" to the cfscript tag where language="actionscript" or something like that. This way, existing cfscript would continue to work
Overloading for functions and CFCs
Mechanism for dealing with name conflicts (overriding) with native CF functions/tags in order to future proof. So, if I already have a UDF called wrap(), upgrading my version of CF won't break my app when CF get's its own wrap() function
Build stronger partnerships with companies like IBM, Actuate, etc to get support for CF into their products
Make CF's security framework more granular. I always need an additional level of security beyond roles. How about groups, roles, and permissions. While you are at it, give us a way to programatically get a list of users currently logged in, their roles/permissions, etc
Add IMAP, NNTP, and SMTP tags
Functions/tags for image manipulation
Tags/functions for manipulating PDF. I saw the Max preview and was impressed with the cfdocument tag. I think this is a good start. I think for the report type, you also want to add Flash Paper in addition to HTML and PDF. Excel would rock.
Since there is already support for Crystal Reports via cfreport, I'd like to see integration with Actuate too. It's J2EE based, so I would think that there are several integration points possible here.
Add the Lotus Notes JDBC driver, free from IBM to the list of native drivers
Tags/functions for dealing with Zip files
Fix reFind() and reFindNoCase() to return the positions for all matched subexpressions
Spell check tag
Wrap up all hot fix in a Zero G installer so that they can easily be backed out. Also, when a hotfix is applied, log it in a server var available in the CF Admin so that an admin can tell what hot fixes have been applied
JDO support if you can think of a way to do this
Add a TRACE attribute to CFQUERY for debugging so that we can see what CF is doing with the underlying JDBC driver. Most drivers have a trace capability that can be logged to a text file, but I'd like to see what's happening from a CF's perspective so I can see exactly what calls to my drivers it is making
Scrap the JS validation in CFFORM and implement the qForms JS API from PengoWorks. It's much more powerful, flexible, and extensible and works very well with CF.
Add XMLDoc as a return types for methods in CFCs. Right now, you can't return a CF XML Document from a CFC as a native type
Add an interface to the CF Admin to allow me to "reset" a datasource without having to restart the CF server. Right now, several of my iSeries DB2 data sources (JTOpen driver) occasionally hang. The rest of the CF server is fine as are the rest of my data sources. In order to free the hung data source, I have to restart my CF Application Server service. I would rather kill the connection to the hung data source and restart it (if that's how it works) without having to restart the server. It would be even better if I could to this programmatically, so I could call it from a cfcatch block if I detected the specific error a hang causes
cfsocket tag (like in DRK5)
Better caching than cfcache provides. See Brandon Purcel's CF_Accelerate. Not sure if you could replace cfcache with this or if it would be a new tag.
In the CF Admin (and programmatically), give us a way to see and admin (expire) cached queries.
Allow for mappings on an application level so that mappings defined in the CF Admin can apply to either the entire server, or a specific application.
More metadata in the cfquery result set. I'd like to see the size (bytes) of the returned record set, column types, etc
Official framework for unit testing CFCs
Support for portlets as outlined in JSR 168 and JSR 170. I'd really like to see the ability to create a portlet in CFML, then have CF generate a WAR file for the portlet that can be deployed to any compliant portal server.
Make the cfproperty tag actually define properties for CFCs as opposed to just for web services and meta data.
Allow parameters for the JDBC URL to be passed dynamically at run time if possible. For example, right now, if I want to add an extra parameter to my data source just for testing, I can't do it from the cfquery tag. I have to go in and make the change in the CF Admin, and then change it back later if I want to "undo" it.
Add XML validation against a DTD
Integrate with JMS
Allow sorting scheduled tasks within the CF Admin alphabetically by name, or time (interval). I have a server with 600+ scheduled tasks, and I'd like to group by time so I can tell whether I need to move any to a different time to avoid using too many of my server's available threads.
Within a CFC method (and a UDF), allow us to VAR variables anywhere, not just at the beginning of the method. I often need to var a variable with a value that is dependant upon another condition (such as a conditional based on an argument being passed in). Because I have to var before any other cfml statements, I first have to var the variable and set it to empty (var=""), then do the conditional later. I'd like to see VAR implemented like in JavaScript. It would be great to var a loop variable inline, as opposed to at the top of the page for example
Make the installer for deploying multiple instances of CFMX easier
Make it possible to deploy a "clone" of an existing instance of a CFMX deployment right from within the CF Admin of that instance. Similar to your archive and deploy, but have the deploy actually create the new instance and then clone the original
Make it easier to tie a different jvm classpath to each instance of CFMX when using multiple instances.
If you are interested in ColdFusion Components (CFCs), and aren't already a member, you might consider joinging the CFCDev mailing list. This moderately trafficed list (avg 35 posts per day) currently has 601 subscribers of varying skill levels. Topics tend toward more advanced subjects, but all discussion related to CFCs is welcome.
Adam Crump, one of the guys on my team has released a Dreamweaver MX extension he created called CFC Bean:
"CFC Bean is a command extension to generate a java style Bean implemented as a ColdFusion MX Component. You simply add the properties required for your bean, and CFC Bean will generate an init method, get and set methods for each property, and if selected getInstance, and setInstance methods. CFC Bean is very useful for creating beans for use with the MachII framework and bean work in general."
We've been using CFC Bean here for a few months now, and it's saved us a ton of time in the creation of our Mach-II beans.
If you don't use Dreamweaver, there is also a web based bean generator with similar functionality:
Jonathan Block's JavaScript bean generator
And a Homesite version by Christopher Bradford here:
Adam Crump and I are heading to San Diego next Tuesday (5/4) to visit the SDCFUG. Sean Corfield, Macromedia's Director of Architecture is giving a presentation on the use of Mach-II at Macromedia. We're particularly interested in what Sean has to say as we've recently adopted the Mach-II framework for CF Development within our company.
My team has been in the process of moving/porting a suite of ColdFusion applications to our new data center. The current apps were originally written using CF 2.0, and updated bit by bit through ColdFusion 4.5.1. We're now migrating them to CF MX 6.1 and have decided to adopt Mach-II as our framework.
We're pretty heavy users of Dan Switzer's qForms JavaScript API and have been integrating it nicely within Mach-II. One gotcha we did run into, however, was discovered by the team (Adam Crump, Jim Bambrough, Ray Ragan, and Steve Rittler). It seems if you have debugging enabled for the request scope, qForms does not work. The problem has to do with the page content being stored in the request scope, so when the page executes, it gets output normally within your view, but it also gets output in the debug code. This results in duplicate form fields and duplicate qForms code, which basically breaks functionality. Not the end of the world, but it can mislead you into believing there's an issue with qForms when there really isn't.
I took a call from our help desk last night around midnight. One of our users in Asia had called in reporting an error in one of our applications. I checked our error logs, and sure enough there was an error - an SQL error: SQL0117 - Statement contains wrong number of values. This server happens to be an old ColdFusion server still running ODBC. We're in the process of upgrading t to MX, but that's another story. Anyhow, at first, I was puzzled by the error as we hadn't made any changes to the code in quite some time. Then it hit me. Earlier in the day, we added a new column to one of the database tables used by the application in order to facilitate the upgrade. Harmless enough, right? Wrong.
Turns out the application in question had an SQL insert that looked something like this:
INSER INTO myTable VALUES('#foo#', goo, '#boo#')
Now granted this code was written about 6 years ago, but the developer who wrote it took a shortcut that came back to bite us. Instead of explicitly declaring the fields to be inserted, he or she simply expressed the values to insert. This only works when the number of values exactly matches the number of fields in the database table. In my case, the extra field we added caused the application to break. Now granted this is something that could have been caught in testing/qa, but we didn't have that luxury in this particular instance.
The moral of the story here is that in order to future proof your application, it's best to always declare the columns you intend to insert:
INSER INTO myTable (foo, goo, boo) VALUES('#foo#', goo, '#boo#')
IBM released JTOpen 4.3 today. JTOpen is an opensource Type IV JDBC driver for accessing DB2 running on the IBM iSeries midrange computer. Version 4.3 adds several bug fixes, performance enhancements, etc.
I'm happy to see that Steve Rittler, long time Philly CFUG manager, has entered the world of blogging with his State of Independence blog. Steves a really great guy, and an excellent developer. Although his blog isn't specific to MAcromedia technologies (it's built in ASP.Net), Steve has a lot of insite to offer on both ColdFusion and Flash development. Look for a lot of good information from Steve in the near future.
CFCZone has recieved several submissions of new CFCs over the past several weeks. I've actually had a few free moments to update the site, the results being 7 new CFCS. Rather than go into all of the details here, drop on by the site and have a look around.
Although this isn't really *new* (the driver was released about a month ago), I never got around to blogging it. For those of you who connect ot an AS400/iSeries with CFMX, you might be interested to know that IBM released version 4.2 of JTOpen, their open source JDBC driver for DB2/400. You can download the driver here.
A fellow ColdFusion developer is having database connectivity issues connecting CFMX 6.1 to DB2 on an IBM OS/390. I was wondering if any of you other ColdFusion developers out there were connecting to that platform and could offer up some help as far as what drivers you use, connection strings, and any other advice. Contact me via the comments or at rbils@amkor.com if you can help.
Three new CFCs have been submitted to the www.CFCZone.org. One's a wrapper around Java string functions, another is a wrapper around Java regular expression functions, and the third is an interface for working with pure Java resource bundles. Check them out in the CFCs section of the site.
Using the JTOpen JDBC Driver with Multiple CFMX 6.1 Instances
I recently setup a new development box running multiple instances of ColdFusion MX 6.1. I posted a question to the CFGURU mailing list asking about the best place to put my 3rd party JDBC driver. Sean Corfield and Simon Horwith both chimed in that they recommended placing it in:
{jrun.home}/servers/lib/
In my previous non J2EE installations of ColdFusion, I always placed my driver in c:\jt400\jtopen\bin. Whenever I setup a new server, I also had to add this location to the JAva CLASSPATH in the ColdFusion Administrator. What's my point? Well, using Sean/Simon's location, I no longer have to add the CLASSPATH to my ColdFusion server as the location is already known to the JRun/ColdFusion server. Very convenient!
Also for you iSeries fans out there, a new article by Jeremy Lyon is in this month's ColdFusion Developer Journal. The article, "MX to iSeries Demystified - A world-class database platform paired up with a world-class Web application server" gives some decent information on using CFMX to query data from DB2 on that platform.
Webreference.com publishes Web Services Excerpt from Programming ColdFusion MX
Webreference.com (an Internet.com site) recently published an excerpt from my book Programming ColdFusion MX. The excerpt is actually the entire chapter, so for those of you who don't already own the book, this might be worth checking out - especially because my book is the only ColdFusion book that covers ColdFusion MX 6.1.
If you are into CFCs, and are looking for a high quality, no-nonsense resource for all things CFC, you might consider joining the CFCDev mailing list over at www.cfczone.org. Currently, the list has over 550 members, with an average of 30 messages per day. Although the discussion tends to center around more advanced topics, developers of all skill levels are encouraged to participate. The list can be subscribed in regular or digest versions, and an archive is available for searching.
Of course there is no commitment on Macromedia's part to include anything I'm about to blog in any future version of any of there products. That said, here are some features/functionality to think about from the MAX Sneak Peek session:
cfform tags as flash components
cfgroup to create, layout and group form fields
Flash based forms within cfml
Tab navigators within the cfgroup tag
Accordion panes within cfgroup
Binding text fields to the data grid in Flash based forms
Reporting via a cfdocument tag. Handles tables, divs, headers, pagination, etc. All layout done via HTML, and the output can automatically be converted to PDF.
Last night, a group of about 20 developers met over at the Marriott to have an informal discussion about CFCs. Ray Camden and his company Mindseye sponsored the room.
There was a lot of great discussion regarding how people are using CFCs right now, as well as the challenges they face and the enhancements they would like to see in the next version of CF. Among the key themes:
CFCs could use a true constructor
People would like to see interfaces
The ability to serialize/deserialize CFC is a key requirement
Copying of CFCs needs to be fixed
The general agreement in the room was that CFCs are the best thing to happen to CF in MX, and that Macromedia should continue to evolve them to meet the needs of developers.
As Ray stated in his blog, we really could use more of this type of session at the next MAX conference. Time to meet with developers in a formal space, but an informal discussion format (with Macromedia in attendance) would be a great addition.
At today's keynote, Ben Forta "unofficially" announced the next version of ColdFusion MX, code named Blackstone. No details on the development cycle, or when alpha/beta would be available for testing.
According to Ben, the most requested feature for this version is enhanced reporting/printing. In my opinion, it would be a waste of time and resources for Macromedia to try to come up with their own reporting engine, especially when enterpries class engines such as Crystal and Actuate already exist. What I'm hoping is that they add intgration into popular reporting engines, as well as built-in support for generation of PDF files (via Apache FOP and XSL-FO, perhaps?). I would also think that some level of advanced report formatting could be achieved via CSS, so I guess we'll have to wait and see.
Other features hinted at were improved performance, more deployment options, and the ability to "protect" source code. My guess on that one is some sort of obfuscation scheme.
I've been doing a lot research into corporate portals lately as part of my job here at Amkor. I've evaluated the offerings of some of the major players such as IBM, Plumtree, and Oracle, and am always interested in how we can leverage our investment in ColdFusion within the portal space, which is dominated (mostly) by Java.
The Portlet specifiation as outlined in JSR 168 and the Content Repository for Java technology API outlined in JSR 170 (both of which Macromedia participate in) standardize the framework for portlets in a vendor/application server neutral way. To me, this standardization and the fact that Java is the portlet technology of choice has me wondering if Macromedia could/will support portlet development within ColdFusion in a furure release of ColdFusion MX.
As I see it, there are (at least) two ways this could be supproted. The first, and probably the simplest would be simply to have ColdFusion MX expose "remote" portlets as web services. WebSphere v5 now supports remote portlet calls, as long as they are registered in a UDDI directory and (presumably) adhere to a specific WSDL format. IBM Portal Server and Web Services, a whitepaper from IBM explains how this works in some detail.
The second way I see ColdFusion supporting portlets would be to actually write the portlet using CFML, and have the underlying CFMX (JRun) application server compile the code to Java and package it up appropriately as a WAR file.
Possibly interesting as well would be how this could be done if you were running ColdFusion MX on top of a J2EE application server (such as IBM WebSphere) that was running as the portal server.
What do you think? Is this something that seems reasonable or even desirable for a future version of ColdFusion?
I really should pay more attention to Builder.com. They seem to have more and more ColdFusion related articles lately.
While browsing today, I noticed an October 2003 article by Brian Kotek called The ColdFusion Core: Write efficient code with the Composition object pattern and CFCs. The article gives a nice succinct description of how to use Composition in your CFCs.
Brendan O'Hara, author of the monthly Design Patterns column in the CFDJ, has a column in the October issue on Creational Patterns. In the event you aren't a subscriber, you can read the article, in its entirety on the CFDJ website.
Brendan is a huge proponent of CFCs and the use of design patterns in ColdFusion development. His articles are an asset to the evolution of ColdFusion from a purely procedural language to the realm of OO.
O'Reilly has just released Flash Remoting: The Definitive Guide, by Tom Muck and friends. The book covers all the ins and outs of Flash Remoting using several languages on teh back end, including ColdFusion MX. I haven't had a chance to review the book yet, but I'm hoping to get the time soon as I've been waiting for a decent book on the topic, and O'Reillt rarely disappoints (and I'm not just saying that because I write for them).
Christian Cantrell Wants to Know, What's Your Dream ColdFusion Feature?
On his blog today, Christian Cantrell asks what your dream ColdFusion feature is. Here's your chance to let Macromedia and others know. I already had the engineering team contact me about one of my suggestions, so I feel confident that what we as a community post is going to be read by some influential people at Macromedia.
So, when you get a chance, check out Christian's post, and feel free to add your two cents to the mix.
FIX: Handling Bad Database Username/Passwords with CFMX and DB2/400
A problem that's been plaguing a lot of us that use CF MX and IBM's JTOpen JDBC driver to connect to DB2 running on IBM's iSeries (AS400) has to do with CF MX hanging when a bad username or password is passed to the database. It's really frustrating on so many levels, especially since the only way to free the hang is to restart the CFMX service. Sometimes even this isn't enough, and the server must eb rebooted. Obviously, this isn't good in a production environment.
Jeremy Lyon emailed me today to let me know that there's a JDBC URL parameter that you can set to fix this problem. Basically, there's a parameter called prompt. The JavaDoc definition for prompt is:
"Specifies whether the user should be prompted if a user name or password is needed to connect to the server. If a connection can not be made without prompting the user, and this property is set to "false", then an attempt to connect will fail."
What this means is that by default, prompt is set to True. If you pass a bad username or password, the system attempts to "prompt" the user for a username/password. Since you aren't using an interactive application to make your connection, you never see this prompt, and the system "hangs" indefinitely.
The fix is to ALWAYS specify prompt=false in your JDBC url. This way, id a bad username/password is passed, the JDBC driver will report this back to ColdFuion, and an exception can be thrown.
O'Reilly has posted the example files for my new book, Programming ColdFusion MX. You can download the example files from http://examples.oreilly.com/coldfusion2/.
Three new CFCs have been submitted to the www.CFCZone.org by Globalization/Internationalization/Localization superstar Paul Hastings. Check them out in the CFCs section of the site.
Another CFTREE Bug in MX 6.1 - That Makes Two in One Day
I've been putting the example files together for my new book, Programming ColdFusion MX, and have been (re)testing each one along the way. Unfortunately, it looks like something changed in MX 6.1 (from 6.0 updater 3) that breaks a lot of the functionality of the CFTREE tag and its related sub tags. I already reported on another CFTREE bug earlier today. Looks like I've found another. This one, like the last, is fairly problematic - especially if you make use of the CFTREE tag in a lot of your applications. I personally rarely use it anymore as I really dislike Java applets and all of the games you have to play with different JVMs and different browsers. However, I do still have a few "legacy" web apps that use the CFTREE tag, and now they are broken.
As with the last bug, this one is with the cftreeitem tag. I've worked up an example that works fine in MX 6.0 Updater 3, but breaks in MX 6.1. It consists of two files. Save the first one as anything you want. The second one is a custom tag that must be saved in the same directory as "recurse.cfm". Basically, the example uses recursion to loop through a DB table and dynamically build a CFTREE based on the parent/child relationships in the table. Works fine in 6.0, results in an empty tree in 6.1:
Here's the caller template (the one you run):
You chose:
Node: #form.Links.Node#
Path: #form.Links.Path#
vscroll="Yes" border="Yes" required="Yes" appendkey="No"
message="You must choose a category or item from the tree.">
Here's the code for the custom tag (recurse.cfm):
SELECT ItemID, ParentItemID, ItemName, LinkURL
FROM request.links WHERE ParentItemID = #attributes.ParentItemID#
ORDER BY ItemName
href="#LinkURL#" img="#Image#" expand="No">
SELECT ItemID, ParentItemID, ItemName, LinkURL
FROM request.links
WHERE ParentItemID = #GetParents.ItemID#
It *seems* to me that cftree has a problem with a cftreeitem with value="0" and parent="0". If I remove the parent attribute (from the main template), the tree displays. Note, though, that the expand attribute that is set to Yes does not result in an expanded tree. This behavior is also incorrect. I plan to submit this to Macromedia as a bug as well, but I'm not sure it will fit in their bug form (it only allows 2000 characters in a text box the size of a credit card).
It looks like there is a bug with the cftreeitem tag that was introduced in MX 6.1. Basically, the queryAsRoot attribute of the tag is broken. It no longer accepts a string value (it now only accepts a Boolean). This is inconsistent with other versions of CF as well as the MX 6.1 documentation.
The following code demonstrates the problem:
Note also that if you change queryAsRoot to Yes, the IMG attribute breaks. Instead of showing fixed, then folder, it shows fixed for both levels in the tree. Run the code on MX 6.1 and 6.0 to see the difference. I've reported this bug to Macromedia.
Pardon the self-promotion, but I wanted to announce that my latest book, Programming ColdFusion MX, 2nd Edition has been released. It's worth noting that this is the only book on the market that covers ColdFusion MX 6.1.
If I was fortunate enough to have you as a reader of the first edition of this book (Programming ColdFusion), you'll be interested to know that the second edition has been completely revised and updated for ColdFusion MX 6.1. Just about every chapter has been rewritten, several of them completely. Many of the changes are the direct result of reader feedback. Four new chapters were added to deal with totally new topics introduced in ColdFusion MX. Additionally, the majority of examples used throughout the book have also been rewritten to reflect new and improved coding techniques and practices. It's worth noting that many of the changes to ColdFusion from Version 5 to MX are significant and simple to spot, while others are subtle and easy to overlook. Wherever possible, I try to point out the differences between the two versions.
CF MX 6.1 Adds Millisecond Support to Time Functions
One often requested enhancement to ColdFusion has been the addition of milliseconds to ColdFusion's various date/time functions. In MX 6.1, Macromedia has finally added support via a new mask element, "l" (that's a lowercae L). This new mask can be used with the following functions:
I saw a question on the CF-Talk list asking about the new wrap() function in CF MX 6.1. It's not as intuitive a function as you would think. The first time I saw it, I assumed you passed it a string and a character break, and it would return a string formatted with tags at the appropriate interval. This is not what it does. Here's an explanation from my new book, Programming ColdFusion MX:
Usage: wrap(string, limit [,strip])
Specifies the maximum number of characters to allow per line in string. If a line is longer than the specified number of characters, an attempt is made to break the line by inserting a line break at the nearest whitespace character (space, tab, etc) before the character limit. If string contains no whitespace characters before the maximum number of characters per line, a line break is inserted at the maximum line length. Wrap() uses operating system specific line breaks. On Windows, it's a carriage return and newline character. On Unix/Linux, it's a newline. Optionally, you can specify a third Boolean argument to indicate whether to remove all existing carriage line breaks before wrapping the string. The default for this argument is false.
#wrap(myString, 80, False)#
If you need a function that actually inserts tags for you, consider wrap() from the CFLib.org web site. Note that you'll have to rename the UDF to avoid conflicting with the new wrap() function in 6.1.
In a blog post earlier today, Ben Forta mentions that getTickCount() returns a different value than in previous versions of ColdFusion.
With the MX 6.1 release, getTickCount() now returns the number of milliseconds from Unix Epoch (January 1, 1970, 00:00 GMT). Note that it doesn't account for your GMT offset.
Here's another interesting new feature in ColdFusion MX 6.1...
There may be cases where it would be useful to have one or more methods available to all of the components on your server. Ideas that come to mind are debugging methods, server-wide settings, etc. As of ColdFusion MX 6.1, you can modify a special component called component.cfc that all components on the server automatically extend. Out of the box, the component.cfc file can be found in the \WEB-INF\ cftags directory and is completely empty. Any methods or properties you place in the file are automatically available to every CFC on your server.
CFCs: Variables/Unnamed Scope Issue Fixed in MX 6.1
For those of you working with CFCs in ColdFusion MX 6.0, you'll be happy to know that the bug affecting variables scope has been fixed in MX 6.1. Now, both the variables scope, and the unnamed scope (unscoped variables) behave the same way. Here's a breakdown of how the variables/unnamed scope, the local scope (var keyword) and the this scope differ:
Variables/Unnamed Scope
Variables in the variables scope are available only within the CFC. They are available to the constructor code, and to all component methods and any pages they include. They may be prefixed with the variables prefix or left unscoped (often called the unnamed scope). Variables in the variables scope that are set within the calling page are not automatically available within the component’s variables scope. Additionally, variables in the variables scope exist as long as the component object exists. This allows them to persist between method calls.
Local Scope
This differs from variables you set in the "local" scope of a method by using the var keyword. These variables are available only to the method in which they are defined and any pages included by that method. Additionally, local variables do not last beyond the life of the method call. The local variable scope differs from other variable scopes in that there is no scope prefix used for the variable. Note that if you do not define the variable with the var keyword, the variable exists in the variables scope, not the local scope.
This Scope
The this scope is functionally equivalent to the this scope in JavaScript and ActionScript. Variables in the this scope are available to all methods within a CFC, any pages they include, and the page that calls the CFC. Within a CFC you refer to variables in the this scope using the this prefix: this.varName. Outside the CFC, you use the component name to reference variables in the this scope: myComponent.varName. Note that this applies only when the CFC is instantiated as an object via the cfobject tag or createObject( ) function, not when a component method is invoked using the cfinvoke tag, without the CFC being instantiated separately.
The long awaited ColdFusion MX 6.1 (formerly Red Sky) is now available for download. I though t it wasn't going to be out for a while longer, but it looks like it's been added to the Macromedia web site (although no mention on the homepage yet).
CF MX 6.1 is so much more than just a maintenance update for ColdFusion. In addition to the over 400 bug fixes in this release, you should (in most cases) notice a huge boost in the speed and stability of the application server thanks to major improvements and tuning undertaken by Macromedia's engineering staff.
Here are the highlights of the new release:
App code is now compiled in memory as opposed to disk, resulting in a significant decrease in initial page compilation time as well as an increase in overall runtime performance.
The installer was completely overhauled, making it easier than ever to install ColdFusion MX. Additionally, a single installer now covers all versions of ColdFusion.
Speaking of versions, Macromedia decided to change the way ColdFusion MX is licensed. I won't go into all of the details here, but I will say that the coolest part is that the Enterprise version now lets you install a FULL copy of JRun and then deploy CF MX 6.1 on top of it. Yep, that's right, a FULL, LICENSED copy of JRun. This means that Enterprise customers can start taking advantage of ome of the more compelling features that J2EE has to offer such as multiple server instances, JRun's buddy list clustering, etc.
ColdFusion MX is now deployable on additional operating systems including Red Hat 8 and 9, SuSE 8, Solaris 9, and Windows 2003 Advanced Server. Additionally, deployment is possible on Mac OS X and AIX.
COM support was vastly improved with a new version of the JIntegra COM/Java bridge (1.5.3).
A new version of Apache Axis (1.1) is including, fixing several web services issues, adding support for SSL, proxies, and timeouts, and improving overall performance.
DataDirect JDBC driver were updated to 3.2 SP 1.
DataDirect SequeLink 5.3 ODBC Agent and Server.
Unicode is now supported in MS Access.
Updated Sun JVM (1.4.2).
Flash remoting updated to Updater 1 level.
Underlying JRun 4 updated to Updater 2 level.
cfchart engine updated.
Email engine has been totally overhauled. In addition to huge performance improvements (ability to send 1 million + emails an hour in Enterprise), several new features were added including connection pooling, multi-threaded message sending, backup mail servers, support for multi-part messages, SMTP authentication, and fail-to support.
CFC's get several major bug fixes and new features. The biggest improvements are the fix to the unnamed/variables scope (more on this later), the addition of a new super "scope" for referencing overriden methods and properties in a parent CFC, a fix for the dreaded page context bug, and the ability to set "global" methods for all CFCs on your server.
ColdFusion's built-in security mechanism has been updated to give you the option to tie cflogin's timeout to the session scope.
New releaseComObject() function for forcibly terminating a COM object connection.
New wrap() function for automatically wrapping text.
timeFormat(), lsTimeFormat(), dateAdd(), and datePart() now support milliseconds with a new mask (l).
getTickCount() now returns a counter representing the elapsed time in milliseconds from Unix Epoch (January 1, 1970, 00:00 GMT).
cfapplication tag now supports new loginstorage attribute, allowing logins to be tied to session scope or a cookie.
new xaxistype and yaxistype attributes added to cfchart tag.
cfdump tag has been updated to allow you to dump COM objects.
cfexecute has a new attribute called variable that you can use to specify a variable name to hold any output generated by the call. Previously, output could only be written to a file.
cfhttp was completely rewritten and now supports all HTTP 1.1 operations (get, post, head, delete, put, options, and trace). Additionally, cfhttp gets several new attributes: getAsBinary, multipart, proxyuser and proxypassword. Additionally, there are several new return variables available.
Two new attributes for the cfhttpparam tag: encoded and mimetype. Also, two new values for the type attribute in the cfhttpparam tag: body and header.
cfinvoke tag gets a few new attributes: proxyserver, proxyport, proxyuser, proxypassword, and timeout.
cflogin tag now supports HTTP Digest and NTLM authentication.
cfmail tag bonanza! New attributes include charset, failto, replyto, username, password, and wraptext. Additionally, you can now specify multiple servers (to act as backup servers) in the server attribute in the Enterprise edition. Also, type attribute was expanded to allow additional mime types to be specified.
cfmailparam tag upated to allow additional mime types in the new type attribute.
cfmailpart tag added to allow for multi-part mail messages.
cfpop can now retrieve multi-part mail messages.
MUCH, MUCH more!
Here's the best part about this release. If you have an existing ColdFusion MX license, the upgrade is completely free! I've been running it in a test environment for quite some time now, and I can say without any hesitation that this is the best, most stable release of ColdFusion ever!
In the self-promotions department, my new book, Programming ColdFusion MX (2nd Ed.) is set to ship on August 13th. O'Reilly specifically decided to hold publication to allow me to update it for MX 6.1. As far as I know, it's the only book on the market that covers all of the changes (and there are a ton) introduced in ColdFusion MX 6.1. I'll be posting more about the book in a few days.
If you are a Macromedia DevNet Subscriber, DRK4 is now available for download. If you aren't a subscriber, you can purchase it seperately. I've had a chance to check it out, and there are some really nice Flash and Dreamweaver MX components as well as several CF MX components, tags, and sample apps, including a complete polling application with a Flash front end and a CF back end. Very nice indeed.
Connect to DB2 on an AS400 (iSeries)? Then I want to hear from you!
Come on, I know you are out there! Seriously, if you use ColdFusion MX to connect to DB2 on an IBM AS400 (now called iSeries), I'd like to hear from you. Specifically, I'm interested in knowing your experiences. What database driver(s) do you use (JTOpem, DB2Connect, HIT, DiataDirect, etc). I'm also interested in hearing whether anyone has been able to get the DB2 driver that ships with CF MX to connect to DB2 for iSeries V5R2. The DataDirect docs state that it's supported, but I've been unable to get it to work.
Also, if you've actually gotten CF MX for J2EE to run on an iSeries Linux partition, I'd be interested in talking as well. IBM told me they know of one Macromedia customer who successfully did this, and it seems totally possible to me.
Feel free to contact me via the comments section of the blog, or directly at my email address (rbils@amkor.com).
Last night I had the pleasure of attending an AZCFUG (Phoenix, AZ) meeting. The topic of the evening was "Dynamically Creating PDF Files using XSL-FO and Apache FOP", given by Ken Johnson. For those of you who aren't familiar with XSL-FO, it's an XML technology for generating (among other things) printable documents from XML. Ken put together an excellent presentation, along with example code and several CFCs for generating PDF documents from both files and string input.
I have to say that this was one of the more informative and useful presentations I've seen in quite some time. This is just one more example of the power available to ColdFusion developers when you leverage ColdFusion's ability to easily integrate with Java. Hats off to Ken.
If you aren't already aware, I run the www.CFCZone.org Blog using a modified version of Raymond Camden's blog.cfc. Originally, I made several modifications to his core CFC to suit my needs. This soon became a problem, however, as each time Ray released a new version of his blog.cfc (either new features or bug fixes), I had to manually go through my version and compare it with his and try to incorporate the changes. Additionally, because Ray sets site specific variables in the "constructor" area of the CFC, you can't just replace your current blog.cfc with an updated version without copying and pasting your constructor code first. There is a better way.
The solution is to treat Ray's blog.cfc as a base component, and extend it with your own sub component. Your sub component should contain code that overrides the values set in Ray's constructor with your own. It can also contain your own version of any methods you want to behave differently than the versions Ray wrote. Additionally, if you want to add any new functionality to the blog.cfc without actually updating the base CFC, you can do it in the one you create.
In my case, I wanted a different version of the generateRSS() method found in blog.cfc. So, I created my sub component, called roBlog.cfc Here's the code for it:
In my CFC, all of my "constructor" code overrides the values set in the base CFC. This way, Ray can modify his CFC anytime he wants and I can upddate it on my site without having to worry about changing the values in the file. The only other thing to note is that instead of calling blog.cfc in all of my actual application code, I now call roBlog.cfc, since it's the main CFC and inherits everything else from blog.cfc.
As for the difference between my generateRSS() and Ray's? There are really two. First, my version uses the cfxml tag instead of the cfsavecontent technique Ray uses. The second difference is that my generateRSS() is context sensitivite. It allows you to generate a different RSS feed depending on what view of the blog you are in. So, on the main page, you get an RSS feed for the last 30 days worth of posts (the default). If you want an RSS feed of only CF related posts, all you need to do is click on the ColdFusion Category link, then click the XML button on that page.
In versions of ColdFusion prior to MX, you could override the default amount of time (if set) the ColdFusion server allowed a page to process before timing it out by appending ?requesttimeout=123 to the end of the URL for the page request. The value passed for requesttimeout indicated the number of seconds before the request should time out.
ColdFusion MX no longer supports this method for overriding the page timeout. In ColdFusion MX, the way to override the default timeout set in the ColdFusion Administrator is to use the new requesttimeout attribute of the the cfsetting tag. Because it may not be convenient to put cfsetting tags in each page you may need to override the timeout for, or you may not want to go back and change existing code you may have already written, there is a workaround.
Add the following code snippet to the Application.cfm page for your application:
It checks on each page request for a URL parameter called requestttimeout. If it exists and contains a numeric value, it writes an appropriate cfsetting tag.
Interesting Discussion on Required vs. Optional CFC/UDF Arguments
I sparked an interesting discussion on the cfcdev mailing list today. At issue is an inconsistency between the way the cfargument tag is documented and the way CF MX (updater 3) implements it.
The docs state that the required attribute of the cffunciton tag is "A type; if no argument is passed, specifies a default argument value. If this attribute is present, the required attribute must be set to "no" or not specified."
However, in implementation, the cfargument tag allows you to specify both required="yes"ANDdefault="some value". To me, this seems wrong. If we use ColdFusion's built in functions (BIFs) as an example, if an argument is required, then the function required you to pass it in. It does not set a default value in the event you choose not to pass a value in. If it does provide a default value, then the argument is optional.
Some posters on the list argued (and I can agree with this) that the required attribute is redundant in that if you specify a default value, then the argument is by definition optional. Unfortunately, since CF MX introduced the required attribute, I doubt Macromedia will ever take it away as it could break backward compatability. That said, I'd really like to see Macromedia "fix" cfargument in the next updater or release of CF MX so that it mirrors the behavior outlined in the documentation.
Last week, I upgraded one of my company's server clusters from CF 5 to CF MX. The install went fine. However, when I tried to apply updater 3 to both servers, it worked fine on one of them, but refused to install on the other.
I tried everything I could think of (initially) - I stopped all of the CF and IIS services ahead of time. I rebooted and tried again, nothing. Finally, I opened the task manager and noticed that an instance of jrun.exe was still running, even though I had stopped all CF services. Highlighting it and clicking End Process had no effect - I just got an access denied error message.
I was finally able to resolve the issue by setting all of the CF services to manual and rebooting the server. Once I did that, the jrun.exe process was no longer running and I was able to complete my updater 3 installation with no additional problems.
Programatically Determining the ColdFusion Root Directory in MX
In ColdFusion 5 (and older versions), you could use the CFREGISTRY tag to lookup the location of the ColdFusion install. This was a handy feature - especially if you wrote ColdFusion code to deal with files and directories under the ColdFusion root (not the web root) and didn't want to hard code the values.
In older versions of ColdFusion, the default install location was c:\cfusion. In ColdFusion MX, it's c:\cfusionmx.
Because CF MX no longer uses the registry to store configuration information, you obviously can't use CFREGISTRY to lookup the install location. There is, however, a new server variable that you can use instead:
SERVER.COLDFUSION.ROOTDIR
This variable gives you the full path to the ColdFusion root directory.
It appears as though ColdFusion MX has introduced a new bug with the CFDEFAULTCASE tag. In previous versions of ColdFusion (CF 5), the following code was valid:
x is 1
As of CFMX, the CFDEFAULTCASE tag with the trailing slash causes the following error:
Invalid CFML construct found on line 19 at column 18. ColdFusion was looking at the following text: />
The CFML compiler was processing:
a cfdefaultcase tag beginning on line 8, column 4. a cfdefaultcase tag beginning on line 8, column 4.
Of course this is easy to work around - just don''t use the CFDEFAULTCASE tag the way I''ve shown above. However, this makes me wonder whether CFMX has problems with other tags that are coded with the trailing slash. I know that CFMODULE works ok, but it would be interesting to test other CFML tags to see what happens...
I'm not sure if anyone else has already blogged this or filed it as a bug with Macromedia (I went ahead and filed it today), but there's a bug in the CFIMPORT tag when trying to import tags from a directory that's outside the web root directory. Normall, ColdFusion allows you to create mappings just for this reason--so that you can have tags like CFINCLUDE get files from outside the webroot withough having to expose those templates via URL. Basically, CFIMPORT is ignoring any mappings you set in the ColdFusion Administrator.
For example, if I create a directory for my custom tags that's outside of the /wwwroot (and not under the /web-inf directory), CFIMPORT ignores the mapping. So, the following code fails assuming my webroot is e:\inetsrv\intranet\wwwroot and my mapping is to e:\inetsrv\intranet\web-sys
The error I get is that:
Could not import the tag library specified by /web-sys/customtags/ui. The following error was encountered: E:\inetsrv\intranet\wwwroot\web-sys\customtags\ui
Now, if I put a template in that same directory and CFINCLUDE it, it works fine. This tells me that there's a bug in CFIMPORT seeing the mapping.
There are two "workarounds" to this. The first is to put the tags you want to import into the WEB-INF directory. I prefer not to do this because this is a directory CFMX creates in it's own directory structure, and it's location will vary depending on where you install CFMX. I'd also hate to see CFMX overwrite any of my files or directories at a later point.
The second workaround is to create the mapping in the jrun-web.xml file in addition to the CF Administrator like this:
/web-sysE:/inetsrv/intranet/web-sys
That works, but is obviously a problem for applications that need to be easily deployed to different servers and environments. I shouldn't have to manually edit a CFMX config file. Hopefully, this is something that's easy for Macromedia to fix and can be included in the next CFMX Updater.
As you know, or should know, when you pass in structures, or queries, or COM objects, or arrays of structs, to a UDF or Custom Tag, you are passing them by reference, not value. This means if you modify the value in the UDF or CT, the original is modified. Most of the time you don't care since you actually want to modify the original...
However if you want to work on a copy, you would need to use duplicate:
You should note that the same rule applies when returning values from a CFC - if and only if you are returning a persisted value. What does this mean? Imagine a persisted CFC (and this doesn't mean it exists in the application, sessiom, or server scope, it means ANY CFC that you have made an object instance of). Imagine that the CFC has a value that exists outside of the method, either in the This scope or in the private scope. Something like so:
If you create an instance of this CFC and then call get A, you will have a structure returned. However, if another method of the CFC modifies this A, it will modify your structure as well. To correct this, simply add duplicate to the return tag:
I've seen a few posts from developers on the Macromedia Forums lately complaining that they can't get CFCHART to display dates on the y-axis. Since I'm finishing up the CFCHART chapter of my book right now, I decided to look into this. It turns out, that this functionality is not at all documented in any of the Macromedia documentation, nor anywhere else that I can tell. After spending a few hours trying to figure out what CFCHART could possibly want as it's date values, I finally figured it out. For some reason, you can't pass dates in formats like mm/dd/yyyy. My next thought was to try a numeric format, so I tried CF MX's new getNumericDate() funciton. That didn't work. Next, I thought of using Epoch seconds. I tried a random Epoch time, but the date CF showed in the chart was about 32 years off! After more messing around, I finally hit on the solution. You need to take your date, convert it to Epoch seconds adjusted for your UTC offset, and multiply that number by 1000. I'm not sure why you have to multiply by 1000. The only thing I can think of is that the 1000 represents milliseconds tacked on to the date. Go figure.
So, here's some code that illustrates how to make it all work:
/** * Returns the number of seconds since January 1, 1970, 00:00:00 (Epoch time). * * @param DateTime Date/time object you want converted to Epoch time. (Required) * @return Returns a numeric value. * @author Rob Brooks-Bilson (rbils@amkor.com) * @version 1, June 21, 2002 */ function GetEpochTimeFromLocal() { var datetime = 0; if (ArrayLen(Arguments) eq 0) { datetime = Now(); } else { datetime = arguments[1]; } return DateDiff("s", DateConvert("utc2Local", "January 1 1970 00:00"), datetime); }
/** * Returns the number of seconds since January 1, 1970, 00:00:00 * * @param DateTime Date/time object you want converted to Epoch time. * @return Returns a numeric value. * @author Chris Mellon (mellan@mnr.org) * @version 1, February 21, 2002 */ function GetEpochTime() { var datetime = 0; if (ArrayLen(Arguments) is 0) { datetime = Now();
Bug Passing Arrays by Value to Tag Based UDFs in CFMX
I was finishing up the example code for my DevCon presentation on User Defined Functions in ColdFusion MX when I discovered what looks like a bug in how tag based UDFs treat arrays passed in as arguments. ColdFusion is supposed to pass arrays by value, meaning that a copy of the array is passed. This means that anything the UDF does to the array affects only the copy of the array, and not the original. In CFMX tag based UDFs, however, it looks like arrays are being passed by reference, meaning that a reference to the original is being passed in, and not a copy. This means that any modifications the UDF makes to the array are actually made to the original as well. This can be a bad thing if you aren't expecting it. To demonstrate, check out the following code:
Before
Inside the UDF
After
If you look at the "After", you'll notice that the 4th array index is still there - and it shouldn't be. This has been logged as a bug with Macromedia.
As a workaround you can make your UDF in CFSCRIPT as script based UDFs aren't affected. If you must have tag based functionality, you can work around the problem by making a copy of your array first using the duplicate() function.
In CF5, when deleting from a Verity collection, you could pass a value as the key, like so:
However, in MX, you MUST pass key as a column name and pass a query in. This means if you want to delete one item, you need to create a temporary query to store the value. The syntax would look like so:
(note, "key" above is a variable that represents the key you want to delete from the index)
Man, I should start calling this a Verity Blog. I've got another little Verity tidbit you Verity junkies might find useful. I first published this in my book, Programming ColdFusion (O'Reilly), but have recently updated it for the forthcoming 2nd edition.
If you use Verity to index and search XML documents, you might have ocassion to want to map the contents of a particular XML tag to one of the ColdFusion fields defined by Verity (CF_TITLE, CF_URL, CF_KEY, CF_CUSTOM1, and CF_CUSTOM2). For example, by defualt, if you index an XML file with Verity, the CF_TITLE field doesn't get populated, which can make your search results less than useful. With a little coding magic, you can easily get Verity to map any XML tag in your document to a ColdFusion field. This means that if you have an XML document with a "title" tag, you can have verity map it to the CF_TITLE field. How? Here's the skinny. Consider this XML file - save it and name it whatever you want:
Programming ColdFusionRob Brooks-BilsonO'Reilly
To map the title tag to the CF_TITLE field, you need to create a file called style.xml and place it in your style directory: either c:\cfusionmx\lib\common\style\file for all file-based collections or c:\cfusionmx\verity\collections\my_collection_name\file\style where my_collection_name is the name of the Verity collection containing the index for your XML files. The style.xml file should look like this:
Stop and Start your CF Server service, then reindex your collection. Now when you search it, the contents of the XML title tag should appear in the CF_TITLE field when output. There's a lot more that can be done with the style.xml file. When I get more time, I'll post what else I know about it.
The highly anticipated "updater" for CFMX was released last night. This is the first updater (replaces service packs) for ColdFusion MX and contains fixes for a decent number of issues, including several COM fixes. You can read the release notes and download the updater here. From personal experience, I can say that the COM fixes corrected a number of issues I was having with COM objects and CFMX. I'm also very pleased that a number of CFMAIL related issues I submitted as bugs after CFMX was released appear to have been fixed in this update. Kudos to Macromedia!
Since I seem to be working a lot with Verity again lately, I thought I'd pass along another bug I found recently. There's a bug in the Verity search engine in MX that wasn't there in CF 5. The bug has to do with using CFSEARCH to search document fields. You are supposed to search the defined fields CF_TITLE, CF_KEY, CF_URL, CF_CUSTOM1, and CF_CUSTOM2 using operators and modifiers in the CRITERIA attribute of the CFSEARCH tag like this:
This should return all documents containing "LDAP" in the title as defined in the CF_TITLE field. This works as intended in CF 5. However, it is broken in CFMX. In CFMX, it returns no results (I indexed the ColdFusion Docs), when the collection clearly contains documents with "LDAP" in the title.
There is a workaround. For some reason, if you change the CRITERIA to "TITLE LDAP", the search works correctly. I've submitted this as a bug to Macromedia, so we'll see if it gets fixed in a future updater.
CFMX Behavior Change: Verity and Explicit Searches
This isn't CFC related, but I wanted to get this out there before I forget about it. I found an interesting behavior change today in CFMX. It's one that might cause you a lot of grief if you aren't aware of what's happening. The "behavior" has to do with EXPLICIT searches in Verity. There was a bug in previous versions of ColdFusion that caused explicit searches to actually execute as simple searches. What's the difference? Well, a simple search employs the STEM operator and MANY modifier by default. So, searching for test returns matches for test, tests, testing, tested, etc. An explicit search, however, does not employ STEM and MANY. So, a search for test returns only docs containing test, and not testing, tests, etc.
Now for the behavior change. Explicit searches are now working as intended in CF MX. This could cause problems for existing apps that are ported to MX, as well as new apps that are written that use explicit searches. There are really two parts to this issue. The first issue is that search terms have to be surrounded by quotation marks in explicit searches. So, the EXPRESSION="test" that works in a simple search throws an error when used in an explicit search. To search for test in an explicit search you have to code the search as EXPRESSION="'test'".
The second issue has to do with using various operators in an explicit search. In a simple search, using EXPRESSION="'f[eo]llow'" returns matches for fellow and follow only (note that stemming is off). Note the single quotation marks around the wildcard criteria. This syntax fails in an explicit search. In order to perform the same search in an explicit search, you must use the backquote (`) and not the single quote like this EXPRESSION="`f[eo]llow`". Even though the single quote works in a simple search, you should consider only using the backquote to ensure compatibility should you ever switch from a simple to an explicit search.
CFLib.org
Raymond Camden's Blog
Christian Cantrell's Blog
Sean Corfield's Blog
Nathan Dintenfass' Blog
Todd Rafferty's Blog
Steve Rittler's Blog
Cameron Childress's Blog