UDF: component() for CFMX

Posted by Dan on Mar 27, 2003 @ 5:01 PM

Have you ever had the need to invoke an instance of a componet based upon it's relative path? I know I have, so I threw this little UDF together.

To invoke a component, you simply call the component() function using either the standard dot notation or you can specify either a relative or absolute path to the CFC. I tried to make the "type" argument somewhat intelligent and it'll probably work correctly 99% of the time for you, but if you want to be absolutely sure you get the expected behavior, specify the type argument for the function.

/****************************************************************
UDF: component(path, type)
Author: Dan G. Switzer, II
Date: 5/26/2004

Arguments:
path - the path to the component. can be standard
dot notation, relative path or absolute path
type - the type of path specified. "component" uses
the standard CF dot notation. "relative" uses
a relative path the the CFC (including file
extension.) "absolute" indicates your using
the direct OS path to the CFC. By default
this tag will either be set to "component"
(if no dots or no slashes and dots are found)
or it'll be set to "relative". As a shortcut,
you can use just the first letter of the type.
(i.e. "c" for "component, etc.)
Notes:
This is based upon some code that has floated around the
different CF lists.
****************************************************************/

function component(path){
    var sPath=Arguments.path;var oProxy="";var oFile="";var sType="";var sProxyPath = "";
    if( arrayLen(Arguments) gt 1 ) sType = lCase(Arguments[2]);

    // determine a default type
    if( len(sType) eq 0 ){
        if( (sPath DOES NOT CONTAIN ".") OR ((sPath CONTAINS ".") AND (sPath DOES NOT CONTAIN "/") AND (sPath DOES NOT CONTAIN "\")) ) sType = "component";
        else sType = "relative";
    }

    // create the component
    switch( left(sType,1) ){
        case "c":
            return createObject("component", sPath);
        break;

        default:
            if( left(sType, 1) neq "a" ) sPath = expandPath(sPath);
            // updated to work w/CFMX v6.1 and v6.0
            // if this code breaks, MACR has either moved the TemplateProxy
            // again or simply prevented it from being publically accessed
            if( left(server.coldFusion.productVersion, 3) eq "6,0") sProxyPath = "coldfusion.runtime.TemplateProxy";
            else sProxyPath = "coldfusion.runtime.TemplateProxyFactory";
            try {
                oProxy = createObject("java", sProxyPath);
                oFile = createObject("java", "java.io.File");
                oFile.init(sPath);
                return oProxy.resolveFile(getPageContext(), oFile);
            }
            catch(Any exception){
                writeOutput("An error occured initializing the component #arguments.path#.");
                return;
            }
        break;
    }
}

NOTE:
This code was updated on Wednesday, November 19, 2003. I've added a check so that the code uses the correct path to the TemplateProxy factory. They changed the location of this service between v6.0 and v6.1.
NOTE:
I edited the code again on May 26, 2004. I added a try/catch to the routine to provide a more intutive error message if the component doesn't load from a relative path.

Categories: HTML/ColdFusion, Source Code

4 Comments

  • If anyone knows 100% who first published the TemplateProxy hack to invoking a CFC, please let me know so I can give credit to where credit's due. I believe it was Matt Liotta, but I'm not sure.
  • FYI - In CFMX v6.1 things have changed a bit. The resolveFile() method has been moved to the "coldfusion.runtime.TemplateProxyFactory" from the "coldfusion.runtime.TemplateProxy". This means you'll need to update the following line:

    oProxy = createObject("java", "coldfusion.runtime.TemplateProxy");

    to:

    oProxy = createObject("java", "coldfusion.runtime.TemplateProxyFactory");

    If you wish things to work w/CFMX 6.1.

    -Dan
  • I've updated the code above so that it should work automatically with either CFMX v6.0 or v6.1.
  • Is anyone aware of any way to achieve the same results using Blue Dragon? The coldfusion.runtime.TemplateProxyFactory (nor TemplateProxy) class is not available under their app server. Any recommendations would be appreciated.

Comments for this entry have been disabled.