Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapping to a CFC in ColdFusion

In my application I have all my CFC's in a cfc folder. From the site root I can access them without any trouble by simply referring to them in my <cfinvoke> tag as component=cfc.mycomponent method=mymethod

The trouble is, when I want to access the cfc from another page that's not in the root I can't use component=../.cfc.mycomponent to get in touch with that cfc.

What am I doing wrong here?

like image 349
Ofeargall Avatar asked Oct 18 '11 22:10

Ofeargall


People also ask

What is application CFC in ColdFusion?

Application event handlers are CFC methods that ColdFusion automatically executes when specific events occur during the lifetime of an application: application start and end, session start and end, request start, execution, and end, and exceptions.

What is the use of application CFM in ColdFusion?

Names the application, enables Client and Session scope variables, and sets the client variable store to the myCompany data source. Ensures that debugging output is not displayed, if the ColdFusion Administrator enables it.


2 Answers

There are a handful of options for getting this to work. Unfortunately, learning them has taken me a good amount of trial and error. Let me share what I've learned.

First, you can use the classic method of creating a mapping in your CF Administrator. Specify the exact path to your components (e.g. c:\wwwroot\cfc), and the mapping (pseudo-folder) that you want to call it by (e.g. MyCFCs). Now from anywhere in your application, you can reference create a new MyCFCs.mycomponent() (using CF9+'s new keyword, you can substitute for createObject("component","MyCFCs.mycomponent") to be compatible back to CF6).

The downsides to using a server mapping are that you have to configure this on every server your application runs on. I typically have a local development server which has a radically different configuration from my production servers, and making changes on production servers is a pain for me, so I try to avoid server mappings whenever possible.

Second, you can reference your CFCs from a web-root-relative path, meaning that if your application is in the root of your server and the /cfc path is directly off of the web root, you can always do new cfc.mycomponent() from anywhere in your application. ColdFusion 6.1 and up will correctly map to the root of your web site. This is like referencing an image using /images/mypicture.jpg, anywhere in your web site, /images will will go straight to the same directory.

The downside of using the web-root-relative path is that if your application will ever be in a different folder off of the web root, or will ever be in a subdirectory and sometimes be at the web root, the relative path from the web root will change, breaking these links.

Third, you can create an application-specific mapping. This was introduced in CF8 and requires that you have an Application.cfc file. It is simple to add. Raymond Camden has a great reference. The syntax is essentially like this.

<cfset this.name = "MyAppName"/>
<cfset this.mappings = structNew() />
<cfset this.mappings["/cfc"] = getDirectoryFromPath(getCurrentTemplatePath()) & "cfc/" />

The only downside to this method is that your Application.cfc can't extend a CFC in a mapped folder. It's an obscure problem, which probably won't affect you. Also, you will need to have an Application.cfc, which is good practice, but I don't know if you are doing that yet.

Fourth, you can instantiate your CFC into your application scope, probably from within the aforementioned Application.cfc, inside an OnApplicationStart() method. This moves any compile/instantiation time into your application's first hit, and removes it from subsequent hits. The code is very simple.

<!--- from Application.cfc, inside onApplicationStart() --->
<cfset application.myComponent = new cfc.myComponent() />

<!--- from anywhere else in your application --->
<cfset application.myComponent.callMyMethod() />

The downside to this one is that once your component is in Application memory, any changes you make to it while you are developing your application will not be reflected until you clear the application memory or call onApplicationStart() again. It's not hard to get around, but it's just more code, and more to manage.

One final note, you may want to think about moving from <cfinvoke> to createObject("component",...) or, if you are on CF9, new. The cfinvoke syntax is fine, but every time you invoke a component from a path, you are re-instantiating it, and it also is not a very object-oriented way to call your components. Food for thought, take it or leave it :)

like image 143
Nathan Strutz Avatar answered Oct 03 '22 10:10

Nathan Strutz


You can't use relative paths with components.

What you need is a ColdFusion mapping. There are two ways to do this.

The first is to go into your ColdFusion administrator, go into the mappings section and add a /cfc mapping that points to your cfc folder.

The other way is to use application specific mappings; In the Application.cfc for your application you can add application mappings as you would under the ColdFusion administrator mapping. At the top of your application cfc add a cfset of this.mappings as an array. In this array set the mapping with the directory path.

<cfset this.mappings["/cfc"] = GetDirectoryFromPath( GetCurrentTemplatePath() )&"cfc">

with the mapping of /cfc to your cfc folder any component calls to cfc.objectname will load the appropriate component in your cfc folder.

like image 41
Stephen Moretti Avatar answered Oct 03 '22 10:10

Stephen Moretti