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

How to get the page call stack

Participant ,
May 19, 2008 May 19, 2008

Copy link to clipboard

Copied

Is there any way to get a list of files used in building a single page? What I need is to be able to see what page called the custom tag from within that custom tag. Using getBaseTemplatePath doesn't work because it only shows the top level page, not the actual file that called the custom tag. Take the following structure for instance:
/webroot/mydir/myfile.cfm
/webroot/mydir/myincludes/includefile.cfm
/webroot/customtags/thecustomtag.cfm

If myfile.cfm cfincludes includedfile.cfm and then includefile.cfm calls thecustomtag.cfm, thecustomtag.cfm thinks myfile.cfm called it. Which is wrong, and a bit stupid.

I've tried the back door method:
<cfset objFactory = CreateObject( "java", "coldfusion.server.ServiceFactory" ) />
<cfset objDebugging = objFactory.GetDebuggingService() />
<cfset qEvents = objDebugging.GetDebugger().GetData() />
<cfdump var="#qEvents#">

But found out later that this only works with debugging turned on in CF admin AND no IP restrictions are set (unless the IPs for the clients are listed there).

This should be a very simple task, one would think. Any suggestions?
TOPICS
Advanced techniques

Views

1.3K

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
Explorer ,
May 19, 2008 May 19, 2008

Copy link to clipboard

Copied

We CFInclude the following snippet into all project files when this functionality is needed:

<CFScript>
//////////////////////////////////////////////////////////////////////////
//
// Init Template Management
//
myName = getFileFromPath(getCurrentTemplatePath());
if(NOT isDefined('TemplateManagement')){
TemplateManagement = structNew();
TemplateManagement.cnt = 0;
}
else{
TemplateManagement.cnt = TemplateManagement.cnt + 1;
}
if(NOT structKeyExists(TemplateManagement, myName)){
TemplateManagement[myName] = structNew();
}
//
// Versioning:
//
TemplateManagement[myName].App.Version.Major = 1;
TemplateManagement[myName].App.Version.Minor = 1;
//
// License:
//
TemplateManagement[myName].License.SerialNumber = '';
TemplateManagement[myName].License.Owner = '';
//
//
//////////////////////////////////////////////////////////////////////////
</CFScript>


...at the end of the http request, usually in onRequestEnd.cfm, you can grab the 'TemplateManagement' struct and take a look.

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
Participant ,
May 19, 2008 May 19, 2008

Copy link to clipboard

Copied

Hmmm... not sure what you mean. Your snippet creates a structure key using the filename with version/license info. What I'm looking for is how to grab the path of the real calling file.

The problem is that cfincluded files don't expose the real calling page, but thinks it was called from the top level requested page. In your snippet, if you add :

TemplateManagement[myName].path = getCurrentTemplatePath();
TemplateManagement[myName].basepath = getBaseTemplatePath();

Then cfinclude that file from a cfincluded file you'll see what I mean.

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
Participant ,
May 21, 2008 May 21, 2008

Copy link to clipboard

Copied

anyone? Is this not possible?

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
LEGEND ,
May 21, 2008 May 21, 2008

Copy link to clipboard

Copied

solutionfinder wrote:
> anyone? Is this not possible?

I assume it must be possible, because CF itself can output it in an
error page, but I have no idea how us lowly developers can get access to
the information.

To add a bit to the the <cfinclude...> question. You are complaining
that is works exactly as documented how it will work. A include is to
be logically considered as part of the page that included it thus
sharing all variables and such that belong to the page.

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
Participant ,
May 21, 2008 May 21, 2008

Copy link to clipboard

Copied

CF uses coldfusion.server.ServiceFactory.GetDebuggingService() to output the error page, if turned on in the CF admin. I am currently using that for this case but I need to find a way to do it without the debugger turned on.

I understand that it is to be logically considered part of the page that included it, but it sure would be nice to be able to determine the *real* path not just the logical one. I'm not complaining that this isn't working as designed, I'm just saying the design leaves much to be desired n this respect.

Though like you said, were just "lowly developers" so why do we need that kind of control :).

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
LEGEND ,
May 21, 2008 May 21, 2008

Copy link to clipboard

Copied

solutionfinder wrote:
> CF uses coldfusion.server.ServiceFactory.GetDebuggingService() to output the
> error page, if turned on in the CF admin. I am currently using that for this
> case but I need to find a way to do it without the debugger turned on.

I'm not in a place to experiment at the moment, but does the 'debugger'
have to be turned on? I mean does CF not display the file stack on an
error page even if 'debugging' is not turned on? I would have thought
it does, but I have never tried to identify this before.

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
Participant ,
May 21, 2008 May 21, 2008

Copy link to clipboard

Copied

It displays it as long as the "Enable Robust Exception Information" option is on. However, if the debugging is off (or and IP filter is used) then only CF can access the data. With debugging off if you do this:
<cfset objFactory = CreateObject( "java", "coldfusion.server.ServiceFactory" ) />
<cfset objDebugging = objFactory.GetDebuggingService() />
<cfset qEvents = objDebugging.GetDebugger().GetData() />
<cfdump var="#qEvents#">

you get a null pointer error.

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
LEGEND ,
May 21, 2008 May 21, 2008

Copy link to clipboard

Copied

solutionfinder wrote:
> However, if the debugging is off (or and IP filter is used) then only CF
> can access the data.

I wonder, in the case of debugging is off, that the information is just
someplace else in the service factory, only known to Adobe nee
Macromedia nee Allaire engineers. I would speculate that the debugging
objects in the factory might just acquire the information from this
other place. But I have no advice on how to find it, if it is at all
available. I have never had need to mess with the service factory.

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
Participant ,
May 21, 2008 May 21, 2008

Copy link to clipboard

Copied

probably. I don't like using the service factory at all. I don't think its even supported (unless that's changed). But to date it is the only way I can find the real include path.

I'll probably have to pass this info in as a variable, though that breaks the dynamic nature of things (and sort of defeats the purpose).

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
LEGEND ,
May 21, 2008 May 21, 2008

Copy link to clipboard

Copied

solutionfinder wrote:
>
> I'll probably have to pass this info in as a variable, though that breaks the
> dynamic nature of things (and sort of defeats the purpose).
>

Could you build your own stack dynamically? I can imagine where a line
or two of code in each template adds something to a global structure at
the beginning and removes the node at the end. It would be manual to
make sure that this code exists in all templates since there is no way
to do this automatically that I can think of. But that maybe a bit
better then nothing.

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
LEGEND ,
May 21, 2008 May 21, 2008

Copy link to clipboard

Copied

I've tried to work out the same thing as you previously, but pretty much
covered the same ground you're reporting.

If you throw an exception and catch it, the catch struct has the template
stack in it. It's not a very performant practice though, as CF error
handling seems to add quite an over to processing.

You could possibly create a very small template doing just the try / throw
/ catch, compile it and then decompile the class file to see what Java is
being called under the hood. It might point you in the right direction.

--
Adam

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
Explorer ,
Aug 19, 2008 Aug 19, 2008

Copy link to clipboard

Copied

LATEST
Cool, I found it. Well: I read someone's blog and they mentioned something related, which got me experimenting.

All one needs to do is to create an Exception object, thus:

{code}
oException = createObject("java","java.lang.Exception").init();
{code}

Dump that, and you'll see there's a tagContext array...

--
Adam

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