ColdFusion users have long wanted a way to define settings per application, rather than server-wide, even within a shared instance. ColdFusion 8 introduced the beginnings of per application settings via Application.cfc (which we introduced in CF7).
To set application settings using Application.cfc, variables are set in the THIS scope. THIS.name to set the application name, THIS.sessionManagement to enable session state management, and so on. In CF8, Application.cfc and the THIS scope can be used to define per application settings. For example, THIS.mappings is a structure which can be used to define ColdFusion mappings. To set a mapping you just modify that structure like this:

To set the Custom Tag path you can update THIS.customtagpaths which is a simple ColdFusion list. You can set the path like this:

Or use ListAppend() to add a path, like this:

It’s clean, simple, highly intuitive, and in CF8, limited to just those two settings – mappings and customtagpaths.
In CF9 (aka Centaur) we may have the opportunity to enhance this functionality. And actually, we’ve already started doing so. For example, at MAX in Europe I mentioned that CF9 allows for THIS.datasource to be defined as a default datasource, eliminating the need to specify the datasource for each and every query. And that’s just an example.
There are others I’d like to see, starting with THIS.logdirectory to set a log file location per application. But, rather than my list of settings, I am interested in yours.
Now, this should go without saying, but I’ll say it anyway. When discussing a future product there is no firm commitment being made about any features. Stuff can, and usually does, change. But, having said that …
What are the settings you’d like to see us support per application in CF9? Feel free to list multiple, but be sure to define them in the order of priority.
(Oh, and before the thread goes off on a tangent, yes, I know we need a way to define on-the-fly datasources as you could in CF5. But no, these are not technically application settings, and are out of scope for this thread).

