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

CF10 cannot find my Custom Tag. CFParam WILL have a Hint!

Enthusiast ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

It is a travesty beyond travesty that the cfparam tag does not support a 'hint' attribute.   So I aims to fix that with a custom tag!  This is the first time I've messed with custom tags, but so far I cannot get them to work.

I created a file called param.cfm, it merely outputs a cfparam that transposes the provided ATTRIBUTES but allows us to specify a hint attribute on the <cf_param> tag to sate that need.

I placed this file into c:\inetpub\wwwroot\project\custom-tags.

In my application.cfc, it states simply:

<cfset THIS.name = hash( getCurrentTemplatePath() )>

<cfset THIS.customTagPaths = 'c:|inetpub\wwwroot\project\custom-tags'>

<cf_param name="test" type="string" default="foo" hint="YES! WE CAN PUT HINTS ON PARAMS!">

<cfabort>

Well, CF comes back and says:

Expression Exception - in c:/inetpub/wwwroot/project/application.cfc: line 17

Cannot find CFML template for custom tag param.

I did some research and saw that there are supposed to be 4 locations CF will look for custom tags:

  • In the same directory as the calling page
  • In the directory specified on a per-application basis
  • In the ColdFusion CustomTags folder or a subdirectory of it
  • In a directory defined in the ColdFusion ACP

Well, I have per-application settings enabled in the CF ACP, and I have both named and defined the custom tags path for this application, yet CF still cannot find it.  So what am I doing wrong here?

Views

5.7K

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

correct answers 1 Correct answer

LEGEND , Oct 10, 2012 Oct 10, 2012

Sorry, I was not clear.

The customTagsPath thing doesn't work for custom tag calls from the pseudoconstructor.  It works fine everywhere else.

This doesn't really surprise me now that I think about it.

CF is basically doing this, under the hood:

appSettingAndHandlers = new Application()

theApp.setName(appSettingAndHandlers.name)
theApp.setCustomTagPaths(appSettingAndHandlers.customTagPaths)
//etc

if not theApp.started() then
     theApp.start()
     appSettingAndHandlers.onApplicationStart()

// e
...

Votes

Translate

Translate
Enthusiast ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

Just a FYI, I tried putting this tag in the same directory as application.cfc and boom, it found it.  So the problem cannot be related to this code running outside methods in the application.cfc.  It simply is ignoring the THIS.customTagPaths value that was provided.

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
Enthusiast ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

Also, the forum editor is very screwy.  For 'protection' reasons, probably, it changed my custom tag path to use a pipe ( | ), but the path is correct.  I cut and paste it into the run prompt and up came the directory with my custom tag in it.  I also provided EVERY application variable before aborting just to make sure things were configured up the wazoo (technical term).  I've even restarted the Application Server service.  Someone suggested that "once CF finds a CF tag (or doesn't), it caches that result until a service/server restart.

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
Advocate ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

I'm sorry, I don't really have an answer for you except for routine stuff.  Does CF have read/execute permission to that directory? Have you tried dropping the cfm into the CF custom_tags server directory?

I am curious though, why do you think (so strongly) that cfparam needs a hint attribute? What purpose would it server?

Jason

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
Enthusiast ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

Hey 12Robots.

I placed the param.cfm into c:\coldfusion-10\cfusion\CustomTags and CF could not find the tag.

As for the HINT attribute, I just love the thing.  I am a stickler for comments, and I hate having to provide a comment line for each param I create (and I param about EVERY variable that I will use)  It's just a cleaner implementation if I can provide the hint inline with the param declaration.  I was being a bit facetious with saying it was adamant, but I'd love to extend cfparam to support it, and this seems like the next best thing.

Also, how would I determine (without providing simple file read/writes) that CF has read/write rights to a specified folder?  Is there a NTFS account that is supposed to be on it?  What account does CF use to determine those rights?

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
Advocate ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

