Two quick Application.cfc questions

This post is more than 2 years old.

This week I got two simple Application.cfc questions that I thought would be interesting to write up. The first one is from Gary and asks:

In Application.cfc
<cfset this.name = "MyFancyName" />

There is also:
<cfset application.name = "MyFancyName" />

What is the difference?

Inside the Application.cfc there is a difference between what you set in the This scope versus what you set in the Application scope. The This scope, within Application.cfc, is used to setup and configure the application. Therefore, when you set this.name = "whatever", you are naming the Application globally across the server. Application.name, however, is nothing special. It is simply a value within the Application scope and does not have any impact on the behavior of the application itself.

Not to make things confusing - but when you name your application, ColdFusion copies the name to the Application scope in a key called applicationname. So given the pseudo-code above, if you dump the Application scope you would see name and applicationname as values.

Now for the second question. Ken asked:

I'm calling an application via cfmodule but I can't get it to use the application.cfc page. The structure is as follows:

webroot (folder)
index.cfm

myapp (folder {under web root folder})
application.cfc
default.cfm

index.cfm code as follows
cfmodule template="myapp/default.cfm" lhn="1"

In the application.cfc file I have session variables, one of which is lhn which I want to assign the value passed in the cfmodule tag.

But it does not seem to use the application.cfc file and thus no session exists.

Good question. It all comes down to the question of - when is Application.cfc/cfm run? The answer is only for network requests. In order for an Application.cfc to fire there must have been a network request to a resource. cfmodule (or cfinclude) will not execute a network request and therefore not execute the Application.cfc file. I hate to say it - and as soon as I type it I'm going to regret it - but you may consider using a cfhttp call to your other application to fetch the data you need. Or - update your custom tag to support running in a "non-initialized" form. Ie, the custom tag could handle noticing it doesn't have Application variables it needs and can handle setting it up itself - possibly within a subkey so as to not overwrite things in the current application. It could possibly also make use of the Server scope, which could be a handy way to handle App to App communication on a box.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Chris Tierney posted on 2/11/2011 at 7:47 PM

Thanks Ray for these two Q/A's. Your first answer brought to light something I didn't know. However I'm not sure exactly what that means. Can you provide an example of the differences? Thanks.

Comment 2 by Raymond Camden posted on 2/11/2011 at 7:48 PM

The differences between what? The This Scope and the Application Scope?

Comment 3 by Chris Tierney posted on 2/11/2011 at 8:18 PM

Yes - the this scope and the application scope.

Comment 4 by Raymond Camden posted on 2/11/2011 at 8:22 PM

I feel like I failed in my explanation. :) In terms of Application.cfc, the This scope expresses the _behavior_ of the Application. What's the name - what are custom tags paths - whats the common datasource name. Etc.

