onMissingTemplate Example
I just added onMissingTemplate support to ColdFusionBloggers.org. This is something we should all do with ColdFusion 8 sites as it is so simple it doesn't make sense not to. To test, simply visit:
http://www.coldfusionbloggers.org/parishiltonisfetch.cfm
Here is what I added to my Application.cfc file:
<cffunction name="onMissingTemplate" returnType="boolean" output="false">
<cfargument name="thePage" type="string" required="true">
<cflog file="cfblgogersmissingfiles" text="#arguments.thePage#">
<cflocation url="404.cfm?thepage=#urlEncodedFormat(arguments.thePage)#" addToken="false">
</cffunction>
The first thing I do is log the request. As I've mentioned before, logging the 404 can be handy as you may see people requesting the same file again and again. It may be worthwhile to add that page and put a redirect there or some other content. I then cflocate to a handler. My handler is rather simple (I've trimmed out some of the silly text):
<cfparam name="url.thePage" default="">
<cfif not len(trim(url.thePage))>
<cflocation url="index.cfm" addToken="false">
</cfif>
<cf_layout title="File Not Found">
<h2>These are not the droids you are looking for...</h2>
<p>
Sorry, but the page you requested, <cfoutput>#url.thePage#</cfoutput>, was not
found on this site.
</p>
</cf_layout>
As you can see, I check for the existence of the URL variable (in case people visit the 404 page directly) and print out a message telling the user that their file didn't exist.
I've updated the code zip on ColdFusionBloggers.org. It now contains this change and the "auto refreshing div" modification I made yesterday.
Comments
It's called Parisite.com.
I have see quite a few websites that display ugly extensive errors when something a bit more end-user friendly should be displayed.
er,
http://www.garyrgilbert.com/parishiltonisfetch.cfm...
http://www.coldfusionjedi.com/parishiltonisfetch.c...
You've got a 302 redirect in there still...
So you're saying "The parishiltonfetch.cfm page *does* exist, but is temporarily elsewhere" then you get the 404 for the "elsewhere" page...
Can you make the cflocation into a 301 redirect?
Or better still, can you not cfinclude your 404.cfm page directly from within onMissingTemplate? That way you'd avoid the "302 moved temporarily" redirect? - the 404 would then apply to "parishiltonfetch.cfm" not to "404.cfm?thepage=%2Fparishiltonfetch%2Ecfm"
Try this:
http://www.seoconsultants.com/tools/headers/
<cfif not len(trim(url.thePage))>
<cflocation url="index.cfm" addToken="false">
</cfif>
should be:
<cfif not len(trim(url.thePage))>
<cfheader statuscode="404" statustext="Not Found">
<cfabort>
</cfif>
Just my 2 cents - can you tell I hate <cflocation> ?? ;-)
http://www.coldfusionbloggers.org/parishiltonisfet...
Nice default IIS page.
<cffunction name="onMissingTemplate" returnType="boolean" output="true">
<cfargument name="thePage" type="string" required="true" />
<cfset somevariable=thepageyoutriedtoget />
<cfinclude template="404.cfm" />
<cfreturn true />
</cffunction>
Using this cfinclude method, I'm not redirecting (302 or 301) then serving a 404, hence the 404 will apply to the page you tried to get, not to the 404.cfm page itself...
http://www.coldfusionbloggers.org/404.cfm?thepage=';alert(String.fromCharCode(88,83,83))//\';alert(String.fromCharCode(88,83,83))//%22;alert(String.fromCharCode(88,83,83))//\%22;alert(String.fromCharCode(88,83,83))//--%3E%3C/SCRIPT%3E%22%3E'%3E%3CSCRIPT%3Ealert(String.fromCharCode(88,83,83))%3C/SCRIPT%3E
Not a big problem, but should be fixed.
<cffunction name="onMissingTemplate" returnType="boolean" output="true">
<cfargument name="targetPage" type="string" required="true" />
<cftry>
<cflog type="error" text="Missing template: #Arguments.targetPage#">
<cfinclude template="404.cfm" />
<cfreturn true />
<cfcatch>
<cfreturn false />
</cfcatch>
</cftry>
</cffunction>
</cfcomponent>
I like pointless code :->
For some reason I am getting an error thrown by the onMissingTemplate function for my 404 page ... request was not of type boolean ... very strange ... here's what I came up with as a slight change to Geoff's code ...
<cffunction name="onMissingTemplate" returnType="void" output="true">
<cfargument name="targetPage" type="string" required="true" />
<cflog type="error" text="Missing template: #Arguments.targetPage#">
<cfinclude template="404.cfm" />
</cffunction>
However, when I changed the retrunType to void ... there is no problem ...
Any reason why an error would be thrown from the return type being set as boolean?
So to be clear you have 2 things here:
a) First is the returnType must match rule, which applies _everywhere_
b) Second is the application behavior depeneding on what you do in the method
One step forward ...
GetPageContext().forward(), and GetPageContext().include().


It bothers me that this only works for .CFM pages, but still, very cool.