21 thoughts

  1. I’ve said this many times, but once again for the record I’d like to see app specific class paths. This would point to a directory of Java classes that would be dynamically loaded and available to the application without the use of a 3rd party java loader and without the need to drop them in the existing class path.

  2. I would second the application setting for logfile location.
    Perhaps a temp folder for application specific results from GetTempDirectory(). I know when operating on a shared host there’s no point to using the temp directory.

  3. Ben, I love the datasource setting. Wish it was there since day one.
    It would be nice to be able to specify some other default settings for tags.
    For example cfmail (server), cfpop, cfftp, those that do make sense.

  4. Andrew: Technically you can do that in 8 – though you have to be a little crafty. You’d basically set a struct of settings in the app scope, then pass that scope as an attributeCollection each time you call the tag.

  5. It would be good to be able to specify proxy server/port/username/password settings in the application scope and have it automatically used by CFHTTP. I used to forget to include our proxy settings regularly 🙂 But this would be particularly helpful where third party code or open source apps are used in a firewalled environment by removing the need to modify the third party code at all, and having the settings specified once in application.cfc and used automatically.

  6. THIS.pageEncoding so I can tell CF that all pages in the site use UTF-8 … it gets kinda old putting cfprocessing directives at the top of every page, include file, etc.

  7. If Adobe chooses to implement dynamic class loading as an application specific setting, please make sure it can be dis-/enabled separately from all the other functionality because of the security implications. I find it very likely that many hosters will want to enable per application mappings, customtag paths etc., but not per application classloading.
    I would like to see per application datasources. Not in the way that I can define which datasource my queries use, but in the way that I can specify a driver, host, port, database, username and password and that the datasource is accessible to me without being defined in the CF Administrator. Like we used to be able to do in CF 5 …

  8. Jochem: Have you checked out the Admin API? You can create datasources on the fly pretty easily without ever opening the administrator.
    You could write a UDF that runs onApplicationStart and checks for the existence of the per-application datasource definition(s) you want to use (a particularly named structure in the this scope to be used as an argument collection to the Admin API methods), then checks to see if the datasource is already defined on the server (Admin API), then creates it if not (Admin API). You’d just drop the UDF into Application.cfc and your application becomes portable (as long as you have a mechanism in place to feed the administrator credentials into your UDF on each server you plan to deploy on).
    The code examples on this page show how to create datasources programmatically with the Datasource.cfc component.
    http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=basiconfig_37.html

  9. Has anyone noticed that the custom tags mapping does not seem to work in the J2EE installation of ColdFusion? It works on my local standalone version but not when I deploy it to my instance where CF runs under JRun. Thanks!

  10. Application level mappings are not honored everywhere that server mappings are (e.g. cfimport@taglib). I understand why that is (compile time vs. runtime). Nevertheless, the existing feature is of very little use to me. In fact, I’ve never found a situation where I could use it. Perhaps, instead of adding new features, polish up the existing ones. I understand that it might be necessary to come up with a different solution altogether (something like ASP.Net’s Web.config file that can be read at compile time). That’s fine. But I’d really like first class application level mappings. You could stop there and I’d be happy.

  11. My feature request isn’t for application specific settings, but for <cfquery>. I don’t know if there’s a better place to request this, so I’ll request it here.
    In addition to the default query object result set that <cfquery> currently returns, I’d like to see the option to return an array of value objects. Not just a standard value object, but the ability to pass a value object that gets populated. This can have 2 major advantages. I’ll explain.
    For example, to enable this, I would specify a recordObject attribute in my <cfquery> tag:
    <cfquery name="users" datasource="#request.dsn#" recordObject="myApplication.vo.UserVO">
    SELECT firstName, lastName
    FROM users
    </cfquery>
    This would return an array with each index storing a UserVO that represents a single record in the DB.
    When I create UserVO.cfc, I would create a setter that represents each column/property from the db table, like setFirstName(), setLastName(), etc. When pass the object to cfquery, these setters would be implicitly invoked based on columns specified in the SQL statement.
    So, WHAT ARE THE ADVANTAGES?
    1) Flex – I no longer have to loop over a query object to create an array of objects with CF or an array of structures with a __type__ key; what I get back from <cfquery> will be flex ready.
    2) Dynamic Properties – In the object that I pass to <cfquery> I can have additional getters that don’t pertain to column in the db, but may act upon data that’s returned.
    For example, my object could have a getter called getFullName that concatenates getFirstName() with getLastName(). I could also have getters that perform date calculations based on data returned from the database. This is just a couple of examples, but I think this could be very valuable. This can be very advantageous to moving logic away from the view and into an object that represents the data.

  12. Not sure if this is appropriate here, but I’d like a way to cache singleton object instantiations (application.Order for example) on my production server but have them loaded dynamically on a non production server.
    /m

  13. Mischa: The easiest way to do this is to move all of your singleton instantiations into their own function within Application.cfc (I usually call mine reset) and call that function in onApplicationStart.
    Then, in onRequestStart you have a check to see if isDefined(‘url.reset’) and cgi.remote_addr is your IP and if so call the reset function.
    To cache on production and reinitialize on every request on development, you can then either:
    1. Append an or true to your onRequestStart check in the development copy (quick and dirty method: requires remembering to remove it when you move the code to production)
    or
    2. Use the domain name or other server variables to differentiate which server you’re on in the check and only reinitialize on the development server.

  14. I just commented on this exact post from Scorpio (http://www.forta.com/blog/index.cfm/2007/4/24/Scorpio-Per-Application-Settings#comments) and then found this nice new vibrant and current post of the exact same topic for Centaur – how nice 🙂 So I thought I would post my Q here and maybe it will get read sooner 🙂 Sorry that is moe of a support Q then an answer to the blog Q posted. but here it is ….
    I have the same troubles as Ameen except I already tried using the this.customtagpaths. I have the following code set:
    this.customtagpaths=ListAppend(this.customtagpaths, "#getDirectoryFromPath(getCurrentTemplatePath())#orgewsudf") ;
    and it returnes the following error:
    Element CUSTOMTAGPATHS is undefined in THIS
    So why am I getting this error when everyone else seems to be touting this nice feature? Is there maybe a setting on my local dev machine that needs to be edited? I can’t find one.
    thanks all,
    Chris

Leave a Reply to Mischa Cancel reply