Skip to main content
Inspiring
May 20, 2011
Answered

Application.cfc and directory mapping

  • May 20, 2011
  • 2 replies
  • 3429 views

Hello,

We have an application that we would like to migrate from using Application.cfm to Application.cfc. It's a management application that is set up on different web sites (all of which we host) with a common 'app directory' that is set up as a virtual directory off of each site, with some site specific variables (mostly just a couple of unique client IDs) located in an XML file off each site definition's root. In other words:

www.site1.com is client A's web app and has /configfolder/appvars.xml

www.site2.org is the same web app for client B and has /configfolder/appvars.xml

The actual application is a virtual directory, let's say:

www.site1.com/mgmt/

www.site2.org/mgmt/

This /mgmt/ folder contains all of the actual application code - the only thing that the root directories do is hold the handful of client-specific variables.

Historically, what we've done is to have an Application.cfm file in the /mgmt/ app folder do a <cfinclude template="../Application.cfm"> so that the same code executes for all the sites but pulls the unique site's credentials from that site's parent folder. But Application.cfm is a bit long in the tooth.

The problem is that the server doesn't seem to 'find' the Application.cfc in the parent folder and I'm not sure there's an equivalent 'cfinclude the file from one directory up' (unless you can cfinclude a CFC, which I don't think you can do?). 'extends' won't cut it either because we'd have to set up a mapping and know which specific Application.cfc we're extending, when the only thing we know is that the data we want is in /configfolder/.

The only solution I can think of is to use a single Application.cfc and to put it in /mgmt/, transfer our client-specific variables from the XML file we read in via cffile to a CF page that can be included in the Application.cfc (so we don't need to know the absolute directory name, as we do now), and then set things like Application.name dynamically, but I'm not sure if this is kosher. I'd prefer that each site had its own Application.cfc but (perhaps by dint of it being a virtual directory?) when you go to login at www.site1.com/mgmt/, it just doesn't seem to use www.site1.com/Application.cfc. I have other traditional sites where Application.cfc does 'filter' down to subdirectories, but there it's located in the root folder, you login in the root folder, and when you navigate to a subdirectory, CF seems to be aware that you're still in the same application.

I apologize if I haven't explained this well and am happy to clarify anything -- would appreciate any advice on how to best implement Application.cfc in a multiple-sites-on-one-codebase scenario.

    This topic has been closed for replies.
    Correct answer Owainnorth

    Ah, if it's a virtual directory you'll have problems. The ApplicationProxy is "the way" it's done, but (as you've realised) CF looks at a file-level, and is not aware of any IIS mappings.

    Any reason they can't just by physical directories? Even using something like a Windows Junction is they're physically located in a different place?

    2 replies

    Participant
    September 7, 2012

    Not sure what the protocol for adding comments to old questions is, but I found this question while trying to find a solution to this problem. Couldn't find one anywhere, so here is the solution I have come up with:

    Essentially I have multiple applications that use multiple modules, and the only differences in the module use will be determined based on the application that is pulling it in and the user session variables, etc:

    http://www.myapp1.co.uk/

    http://www.myapp2.co.uk/

    I want them both to pull in: mymodule1 which sits outside their physical directory, so I have a virtual mapping that allows them to be used in each:

    http://www.myapp1.co.uk/mymodule1/

    http://www.myapp2.co.uk/mymodule1/

    My physical directories are:

    /sites/myapp1/

    /sites/myapp2/

    /modules/mymodule1/

    When I am inside mymodule1 it needs to use the Application file of myapp1 or myapp2 in order to continue to use the correct session variables etc. As noted above, the search for Application cfc is done by physical directory and will not allow you to reference it by relative or full paths either if you try to use 'extends'. So, basically it's impossible for the module to pull in a different Application.cfc unless you place physical copies under each app. I really don't like code duplication, so if I can't get the physical file, I need to dynamically change the Application.cfc. Here is the solution:

    Create a file in each app called ApplicationSettings.xml. Add items for whatever settings are unique to the application.

    So in the xml file I have applicationSettings containing applicationName, applicationID, etc.

    Before I do anything in the Application.cfc I call the xml file using:

    appXML = XmlParse("ApplicationSettings.xml");

    appSettings = appXML.ApplicationSettings;

    I then set my unique variables using the data from the xml file rather than hard coded in the Application.cfc:

    THIS.name = appXML.ApplicationSettings.applicationName.xmlText;

    Application.appID = appXML.ApplicationSettings.applicationAppID.xmlText;

    etc

    In the module1 directory, the Application file just needs an extra bit to determine which ApplicationSettings.xml to pull:

    appSettingsPath = "http://#CGI.HTTP_HOST#/";

    appXML = XmlParse("#appSettingsPath#ApplicationSettings.xml");

    Owainnorth
    Inspiring
    May 20, 2011

    Think I get you, and the recommended workaround is to create an ApplicationProxy.cfc (name is arbitary) in the root, with just the following:

    <cfcomponent extends="Application.cfc">


    </cfcomponent>

    So is literally just an empty proxy to your root App.cfc. From your subfolders, you can then do:

    <cfcomponent extends="ApplicationProxy.cfc"> and it'll keep searching until it finds your uniquely-named proxy in the root.

    If that's what you meant to do, of course...

    AquitaineAuthor
    Inspiring
    May 20, 2011

    This solution has the same problem that simply using Application.cfc does -- the subdirectory can't find the parent directory's ApplicationProxy.cfc without an explicit mapping (e.g. if I just 'extends="ApplicationProxy.cfc", it comes up not found, and I can't extend ../ApplicationProxy.cfc, and I can't put in an explicit mapping) - unless I am misunderstanding you. What I have just tried is:

    each parent site has Application.cfc

    each parent site now has ApplicationProxy.cfc which extends Application.cfc

    the single subdirectory that contains the app has an Application.cfc that has tried but cannot extend either Application.cfc or ApplicationProxy.cfc.

    The only thing I can think of is that it's not finding it because the subdirectory containing the app is a virtual directory set up from IIS, because I know in other instances CF will simply 'search up,' but in this case, it's got to be crawling the file system and not the web root.

    Owainnorth
    OwainnorthCorrect answer
    Inspiring
    May 20, 2011

    Ah, if it's a virtual directory you'll have problems. The ApplicationProxy is "the way" it's done, but (as you've realised) CF looks at a file-level, and is not aware of any IIS mappings.

    Any reason they can't just by physical directories? Even using something like a Windows Junction is they're physically located in a different place?