In Coldfusion, how do I init a component that is located above the current path folder?
Asked Answered
A

6

17

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.

Adaadabel answered 26/3, 2010 at 18:35 Comment(0)
C
17

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");
Cowans answered 26/3, 2010 at 18:47 Comment(2)
While I like the method above, this is just cleaner since I have administator access.Adaadabel
i have one folder with dot in his text, how can i add in path from createObject? (eg: board.models) and i cant change the path nameOpportunity
R
17

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"

Rozek answered 26/3, 2010 at 20:0 Comment(2)
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"]?Adaadabel
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)Staple
C
4

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.

Carlitacarlo answered 26/3, 2010 at 21:11 Comment(1)
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!Adaadabel
A
3

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.

Amylopsin answered 26/3, 2010 at 20:4 Comment(3)
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.Adaadabel
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?Amylopsin
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.Adaadabel
T
0

I had this same issue and this was my solution. It's pretty straight forward but it took a few hours for it to hit me. Hopefully this will save someone some time.

I started with

<bean id="ColdBooksConnectionService" class="myservice.model.service.ConnectionService" />

and always got the error that it wasn't available, so I wrote out the full path

<bean id="ColdBooksConnectionService" class="/CFIDE.administrator.myservice.model.service.ConnectionService" />

and the problem is solved.

Hope this helps.

Tactical answered 5/7, 2011 at 22:29 Comment(0)
R
0

Put the cfobject in an include.cfm file within the same directory as the .cfc, then you can call using a <cfinclude template="..\Whatever\include.cfm" />

Reger answered 14/1, 2020 at 14:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.