Skip to main content
Inspiring
April 5, 2012
Question

Application.cfc, THIS.mappings & cfinclude

  • April 5, 2012
  • 3 replies
  • 10055 views

hi there

In my Application.cfc

<cfcomponent>

  <cfscript>

    THIS.name = "myName";

    {etc.}

    THIS.mappings = StructNew();

    mappingname = "/include";

    mappingpath = "Z:\webincludes\didi\test\aaisession\appcfc";

    THIS.mappings[mappingname] = mappingpath;

  </cfscript>

  

  <cfinclude template="/include/appcfc-onApplicationStart.inc" >

    {etc.}

does not work!

When I do the mapping in CFadmin, it works. But I need to do it on an application base.

Is this due to the fact, that at the time CF tries to resolve the path of the template, the mapping has not yet been assigned?

How can I overcome this?

-Didi

This topic has been closed for replies.

3 replies

Inspiring
April 9, 2012

Regarding:

In my Application.cfc

<cfcomponent>

     <cfinclude template="/include/appcfc-onApplicationStart.inc" >

I find that strange.  Why would you not have an onApplicationStart method in your cfc?

Didi3Author
Inspiring
April 9, 2012

Dan:

I just wanted to get a lean Application.cfc, since I do not like to scroll around in codefiles having hundreds of lines.

I prefer smaller code chunks - that's actually all behind it

Now it looks the way as you see below ...

BTW: Do you work with CFB2? What version control system are you using?

-Didi

___________________________________________________________________________

<cfcomponent>

  <cfscript>

    THIS.name = "myName";

    {etc.}

    THIS.mappings = StructNew();

    mappingname = "/include";

    mappingpath = "Z:\webincludes-outside-webroot\appcfc";

    THIS.mappings[mappingname] = mappingpath;

  </cfscript>

  <cffunction name="onApplicationStart">

    <cfinclude template="/include/appcfc-onApplicationStart.inc" >

  </cffunction>

  <cffunction name="onApplicationEnd" >

    <cfinclude template="/include/appcfc/appcfc-onApplicationEnd.inc" >

  </cffunction>

  <cffunction name="onSessionStart" >

    <cfinclude template="/include/appcfc/appcfc-onSessionStart.inc" >

  </cffunction>

  <cffunction name="onSessionEnd" >

    <cfargument name="SessionScope" required=true />

    <cfinclude template="/include/appcfc/appcfc-onSessionEnd.inc" >

  </cffunction>

  <cffunction name="onRequestStart" >

    <cfinclude template="/include/appcfc/appcfc-onRequestStart.inc" >

  </cffunction>

  <cffunction name="onRequestEnd" >

    <cfinclude template="/include/appcfc/appcfc-onRequestEnd.inc" >

  </cffunction>

</cfcomponent>

<!--- ***** END of Application.cfc ***** --->

Inspiring
April 9, 2012

I'm not sure if this has been mentioned, but I'd extend the Application.cfc rather than doing includes. It's not necessarily better or worse, but I think it makes more sense programmatically. Like so:

[ApplicationBase.cfc]

<cfcomponent>

  [onApplicationStart, other CF methods]

</cfcomponent>

[Application.cfc]

<cfcomponent extends="ApplicationBase">

  [your own business methods]

</cfcomponent>

They can also extend each other, so you could have Application.cfc extending ApplicationBusinessMethods.cfc which in turn extends ApplicationCoreMethods.cfc which extends ApplicationBase.cfc, which has the built-in CF methods.

Just another little something to throw into the mix there

O.

PS: CF Builder 2, VisualSVN Server and TortoiseSVN


I'm not sure if this has been mentioned, but I'd extend the Application.cfc rather than doing includes. It's not necessarily better or worse, but I think it makes more sense programmatically. Like so:

Yep, using inheritance would be preferable to using includes in the way Didi is currently doing it, although it's kinda contorting the notion of inheritance a bit.  However just not doing either would be better here, I think.

I could possibly see doing something like this as passable:

// ApplicationEventHandlers.cfc

component {

          this.name = "myApp";

          // etc

          function onApplicationStart(){

 

          }

 

          function onApplicationEnd(){

 

          }

}

// SessionEventHandlers.cfc

component extends="ApplicationEventHandlers" {

          function onSessionStart(){

 

          }

 

          function onSessionEnd(){

 

          }

}

// RequestEventHandlers.cfc

component extends="SessionEventHandlers" {

          function onRequestStart(){

 

          }

          function onRequest(){

 

          }

          function onMissingTemplate(){

 

          }

          function onError(){

 

          }

 

          function onRequestEnd(){

 

          }

}

However this is abusing the notion of inheritance I think.  And as per my previous post, basing one's architecture on developer-laziness is not something I'd engage in.  I'd just smarten-up my approach to my work practices/ethics.

--

Adam

BKBK
Community Expert
April 8, 2012

OK. It just might be that ColdFusion isn't happy that the mapping is at once being set (written) and used (read) in the pseudo-constructor. What if you move the cfinclude tag to onRequestStart or, perhaps more appropriately, to onApplicationStart? Then it will run only after Application.cfc has been instantiated.

Inspiring
April 8, 2012

BKBK:

The <cfinclude> is including the onApplicationStart() handler.  So kinda needs to be included from the body of Application.cfc.

I suspect this won't work for the very reason the OP suspects.

Didi:

The way to overcome it is to not factor your onApplicationStart handler out into an included file.  Why are you doing that?

--

Adam

BKBK
Community Expert
April 8, 2012

Adam Cameron. wrote:

BKBK:

The <cfinclude> is including the onApplicationStart() handler.

Does it? Sorry, I missed that. Likely because I don't quite understand Didi's passage about inner/outer space.

BKBK
Community Expert
April 8, 2012

You can do it in Application.cfc. However, you first have to go to the page Server Settings => Settings in the administrator, and check the option 'Enable Per Application Settings'.

On a separate note, what's the deal with the INC extension in the Application file? This might force the browser to display or download. It is best practice to avoid such presentation code in the application file.

Didi3Author
Inspiring
April 8, 2012

Hi BKBK

not searching for eggs at these days  ?

'Enable Per Application Settings' ist checked.

Believe me (at least on my server ..)

    <cfinclude template="/include/appcfc/appcfc-onApplicationEnd.inc" >

is not working as long as the <cfinclude ..> is in the 'outer space' of the Application.cfc.

The idea is to implement the events inside includes.

On the other hand:

  <cffunction name="onApplicationEnd" >

    <cfinclude template="/include/appcfc/appcfc-onApplicationEnd.inc" >

  </cffunction>

where I declare the event in the 'outer space' of the Application.cfc and I only put the body of the event of the include, it works.

So I think my theory gets more meat on the bone.

-----

now to your note of accessing the include:

Why not an INC extension to viualize the difference between a directly called CFM page and an include?

It just makes it more visible ...

  http://server/include/appcfc-onApplicationStart.inc


doesn't expose the include file. The mapping is CF internal only - Apache does not know about this.

That's why I took it outside the webroot.

  Z:\webincludes

is parallel to

    Z:\webroot

-----

our goal is structuring code and not putting all in one huge Application.cfc, since out onXxxStart events are quite long.

How would you do that?

-Didi