Application scope variables are simple name/value pairs. Application.foo = "goo". Etc. They do not impact how the application behaves at the server level. (Technically they can impact your app if your app does different things based on application variables, but I'm talking about _built in_ behavior.)

Comment 5 by Carlos posted on 2/11/2011 at 8:31 PM

Hi Ray, I have a (dumb?) question related to this:

Back when there was no Application.cfc. only Application.cfm, there were occasions when it was proper to cfinclude – in Application.cfm – another Application.cfm that was higher up in the directory hierarchy. Can this somehow be done when using Application.cfc?

I have not been able to figure out how to do this, the result being that I have separate Application.cfc’s in different folders, but sometimes one is practically a duplicate of the other.

I hope I am making myself clear.

Comment 6 by Bill King posted on 2/11/2011 at 8:48 PM

Ray,

For the second question about looking for a session variable within a module, would it not be a better practice to send in the session var as an attribute of the cfmodule as follows?

<cfmodule template="myapp/default.cfm" lhm="#session.lhn#">

Comment 7 by Raymond Camden posted on 2/11/2011 at 8:52 PM

@Bill King: If we assume that you build some custom tag API for the App, then yes, you would want to pass the session var like that. The other app cannot/should not know about your session vars.

@Carlos: App.cfc _can_ extend other App.cfcs. I know Ben Nadel just recently did a blog post on this and Sean Corfield also has. Personally - I've never really needed the functionality myself.

Comment 8 by Carlos posted on 2/11/2011 at 9:09 PM

Thanks Ray, exactly what i was looking for.

Comment 9 by Brian O. posted on 2/12/2011 at 3:29 AM

Perhaps Ken, your second questioner, just needs to define his variable as a session or application variable (depending on variable's lifespan needs) in a root level Application.cfc. I use the extends attribute to 2 levels (its limit at least in CF8) in my main work application web portal of a couple dozen systems/applications that I help to develop/manage. It works great and I'm able to inherit or override (using 'super') the methods and properties 1 to 2 levels up as needed depending on the system. I have not tried to go in the other direction, but I suppose it would be possible. I'm not saying Ken should do it this way, but it is probably an option. I have a root level application.cfc that we'll say exists at a mapping of 'webroot'. In the first lower level folder like Ken we'll call myapp, I have an Application.cfc with <cfcomponent extends="webroot.Application" ... > . I also have an application with a subfolder we'll say called mysubapp with an Application.cfc with <cfcomponent extends="webroot.myapp.Application" ... > . Using these I'm able to reduce the duplication of methods and properties and take advantage of OO inheritance.

Comment 10 by Gary Funk posted on 2/12/2011 at 5:14 AM

Here is a follow up question. Is there wa way for application A to share application variables with application B?

Comment 11 by Brian O posted on 2/12/2011 at 5:59 AM

I would look at using cfinterface, which I have yet to need, if you are talking a 2-way transaction, which I assume. One way could be done many different ways.

Comment 12 by ppshein posted on 2/13/2011 at 4:17 PM

Here is application.cfc
<cfset this.name = "MyFancyName" />

Here is index.cfm in the same root
<cfoutput>#this.name#</cfoutput>

Got error. I cannot convince why. So, I've tried the another way like in index.cfm
<cfoutput>#application.name#</cfoutput>

Got error also.

Comment 13 by ppshein posted on 2/13/2011 at 6:00 PM

Sorry, Ray. I got the answer.

Another question is when I defined <cfset this.datasource = "PPShein" /> in application.cfc, how can I get this.datasource value in index.cfm?

Comment 14 by Ken Caldwell posted on 2/14/2011 at 3:21 AM

@Ray: Thank you for your help. In the end I just needed to ensure that the session variable was defined.

@Bill King: I did pass through the lhm, but it is a hard coded value. As there is no Application.cfc (in fact there is only one cfm page) at this level there is no session scope so you can not pass through a session var.

@Brian O: This is two distinct applications, well really a base level Intranet home section. That is menu, banner footer and home page. with the home page containing the other application. It's a notice board.

On another note, the reason I used cfmodule in the first place was because using cfdiv with bind the spry dataset would not load.

Ken

Comment 15 by Raymond Camden posted on 2/14/2011 at 4:57 AM

@PPshein: Unfortunately, there is no way to get the datasource value set in the DSN. The whole point of that feature (normally) is to set it so you don't need it elsewhere. If you need it, I'd just set it in the app scope as well.

Comment 16 by Peter Hoopes posted on 2/14/2011 at 11:28 PM

For Ken, aside from creating another level of application.cfc (which another poster posited), another option is to simply pass the session variable you need as an argument in the cfmodule tag. Then the myapp/default.cfm can read from the arguments struct and go from there.

That is, unless I missing something here.

Comment 17 by Ken Caldwell posted on 2/15/2011 at 3:14 AM

@Peter Hoopes: The session variables are created when a user/admin logs into the system. Because of the nature of the system I would have to create a structure with default values and pass that through as an argument. It is easier just to check that the session vars are defined. Initially I just assumed that cfmodule would invoke the application.cfc, which I now know it will not.

Ken

Comment 18 by Misty posted on 2/21/2012 at 5:44 PM

Hi Ray, I have a question here,

we are on colfusion 9 but not using the Application.cfc, we are still using Application.cfm

Now the thing is we have cfmails defined everywhere and i do not know at how many places, we want to use the this.smtpserversettings feature of cf9 in application.cfm file, how will i declare this in application.cfm file

Comment 19 by Raymond Camden posted on 2/21/2012 at 6:03 PM

You can't do it. I'd recommend just simply switching to Application.cfc.

Comment 20 by Misty posted on 2/21/2012 at 6:15 PM

u mean to say simply there is no other way

if i can create application.cfc and onrequeststartmethod call my application.cfm, will that work and will it have any side effects

Comment 21 by Raymond Camden posted on 2/21/2012 at 7:25 PM

You should be able to. Don't forget to remove the cfapplication tag from application.cfm.

Comment 22 by Misty posted on 2/21/2012 at 7:47 PM

ok, so like the above i an do the <cffunction name="onrequestStart()">

<cfinclude template="application.cfm">

</cffunction>

thopugh this will not effect the sessions and other variables defined in the website

Comment 23 by Raymond Camden posted on 2/22/2012 at 9:34 AM

Well, sure, that may work. It really depends on whats in your file, but it may work. Again, remove the <cfapplication> tag.

Comment 24 by Pankaj posted on 2/14/2013 at 4:51 PM

@ppshein In Cf9 you can get this.datasource value in index.cfm via #application.getApplicationSettings().datasource#

Comment 25 by Gordon Frobenius posted on 4/21/2016 at 1:57 PM

"Not to make things confusing - but when you name your application, ColdFusion copies the name to the Application scope in a key called applicationname."

So I'm assuming they are not consistent about this. For example: I want to use this.secureJSON and this.secureJSONPrefix. But when I do, in my protection function which actually does the check, I cannot access application.secureJSON or application.secureJSONPrefix. So I'm going to have to create both sets of variables (this & application) and set the identically. Do you know of a better way?

Comment 26 (In reply to #25) by Raymond Camden posted on 4/21/2016 at 2:30 PM

If you are talking about reading application settings like this, ColdFusion added GetApplicationMetadata just for that purpose.

Comment 27 (In reply to #26) by Gordon Frobenius posted on 4/21/2016 at 3:54 PM

Just what I needed. I need to keep up with new crap like this better. You da man. Thanks!

Comment 28 (In reply to #27) by Raymond Camden posted on 4/21/2016 at 4:10 PM

No problem. To be fair, I think this was added in CF10, so not terribly new.