• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

extending an application.cfc, but giving it, it's own application name.

New Here ,
Jun 04, 2018 Jun 04, 2018

Copy link to clipboard

Copied

Hello,

I am extending an application.cfc from another directory. In my parent application.cfc I have:

<cfcomponent>

this.name=hash( getCurrentTemplatePath());

in the child I have:

<cfcomponent extends="rootapplication">   

    this.name="child";

It looks like the child "this.name" never runs. No matter what i do they share the same application scope and a change in one changes both (as they have the same application name).

So I have two questions (different ways to fix the same problem):

1. Is there a way to change the application name?

2. Is there a better hash tag I can use for the parent this.name such that when run from a different directory it has a different value?.

I was hoping the getCurrentTemplatePath would load the child path when the parent is extended (which would fix all my problems). Is there an easier solution before I bang on this some more, as this has been rather frustration (this scope in application.cfc seems to be protected from anything not in the parent application.cfc).

Thanks,

-Eleon

Views

911

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 04, 2018 Jun 04, 2018

Copy link to clipboard

Copied

Follow Daniel Short's steps for extending Application.cfc, and you will be all right.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jun 04, 2018 Jun 04, 2018

Copy link to clipboard

Copied

I have read about 20 articles on how to do it (including this one a few days ago), and they are all worried about how to use a file with the same name, and this article is only talking about how to extend an application.cfc with the same name.

I have the extension works,the use of supper scope and more or less everything, except that application name for the application scope.The child application is just appending onto the other application in memory and not creating it's own application memory space, because i can not easily change the name in the child.

The "this" scope variables in the child cfc do not fire and do not rename the application cfc (seems like a rather major bug in my mind).

Odds are I will have to get very creative in the parent application.cfc to get this working, but that is an ugly hack, and there really should be an easier way to do this.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 06, 2018 Jun 06, 2018

Copy link to clipboard

Copied

I thought there might be a problem with your extension tree. Supposing not, then I shall now assume that the child extends a component called rootApplication which in turn extends the parent. I can see no reason why the this.name value will be the same for parent and child.

Do all 3 CFCs have a distinct value for this.name?

I created a similar test, in which I ran <cfdump var="#application#"> in the OnRequestStart of the child and of the parent. The dumps showed distinct application names.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jun 06, 2018 Jun 06, 2018

Copy link to clipboard

Copied

the rootapplication.cfc is just an include of the application.cfc of the parent application (I was trying to avoid extending of an extension). So rootapplication.cfc just has an include line in it.

All of them have unique names for "this.name".

I could never get the child to change the application name..

I did finally hack a solution, by doing a hash of the root URL for this.name in the parent application.cfc such that iit is a dynamic hash (I could not use a hash of the current template).

So while I was able to hack a solution, I still am mystified why this.name will not set anything when called from the child.

Thanks,

-Eleon

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 07, 2018 Jun 07, 2018

Copy link to clipboard

Copied

Hi Eleon,

I would not risk going forward with your current set-up. That is because it has signs of increased coupling and reduced encapsulation.

The two Application files - parent and child -  represent two separate applications. Therefore, they shouldn't share a common application-name. The fact that they do implies you have coupled them somehow. Those were in fact my initial thoughts.

Why are you "trying to avoid extending of an extension" ? As ColdFusion is a Java application, you can't avoid that anyway. For example, in ColdFusion, functions extend coldfusion.runtime.CFPageMethod, structs extend coldfusion.util.CaseInsensitiveMap and arrays extend coldfusion.runtime.FastArray. These parent classes are all children of java.lang.Object. 

I don't know what hack you are talking about. But you should follow the steps in Daniel Shorts blog.

1. Application.cfc (parent)

2. ApplicationProxy.cfc (in same folder as the file in 1. and extends it)

Its code is simply:

<cfcomponent extends="Application">

</cfcomponent>

3. Application.cfc (child, in an arbitrary subfolder; it extends ApplicationProxy)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jun 08, 2018 Jun 08, 2018

Copy link to clipboard

Copied

Daniel Shorts blog, does not work when the application.cfc you are extending is not in the same directory structure.

My directory structure is more along the lines of

/stuff/app1/application.cfc

/stuff/app2/application.cfc

so I created /stuff/app2/rootapplication.cfc (which has an include to /stuff/app1/application.cfc)

and then I have /stuff/app2/application.cfc extend rootapplication.cfc

Daniels Shorts blog is great if all you want to do is have a sub application.cfc under the current one, but the work around to try to get it to use an application.cfc in a separate application are a lot harder to do.

The easiest answer I was able to find with google was to use the include to do this. In theory you can also do a complex mapping, but I felt an include would do the same thing, and require a whole lot less work.
I have no idea why this.name is not working (from all I have read it should, but it does not).

I do not think using an include in a cfc would stop this.name from working, but it does or something else is working very strangely.

my app1 application.cfc is not all that crazy, so I see no logical reason for them to have increased coupling.

(I removed/renamed a lot of stuff not really important to showing the base app1)

