tags:

views:

319

answers:

4

If I have a folder structure that looks like this:

/
/bin/myComponent.cfc
/reports/index.cfm

How do I initiate myComponent.cfc from index.cfm?

myService = createObject("component", "bin.myComponent");

Using the dot syntax, I know how to go to deeper folders, but how to do I go up a folder, and down into the other folder? Using slash syntax it would be something like this:

../bin/myComponent.cfc

But createObject() doesn't work that way. I'd like to keep a relative path so that I can move this folder to another server without breaking the paths.

Ideas? Thanks!

EDIT:

My example didn't display a deep enough folder structure for the creative answers that you all have provided. Here's what I should have done:

/[my project folder]/
/[my project folder]/bin/myComponent.cfc
/[my project folder]/reports/index.cfm

My basic question was if it was possible to go UP a directory when using createObject("component","dot path") from index.cfm to myComponent.cfc IF the name of [my project folder] is not static across all installs of the project.

If the answer is NO, then I'll just need to figure out what the best practice is, whether it's a mapping or an application setting.

+5  A: 

We handle this using a mapping in the cf administrator. Usually all of the components go in one directory which is above the www root. In your case you could add a mapping to / which would allow you to do:

myService = createObject("component", "mymapping.bin.myComponent");
Nick
+6  A: 

if you have the Application.cfc in the root of your folder structure, you could use something like this:

<cfset this.mappings["/local"] = getDirectoryFromPath(getCurrentTemplatePath()) />

and then access it through "local.bin.myComponent"

intnick
This will probably work. I assume I use this code in the application.cfc? From that point to I reference it with #application.mappings["/local"]?
Dan Sorensen
It works the same way as if you would set the mapping in CF Administrator. You can reference your files as /local/bin/somefile.cfm or your component as local.bin.myComponent (as shown by intnick above)
Andreas Schuldhaus
A: 

just use the full path from the root

<cfset obj = createObject("component", "bin.cart.item")>

where item.cfc in located in [website root]/lib/cart/ - this will work from anywhere in your code.

Yisroel
The issue is that I won't know the website root folder name, it's possible to install the website into a differently named folder. From that folder everything is in a known place relative to each other. I need to be able to determine that folder name programatically.
Dan Sorensen
you dont need to know the website root folder name, as long as /bin is right under the root. for example if your website was here c:/inetpub/example.com/webroot/ then you can instantiate cfc's located in c:/inetpub/example.com/webroot/bin/ by using the createObject above.and now i'm realizing that all your cfc's are not under the webroot folder, in which case my solution will not work. is that right?
Yisroel
I believe I caused confusion by using the folder name 'bin' in my example. In actual practice, it's just a folder for all cfc's related to this project. It is not located at the webroot. The projects on this server are all separated from other projects.
Dan Sorensen
+1  A: 

It is an end of the hard week, so pretty likely that following code can be enhanced somehow, but generally this approach should work:

<cfscript>

    // this script is here http://XXXXXXX/test/paths/relative/reports/index.cfm
    // component is here http://XXXXXXX/test/paths/relative/bin/myComponent.cfc

    local = {};

    // initialize with dynamic mapping
    local.myComponentDynamic = createObject("component", "/bin/myComponent");

    // grab the current directory name
    local.parentPathExpanded = ExpandPath("../");
    local.scriptPathExpanded = ExpandPath(cgi.SCRIPT_NAME);
    local.thisDirectory = GetDirectoryFromPath(Replace(local.scriptPathExpanded, local.parentPathExpanded, ""));

    // build base path
    local.scriptPathDirectory = GetDirectoryFromPath(cgi.SCRIPT_NAME);
    local.basePath = Replace(local.scriptPathDirectory, local.thisDirectory, "");

    // this is relative path we already know
    local.relativePath = "bin/myComponent";

    // initialize with slash-syntax (path starting with /)
    local.myComponentSlash = createObject("component", local.basePath & local.relativePath);

    // convert path to the dot-syntax
    local.dottedPath = Replace(local.basePath & local.relativePath, "/", ".", "ALL");
    local.dottedPath = Right(local.dottedPath, Len(local.dottedPath)-1);

    // initialize with dot-syntax path
    local.myComponentDot = createObject("component", local.dottedPath);

</cfscript>
<cfdump var="#local#">

I've split the process into the separate variables and dumped the common container just to make it easy to read and understand this example.

But any way, if you can use dynamic mapping in Application.cfc -- use it.

EDIT: I've added such example, assuming you have following Application.cfc in the parent folder (e.g. "../Application.cfc" if looking from the index.cfm):

<cfcomponent output="false">

    <cfset this.mappings["/bin"] = getDirectoryFromPath(getCurrentTemplatePath()) & "bin/" />

</cfcomponent>

My "paths-converting" example is just a fun trickery and playing with code which not really straightforward approach for good applications.

Sergii
I REALLY like this example, for the out of the box thinking late on a Friday. :-) However, I agree with you: I need to put the mapping in my application file. I'm just surprised that it's SO EASY to create objects deeper in the path, but not higher up. Thanks!
Dan Sorensen