I would guess that, for whatever reason, those paths are not yet ready at that point in the application (you're trying this from App.cfc, right)?  I would bet that if you tried it from a cfm that they would work.

Hints are not really there for commenting though. They exist for creating API documentation. Since cfparams cannot really be a part of an API, it doesn't really make sense for them to have hint attributes.

Jason

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
Enthusiast ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

Right, well I could change the tag's attribute to use a more semantic value like: <cf_param name="foo" type="string" default="der" info="Information about the param goes here">

If invoking the custom tag from the pseudo-constructor area of the application.cfc works, I'm not sure if executing it from a request would be any different.  It worked when in the same directory as the calling page, but not when placed in the CF Custom Tags directory or when specified in the per-app THIS.customTagPaths variable.

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
Advocate ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

Aegis Kleais wrote:

If invoking the custom tag from the pseudo-constructor area of the application.cfc works, I'm not sure if executing it from a request would be any different.

I suggest you try it.  That would give you your answer.

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
Enthusiast ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

Whew!

I had to go through TONS of commenting out (application.cfc, it's oAS, oSS, oRS, oR methods), and then go into IIS and start disabling IIS URL rewrite rules that I had setup in order to emulate a simple non-modified request.... but I did it!

...and it doesn't work.

The application.cfc sets values, including the customTagPaths variable.  The oAS was commented out, but returns true.  The oRS was commented out and returns true.  The oR was commented out, and I added:

<cfinclude template="#ARGUMENTS.targetPage#">

and it returns void.  I then call: http://localhost/file.cfm which has the following code in it:

<cfoutput>

Hello

<cftry>

<cf_param name="test" type="string" default="foo" info="Info about tag">

<cfcatch>

<p>No go, boss.</p>

</cfcatch>

</cftry>

And up comes "Hello.  No go, boss".  The debug info states that ColdFusion could not find the param custom tag.

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 ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

I have verified that this simply doesn't work (on any version of CF that supports the customTagPaths setting in Application.cfc).

I cannot see anywhere that it's stated that this is by design, or what.  If it's by design, I'd call it a bit shonky.

It also does not work in Railo.

That said, I'm with Jason: if you need to put comments by your <cfparam> tags, then just put comments.  Creating a custom tag just so you can embed a comment in it is... um... a bit misguided, IMO.  Comments are not supposed to be part of your executable code, and to write your code in such a way as they are part of your execute code is simply wrong-headed.  Sorry.

--

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
Enthusiast ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

Well, if I understand correctly, the first time a page is rendered, it compiles to code that omits all comment processing.

Even if I don't "extend" the <cfparam> tag with this attribute, I can see the value in custom tags, however if they don't work properly, it kind of harkens back to a bigger problem.  I can resolve to just comment out my params for the time being, but I'm a bit stubborn with this custom tag problem.

I cross checked Nadel, Forta and Camden's sites and couldn't find anything regarding a discovery that customTagPaths was broken/ignored.  Just seems like a hard pill to swallow for such a glaring issue.

I really don't want to put my custom tags into the CF server, because I won't have access to doing this on my host.  Putting them in the same directory hierarchy would just gnaw at my over zealous nature to keep my directories clean and organized....

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 ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

Sorry, I was not clear.

The customTagsPath thing doesn't work for custom tag calls from the pseudoconstructor.  It works fine everywhere else.

This doesn't really surprise me now that I think about it.

CF is basically doing this, under the hood:

appSettingAndHandlers = new Application()

theApp.setName(appSettingAndHandlers.name)
theApp.setCustomTagPaths(appSettingAndHandlers.customTagPaths)
//etc

if not theApp.started() then
     theApp.start()
     appSettingAndHandlers.onApplicationStart()

// etc

So whilst it gathers the settings from the pseudo constructor of Application.cfc, just because there's a line of code declaring the setting's value doesn't mean the value has been applied to anything yet.

Bear in mind Application.cfc is just a normal CFC, and the act of doing this:

this.customTagPaths = "stuff here";

merely sets a variable.  Setting that variable does not magically make the variable mean something, or execute any other code.

Heh.  That's quite interesting.  I never thought of any of this stuff before.

--

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
Enthusiast ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

But I'm still confused.  Something HAS to be borked.

THIS.customTagPaths (which is merely a variable set in the application component) has specific functionality to the operation of the application.  Like how you can use THIS.sessionManagement = true in order to change the default value of 'no/false', and ColdFusion will look at that value in order to determine whether SESSION scope can be used in the application.

I thought all application.cfc app variables were to be set in the pseudo-constructor, outside of all methods, and put into the THIS scope.  That's what I did, and yet, ColdFusion never checks the paths defined there for where to look for Custom Tags.

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
Advocate ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

Look at the code in the pseudo-constructor this way. This is how it runs everytime (every request) that Application.cfc is instantiated.

1. <!--- A variable named "name" is created in the this scope --->

2. <cfset THIS.name = hash( getCurrentTemplatePath() )>

3.

4. <!-- A variable named "customTagPaths" is created in the this scope --->

5. <cfset THIS.customTagPaths = 'c:|inetpub\wwwroot\project\custom-tags'>

6.

7. <!--- You try to use the param.cfm custom tag --->

8. <cf_param name="test" type="string" default="foo" hint="YES! WE CAN PUT HINTS ON PARAMS!">

Did any code get executed between lines 5 and 8 to actually tell CF to take the value set in line 5 and make that a custom tag path? The answer is no. At this point in the code THIS.customTagPaths is just a string variable sitting in the Application.cfc object. ColdFusion does not come across that line and say "Oh, this is a special variable, let me pause this thread, run out and set those custom tag paths, and then go back and continue processing this code". 

AFTER the pseudo constructor code finishes running CF will start processing that stuff.  It will go set up the custom tag paths, it will create per-application mappings, etc etc. Then it will start firing event handlers. oAS will run, oSS will run, etc. Finally it will include the requested template.

When it comes across like 8 above it will search for the param.cfm where it can (same directory, server directory), but at this point it has not yet executed any code that will set up custom tags per-application based on the value in App.cfc's pseudo constructor.

I hope this makes sense.

Jason

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
Enthusiast ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

OK, I'm following you so far, and testing verifies this.

If I set:

<cfset THIS.applicationTimeout = "I love figgy pudding.">

Logically, we know that this is wrong, as ColdFusion WILL expect this to be a value returned by the createTimeSpan() BIF.  BUT the code is valid, because if we dump THIS immediately after it, we see that value set in the assigned variable.  For all practical purposes, all we did here is set a variable.  So like you explained, customTagPaths IS just a string which happens to be a path, but is nothing more to CF at the moment.

Then, like you explained, after the pseudo-constructor is processed, CF runs through it's logic:

> Has the Application Started yet?  No?  I need to run onApplicationStart()

> Has a Session Started yet?  etc...

But having understood that, you and I both know the THIS.customTagPaths variable to HAVE particular importance when defined in the APPLICATION.CFC's THIS scope.  So where is ColdFusion when it gets to a point where it SHOULD care about this variable and the way it should have an effect on how ColdFusion handles (in this case) the location of Custom Tags on a per-application basis?

I mean, I moved the <cf_param> tag into the onRequest() method for testing at a different point in the request process, but are we saying that even at THAT point, we cannot use Custom Tags?

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
Enthusiast ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

OK, I think I'm getting somewhere.

CF DOES NOT give us grief if we set those special THIS-scoped variables to whatever the heck we want while processing the pseudo-constructor.  HOWEVER, the moment it fires off the oAS(), CF barks at me and says "Hey, the value you set in the application.cfc's THIS-scope variable called 'applicationTimeout', I cannot accept 'work darnit, work!', cause it's not a number.

CF seems to do logical checking on those special variables at the earliest, in the oAS().

Using THAT knowledge, we know that CF sanity-checks those special variables in the oAS() to ensure they are valid, and probably goes so far as to actually process them internally to modify the application's behavior (ie, like changing the default 'sessionManagement' from 'false' to 'true').

Now, we know that CF will NOT process the oAS() on subsequent requests IF it successfully started up.  Before app initialization, CF goes:

onApplicationStart() > onSessionStart() > onRequestStart() > onRequest()/onCFCRequest() > onRequestEnd()

After app initialization, CF goes:

onRequestStart() > onRequest()/onCFCRequest() > onRequestEnd()

But at THAT point, the oAS() ran and validated all code, so even when we're processing a request after app initialization, ColdFusion is probably ignoring all psuedo-constructor logic that changes the THIS scope variables (in effect, caching what the pre-app init run through defined and configured CF to run as)

....am I barking up the right tree here?

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
Enthusiast ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

HEY HEY!

I did this in the pseudo-constructor:

<cfset THIS.name = hash( getCurrentTemplatePath() )>

<cfset THIS.applicationTimeout = createTimeSpan( 0,4,0,0 )>

<cfset THIS.customTagPaths = 'c:\inetpub\wwwroot\project\custom-tags'>

I then commented out the code in my oAS() but did a <cfreturn true>

I then commented out the code in my oRS() but at the top I added:

<cf_param name="der" type="string" default="foo">

I also modified my param.cfm so at the top I added:

<cfabort showerror="This better work!">

And when I ran the request, I GOT THE ABORT'S MESSAGE IN THE PARAM.CFM TAG!

It seems the line of logic you set me down was right.  In the Pseudo-constructor, CF doesn't care WHAT you do, what variables you set.  But once the oAS() starts, it will ensure that special variables in the application.cfc's THIS scope are sanity-checked, and then use their values to modify internal-behavior.

I took it one step futher and moved that <cf_param> call INSIDE the oAS() (right before it returned true), and the code still ran!  This must mean that CF does its sanity checks before it processes the code in the oAS() method.

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 ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

Yep, that was my expectation.

I meant to come back to you before (I was waylaied with someone else's problem...) to clarify that the only place the this.customTagPaths look-ups don't work is in the pseudo-constructor, but once we're at the stage of any of the event handlers running (oAS, oSS, oRS), then your custom tag calls will work fine.  You've discovered this off yer own bat.

--

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
Enthusiast ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

Nah, not on my own.  I'd have never have come to the logical conclusion (and subsequent testing to prove it) without the help you provided.  (Top notch, as always!)

I REALLY think that this is a mechanic of ColdFusion that warrants official documentation.  But in the same way, this level of comprehension is what I love to know.  It's not that "We do THIS because THIS is how it's been done."  It's that "We do THIS because if THAT, when THIS is THAT".  In other words, we now KNOW why CF behaves the way it does.  Rather than being given the fish so that we can eat, we now know HOW to get a fish so that the problem of being hungry doesn't elude us.

I'll run this by my co-worker.  We always love sharing AHHH! So THAT's why-moments after things like this stump us for hours at a time.

The great thing is that this type of behavior is probably duplicated in other areas of ColdFusion; so since we learned it here, that logical thinking can actually prove to help us prevent problems in other areas.  Comprehension will always be better than compensation.

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
Advocate ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

What am I? Chopped Liver?

Anyway, you marked the wrong part of this thread as the correct answer. It should have been #11.

Glad you got it working (even though I don't agree with what you're trying to do).

Jason

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
Enthusiast ,
Oct 10, 2012 Oct 10, 2012

Copy link to clipboard

Copied

Thanks for the assist, chopped liver.

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 ,
Oct 11, 2012 Oct 11, 2012

Copy link to clipboard

Copied

LATEST

Thanks for the assist, chopped liver.

Chuckle.

As an aside, I've taken the liberty of summarising this on my blog: http://adamcameroncoldfusion.blogspot.co.uk/2012/10/clarification-in-my-mind-as-to-how.html.

--

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