The simplicity of "upward" relative component paths in Lucee

24 May 2017

When instantiating or extending CFML components (CFCs), you essentially have 3 choices:

1) Place the target CFC in the same directory as the calling code:

  • app/
    • script.cfm
    • user.cfc

//script.cfm
user = New user();

2) Place it in a directory below the current location:

  • app/
    • script.cfm
    • model/
      • user.cfc

//script.cfm
user = New model.user();

3) Define a mapping to the directory where the component lives:

  • app/
    • model/
      • user.cfc
    • scripts/
      • Application.cfc
      • script.cfm

//Application.cfc
this.mappings[ "/model" ] = GetDirectoryFromPath( GetCurrentTemplatePath() ) & "../model/";

//script.cfm
user = New model.user();

At least, this seems to be the case with Adobe ColdFusion.

I've recently discovered that Lucee in fact supports relative paths to CFCs above the current directory.

  • app/
    • model/
      • user.cfc
    • scripts/
      • script.cfm

//script.cfm
user = New "../model/user"();

This allows more flexibility in how you organise your application files and may avoid the need for server wide mappings.

Frameworks

FW/1, for example, requires your Application.cfc to extend the framework component. Per-application mappings can't be used in this case (they are defined too late in the application lifecycle), so you must either place the framework in or below your application root, or pre-define a mapping in the admin. (Actually, version 3.5+ provides a workaround, but it's somewhat convoluted.)

Using this simple relative syntax gives you the option of placing the framework above your root, which is preferable from a security standpoint, without needing an admin defined mapping, which makes for better portability (one less dependency on the server environment).


//Application.cfc
component extends="../framework/one"{

}

Tests

Another area where this is potentially useful is testing. You may want to keep all your test code and assets in a separate directory from the code it exercises.

  • cfcs/
    • user.cfc
    • test/
      • suite.cfc
      • testphoto.png

The relative syntax means suite.cfc can easily "reach up" to the component it is testing.

You could also use it to allow a single copy of your test framework to be available to multiple test suites without requiring a mapping:

  • testbox
  • cfcs/
    • user/
      • user.cfc
      • tests.cfc
    • product/
      • product.cfc
      • tests.cfc

//user/tests.cfc product/tests.cfc etc
component extends="../../testbox.system.BaseSpec"{

}

Posted by Julian on .

Comments

  • Formatting comments: See this list of formatting tags you can use in your comments.
  • Want to paste code? Enclose within <pre><code> tags for syntax higlighting and better formatting and if possible use script. If your code includes "self-closing" tags, such as <cfargument>, you must add an explicit closing tag, otherwise it is likely to be mangled by the Disqus parser.
Back to the top