I'm in the process of switching over from using Application.cfm to Application.cfc and I'm using Ben Nadel's method for extending my application into a sub folder using an application proxy. (link to article)
The problem I'm having is that when I load a page in a sub folder all cfinclude tags that are called in the root Application.cfc file bring up a "Could not find the included template..." error message. (The include is intentionally at the top of the component so I can set application specific variables)
Here are a few requirements:
- The application has to be run without access to the ColdFusion administrator.
- The application may or may not reside in a sub folder of another site (i.e. www.example.com/ or localhost/mysite/)
Here's the file structure:
- /application.cfc
- /include_me.cfm
- /index.cfm
- /sub/application.cfc
- /sub/application_rootProxy.cfc
- /sub/index.cfm
Root Application.cfm:
<cfcomponent
output="false"
hint="I define the application settings and event handlers.">
<!--- Define the application settings. --->
<cfset this.name = "TestApplication" />
<cfset this.applicationTimeout = createTimeSpan( 0, 0, 10, 0 ) />
<!---
Store the path of the current template. We want to see if
this shows up as the root template or the sub template.
--->
<cfset this.ROOT_currentTemplatePath = getCurrentTemplatePath() />
<!--- Set a variable to indicate that the included file hasn't been run yet --->
<cfset this.includedFile = "no" />
<!--- include the file --->
<cfinclude template="include_me.cfm" />
<cffunction
name="onApplicationStart"
access="public"
returntype="boolean"
output="false"
hint="I initialize the application.">
<!--- Set some app variables for testing. --->
<cfset application.ROOT_onApplicationStart = true />
<!--- Return true so the page can process. --->
<cfreturn true />
</cffunction>
<cffunction
name="onRequestStart"
access="public"
returntype="boolean"
output="false"
hint="I initialize the request.">
<!--- Set some request variables for testing. --->
<cfset request.ROOT_onRequestStart = true />
<!--- Return true so the page can process. --->
<cfreturn true />
</cffunction>
<cffunction
name="onRequest"
access="public"
returntype="void"
output="true"
hint="I process the user's request.">
<!--- Define arguments. --->
<cfargument name="script"type="string" required="true"hint="I am the request script." />
<!--- Output the current THIS collection. --->
<cfdump var="#this#" label="THIS" />
<!--- Include (execute) requested script. --->
<cfinclude template="#arguments.script#" />
<!--- Return out. --->
<cfreturn />
</cffunction>
</cfcomponent>
Root Include_me.cfm:
<!--- update the value so we know the file was indeed included --->
<cfset this.includedFile = "yes" />
Sub Folder Application.cfc
<!--- extends the application so we can make changes when needed --->
<cfcomponent extends="application_rootProxy">
<cfset this.SUB_currentTemplatePath = getCurrentTemplatePath() />
</cfcomponent>
Sub Folder Root Proxy:
<cfinclude template="../application.cfc">
What is the correct way to allow cfinclude tags in the base application.cfc when you're accessing the application through a root proxy?
My initial instinct was to see if I could calculate the application root dynamically and luckily getCurrentTemplatePath() is able to differentiate between the sub application.cfc and the root application.cfc. However cfincludes don't work when you try and access them via a local file system link (e.g. d:\mysite\include_me.cfm). It looks like I need to somehow figure out the dynamic relative position of the included file based on the sub directory of the executing application.cfc. Any and all help is appreciated!
I may be on to something... and if this is the answer hopefully it will help someone else out who finds themselves in a similar predicament.
I noticed that the cfinclude within the OnRequest() method processes normally regardless of whether the template is being called from the root of the application or a sub directory. Therefore I theorized if I put my cfincludes within methods they might execute properly.
So instead of placing my cfincludes at the top of my root component:
I can put them in a separate method and then call that method within the component:
The key to this seems to be not including anything in application.cfc unless it's contained within a method.