component {

    this.name=hash( getCurrentTemplatePath());

    this.sessionManagement=true;

    this.clientmanagement="no";

    this.sessiontimeout="#CreateTimeSpan(0,4,0,0)#";

    this.applicationtimeout="#CreateTimeSpan(1,0,0,0)#";

    this.setclientcookies="yes";

    ds="app";

    if (findnocase("sandbox\",CGI.CF_TEMPLATE_PATH)) {

        ds="app_to";

    }

    this.datasource=ds;

    function onApplicationStart() {

        application.version="X.X";

        application.title="App1";

        dirfind="app/";

        rootfind="/app/";

        application.ds ="app";

        //

        //application.rootdir = left(cgi.script_name,findnocase("#rootfind#",cgi.script_name));       

        if (findnocase(rootfind,cgi.script_name) neq 0) {

            application.rootdir = left(cgi.script_name,findnocase("#rootfind#",cgi.script_name));

            application.dir = left(cgi.script_name,find("/",cgi.script_name, findnocase("#dirfind#",cgi.script_name))-1);

        } else {

            application.rootdir = left(cgi.script_name,findnocase("/app2/",cgi.script_name));

            application.dir = "#application.rootdir##(left(dirfind,len(dirfind)-1))#";

        }       

        application.img="http://#cgi.SERVER_NAME#/images";

        application.app2string="http://#server_name#/app2";

        application.appstring="http://#server_name##application.dir#";

        serverrole =createObject("com.serverRole");

        application.servertype=ServerRole.getServerRole();

        application.testMode=1;

        if (application.servertype eq "PRD") {

            application.testMode=0;

        }

        if ( not  isdefined("server.qry") or isdefined("url.resetinit")) {

            server.qry = createObject("com.qry");

        }

        return true;

    }

    function OnSessionStart() {

        include "security.cfm";

    }

    function OnRequestStart(string targetPage) {

        if (structKeyExists(url,'reset')) onApplicationStart();

        if (structKeyExists(url,'reset')) {

            OnSessionStart();

        }

        include "titleheader.cfm";

    }

    function OnRequestEnd    () {

        if (((not (isdefined("page") and page eq "DocLoad")) and request.pagestyle eq "HTML")) {

            writeoutput("</body></html>");

        }

    }

}

rootapplication.cfc is :

<cfinclude template="../app1/application.cfc">

app2's application.cfc:

<cfcomponent extends="rootapplication">   

    this.name=hash( getCurrentTemplatePath());

    this.sessionManagement=true;

    this.clientmanagement="no";

    this.sessiontimeout="#CreateTimeSpan(0,4,0,0)#";

    this.applicationtimeout="#CreateTimeSpan(1,0,0,0)#";

    this.setclientcookies="yes";

   

    <cffunction name="onApplicationStart" access="public" output="false" hint="Application start">       

        <cfscript>       

            super.onApplicationStart();

            application.title = "app2";

            app2dirfind="app2/";

            app2rootfind="/app2/";

            application.ds_app2="app2";

            application.app2dir = left(cgi.script_name,find("/",cgi.script_name, findnocase("#app2dirfind#",cgi.script_name))-1);

            application.app2rootdir = left(cgi.script_name,findnocase("#app2rootfind#",cgi.script_name));

        </cfscript>

    </cffunction>

    <cffunction name="onSessionStart" access="public" output="false" hint="Session start">

        <cfscript>

            super.OnSessionStart();

        </cfscript>       

    </cffunction>

    <cffunction name="onRequestStart" access="public" hint="Request start">

        <cfscript>

            super.onRequestStart(targetpage);

        </cfscript>       

    </cffunction>

    <cffunction name="OnRequestEnd" access="public" hint="Request End">

        <cfscript>

            super.onRequestEnd();

        </cfscript>

    </cffunction>

</cfcomponent>

My hack to get around this is:

   app_string="/app1";

    first_part = FindNoCase(app_string,CGI.http_url);

    second_part= FindNoCase("/", cgi.http_url,first_part+1);

    new_string=left(CGI.http_url,second_part);   

    this.name=hash(new_string);

as this will set app1.cfc name to the url root and not the templatepath and lets both applications have different application memory spaces.

Now if someone can tell me what I did wrong in the old this.name method that caused the this.name in app2 to never work, more than happy to use that (as that is the better solution, but if it does not work, still need to get the work done at the end of the day).

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 09, 2018 Jun 09, 2018

Copy link to clipboard

Copied

LATEST

Eleonf wrote:

I created /stuff/app2/rootapplication.cfc ...and then I have /stuff/app2/application.cfc extend rootapplication.cfc

This design might be troublesome. Application.cfc defines the application, app2, and runs before any file within the application. But your design gets rootapplication.cfc, a component within the application, to include its own application file. I think this needs improving.

I am not a big fan of this way of applying cfinclude. But, assuming it works for you, I would suggest you improve your design by, for example:

1) moving rootapplication.cfc to /stuff/app1/rootapplication.cfc and changing the include template path to "Application";

and

2) changing the value of the extends attribute of app2's Application.cfc to "stuff.app1.rootapplication"

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation