3

In using the CF application.cfc - there is a need to create some vars to begin with (in the THIS scope) - such as this.name and this.applicationtimeout() etc.

I ran across something I consider an odd behavior - and hope someone can explain why this happens and a possible workaround.

There are quite a few "THIS" vars accepted that can work to set application specific variables (of course you have to check "allow application specific vars" in the CFADMIN - which I did)

One of these is THIS.mappings - which is an array of mappings - MINE looks something like this:

this.path = GetDirectoryFromPath( GetCurrentTemplatePath() );
this.mappings = {
     '/files' = '#this.path#_my_files\'
     ,'/functions' = '#this.path#_my_functions\'
     ,'/logs' = '#this.path#_my_logs\'
};

it works fine - when it is set inside a cfscript block at the top of the application.cfc it works fine - if I put that script block in it's own file and cfinclude it in the application.cfc

however - In an attempt to segment my code - I wanted to put ALL of my application setting in a settings.cfc... (the thought here was IF some setting had to be changed - I wouldn't have to worry about 'where' to look, I don't really want to split the THIS stuff on my app.cfc and other application or session settings in the settings.cfc

SO I created a method in the settings.cfc called getTHIS, and I put the script block there... then used

<cfinvoke component="settings"
          method="getTHIS" 
      returnvariable="THIS" 
    />

Which WORKS - except (it seems) on the mappings...

The this.name etc, all seem to work and get set - as a matter of fact the this.mappings gets set fine too (so it appears) if i do a

<cfdump var="#THIS#" label="THIS" />

The dump is identical to the dump of THIS when I set it 'literally' on the app.cfc page..

HOWEVER - any attempt to call a template thru the mapping - results in a standard "if you want to use absolute paths you have to create a mapping blah blah..."

MY BIGGER goal was (on application start) to scan a directory for sub-directories, and create mappings based on certain sub-directories.. but if I can't abstract that functionality out into it's own function - I'll be forced to write it directly in the app.cfc (which wouldn't KILL me, but again, I was trying to segment my code logically... There seems to be a limitation of when and where these mappings can be set... true?

So I guess the big question is - can I SET this.mappings thru an outside method?? I guess I could bring back the 'settings I want' using the cfc call, and then just do the 'set this.whatever = return form cfc' - (this may be my answer...)

Thanks

j-p
  • 3,698
  • 9
  • 50
  • 93

2 Answers2

0

Mappings can only be set in the 'pseudo-constructor' and not inside any of the methods inside Application.cfc - http://adobe.ly/QN2oX1

You could try setting this.mappings to the result of a CFC call (I cannot think of why this would not work), but if it depends on a mapping to do so, it will likely not work.

Scott Stroz
  • 7,510
  • 2
  • 21
  • 25
  • ya - that's where i ended up - I'll see if I can get a more 'graceful' (read: less code, less memory) way around it. – j-p Aug 10 '12 at 17:49
  • For what its worth, scanning a directory to create mappings is not the best idea as it will get done on EVERY page request. – Scott Stroz Aug 10 '12 at 17:51
0

I haven't tested this, but I'm pretty sure it would work if your application.cfc extends your settings.cfc.

component {
    public any function getMappings() {
        var mappings = {};
        //code to get your directories etc.
        return mappings;
    }
}

component extends="settings" {
    this.name = "xxxx";
    this.mappings = getMappings();
    ...
}
Sharondio
  • 2,605
  • 13
  • 16
  • That may work, but if the poster said they wanted to check if directories existed and then make mappings. That would get done on every page request. performance may be an issue. – Scott Stroz Aug 10 '12 at 16:49
  • ya - that's two separate issues - the ability to SET THIS.MAPPINGS - AND THEN the parse and set (which is a wholly other issue, and would only be done on APPLICATION START... not every request. Thx Sharon - i'll try it, and let ya know... The thought I had and added - about calling he cfc method and returning a var that I can THEN set this.mapping = to.. works and gives me the segregation I was looking for - it means I have two structs with similar info - per page load - but it's SMALL, so I'm not too concerned. I'll do some benchmarking with your code and see... – j-p Aug 10 '12 at 17:48