10

I want to extend a CFC in a different directory and I have a couple of options, but can't figure out how to do this:

A) Use a dynamic mapping (this will have to be dynamic based on the site, e.g. for the live site it would be cfc.myPackage.MyCFC but on a dev site it would be myCfcRoot.myPackage.MyCFC) - I've tried putting expressions into the extends bit but obviously CF doesn't like that, e.g. :

<cfcomponent name="MyComponent" extends="#config.cfcRoot#.BaseComponent">

or

<cfcomponent name="MyComponent" extends="#GetRealPath(../BaseComponent.cfc)#">

B) Provide a relative path (somehow) to the CFC to extend.

I fear that I can't do this, but I'm hoping that there is something I've missed.

DEfusion
  • 5,463
  • 5
  • 42
  • 59

4 Answers4

11

Daniel is basically correct, you need a mapping. However, there are 3 workarounds.

CFCs will pick the current path as a relative root mapping, so if your CFCs are all in the same directory, you can just say

<cfcomponent name="MyComponent" extends="Example">

Or if your components are in subdirectories from the current cfc, you can access it:

<cfcomponent name="MyComponent" extends="subdirectory.Example">  

Second, if you are running on ColdFusion 8, you can define a mapping in your application.cfc using the mappings struct like this:

<cfset this.mappings["/MyApp"] = expandPath(".") />

There are two good references for Application.cfc, first, Ray Camden's example Application.cfc which just gives a nice view of what goes where, then the CF8 Live Docs application settings page, which has a section on mappings along with some good comments.

Finally, you can use the built-in mapping of your web root, so if your application is in a subdirectory named "MyApp" off the web root, your root mapping will be "MyApp". Let's say you correctly put your components in:

wwwroot\MyApp\com\MyApp\example.cfc

The mapping to this cfc in this case will be:

MyApp.com.MyApp.Example

And using your example, you can extend like this:

<cfcomponent name="MyComponent" extends="MyApp.com.MyApp.Example">

Anything else, such as if your components are outside of the web root, or if you are not sure what the folder structure of your finished application will be, and you will need to set a mapping in the CF Administrator.

Nathan Strutz
  • 7,721
  • 1
  • 37
  • 48
  • Is this.mappings inside the Application.cfc only for CF 8, do you have doc links. – DEfusion Nov 13 '08 at 16:47
  • I added some reference links to the 2nd section under the example. – Nathan Strutz Nov 13 '08 at 17:59
  • The application mapping approach rocks. It fixes one of the last big hurdles for using typed components. – anopres Nov 17 '08 at 14:14
  • Worth being aware that application specific mappings are not the same as standard ColdFusion mappings you might create in the CF Administrator: http://blog.daemon.com.au/go/blog-post/application-specific-mappings-are-horribly-broken – modius Dec 01 '08 at 00:26
  • I've done the this.mappings bit in CFMX7 as well. In Railo, I should also point out, using the slash mapping to the root, at least, (ie., this.mappings["/"]) is unnecessary, as Railo somehow magically understands that the slash mapping should reference the folder with the Application.cfc in it. – Shawn Grigson Mar 02 '10 at 20:09
3

Now this is only tested in cf8 so other engine could differ.

if you want to use relative paths to extend applications you can but your have to start them with a "/.". For instance you can do this to extend an application.cfc from your web root into directory below you webroot:

<cfcomponent output="false" extends="/.application">
 <!--- whatever code you have --->
</cfcomponent>

now let's say I have the following paths in my application:

[webroot]/1/1a
[webroot]/2

let's say that the application.cfc in [webroot]/1/1a extends the application.cfc in [webroot]. now I want to place an application.cfc in [webroot]/2 and extend the application.cfc in [webroot]/1/1a. all i would have to do in my [webroot]/2/application.cfc is the following:

<cfcomponent output="false" extends="/./1/1a/application">
 <!--- whatever code you have --->
</cfcomponent>

hope this makes sense.

rip747
  • 9,021
  • 6
  • 33
  • 44
2

Unless the CFC is in the same directory as the calling script the CFC must be located and referenced from a path relative to a "Mapping".

I have found that sometimes you need to make sure that "/" is mapped to your document root of your webserver and that becomes the base for all relative paths. Or you can setup a mapping for a CFC directory that hold all of your common CFCs.

This screen is found in the ColdFusion Admin under "Server Settings" -> "Mappings".

danielrsmith
  • 3,994
  • 3
  • 24
  • 32
  • Yeah I figured as much, the problem is I want to be able to change the mapping it uses depending on what site it's running under. – DEfusion Nov 13 '08 at 15:21
0

In regards to Method B. It can be done using an additional file in your example. It's one extra file per cfc that you want to extend per directory that you want to extend from.

The 3 files that are required.

  • /somepathtobasecomponent/basecomponent.cfc (your base component file)
  • /pathtoworkingcfc/function.cfc (the file with the extends attribute)
  • /pathtoworkingcfc/basecomponent_extend.cfc (the new file that will do the extending)

/somepathtobasecomponent/basecomponent.cfc

Nothing to change here. This stays the same.

/pathtoworkingcfc/function.cfc

in the cffunction tag set the extends to extends="basecomponent_extend"

/pathtoworkingcfc/basecomponent_extend.cfc

Sole content of the file is a cfinclude

<cfinclude template="/somepathtobasecomponent/basecomponent.cfc">
nosilleg
  • 2,103
  • 1
  • 21
  • 36