Frontier Tutorials / Writing an ObjectNotFoundHandler / Bonus: The "Penultimate" Master Script

Bonus: The "Penultimate" Master Script

fatpage picture space picture This page is a Fat Page. It includes the "ultimate" ONFH master script, encoded by and for Frontier. To retrieve the script(s), save the page as source text and open it using the File->Open command.

This page contains a more generic version of the master script presented on the Misdirected URLs page. Here's the script:

« #navTitle "Object Not Found"
« ObjectNotFoundHandler Master Script
local
space picturepageTbl = html.getPageTableAddress()
space picturetoolsTbl = pageTbl^.tools
 
« Parse searchArgs (if any) into temp args table
local ( tempArgs )
new ( tabletype, @tempArgs )
webserver.parseargs( pageTbl^.searchargs, @tempArgs )
if defined( tempArgs.whatObjectNotFound ) « Is this the redirected call?
space picture« This is the redirected call; make Mode 1 return.
space picturepageTbl^.title = "Page Not Found"
space picturepageTbl^.code = 404
space pictureif defined( pageTbl^.notFoundText )
space picture« Put missing subpath in page table for inclusion in #notFoundText
space picturepageTbl^.whatObjectNotFound = string.nthField( tempArgs.whatObjectNotFound, "/", 1 )
space picturereturn ( html.processMacros( string( pageTbl^.notFoundText^ ) ) )
space pictureelse
space picturescriptError ("Can't process the request because there is no object named \""
space picture+ string.nthField( tempArgs.whatObjectNotFound, "/", 1 ) + "\".")
space picturetoolsTbl^.PageNotFound( pageTbl )
 
bundle « Mode 2 & 3 ONFH scripts
space picture« Mode 2 & 3 scripts are assumed to return if unsuccessful, but not if successful.
space picture« As a result, we can simply call them one after another.
space picture« Assume that the scripts are in ["#tools"].ONFH_2and3
space pictureif defined( toolsTbl^.ONFH_2and3 )
space picturelocal
space picturenumHandlers = sizeOf( toolsTbl^.ONFH_2and3 )
space pictureidx
space pictureentryAdr
space picturefor idx = 1 to numHandlers
space pictureentryAdr = @toolsTbl^.ONFH_2and3
space picturewhile typeOf( entryAdr^ ) == addressType
space pictureentryAdr = entryAdr^
space picturetoolsTbl^.ONFH_2and3[idx]()
 
« URL not handled by Mode 3 scripts; do Mode 2 redirect so we can do Mode 1 return without bogus URLs.
local
space picturemyDepth = sizeof(string.parseaddress(this))
space picturenomadDepth = sizeof( string.parseaddress( pageTbl^.lastnomad ) )
space picturetargetDepth = string.countfields(pageTbl^.remainingpath, "/")
space picturegoUpLevels = nomadDepth + targetDepth - myDepth
space picturerelPath = string.filledstring( "../", goUpLevels ) + "nonexistent"
scripterror ("!redirect " + relPath + "?whatObjectNotFound=" + string.urlEncode( pageTbl^.remainingPath ) )

Only the block where the script calls Mode 2 and Mode 3 scripts has changed.

Instead of explicitly calling each subsidiary script from within the master script, it looks for them in a subtable of the #tools table named "ONFH_2and3". It expects each entry to be either a script or an address that can be resolved to a script.

As a result, you can install and remove ONFH scripts without modifying the master script in any way.

Directions For Use

Install the master #objectNotFoundHandler script from this page in your website.

Create a subtable in your #tools table named "ONFH_2and3".

Copy Mode 2 and Mode 3 ONFH handlers (such as the Bonus handlers in this tutorial) into the "ONFH_2and3" table, or enter the addresses of such handlers in the table (e.g., @xfile.mainResponder.ObjectNotFoundHandler).

If you desire, you can create a #notFoundText entry (directive) in your site (or multiple ones at various levels). If you do so, this script will insert the missing path in the page table as whatObjectNotFound, to make it available in #notFoundText. It will then return the text of #notFoundText, after calling html.processMacros on it. For the #notFoundText entry shown in the Mode 1 Example, this would create a hot-link to the site outline (if there were one) and expand the "{whatObjectNotFound}" and "{string( forms^.search )}" macros we inserted in the text.

If you do not create a #notFoundText entry, this script returns a very simple file-not-found page text.

Why Penultimate?

The technique described here to create an ONFH script that works within Manila sites was devised by Jason Levine, and presented in his article, Manila and #objectNotFoundHandler. See that article for a full discussion of the technique.

I call this the penultimate script because it omits something: it doesn't support operation within Manila websites. Because Manila uses an ONFH for its own purposes, you would have to modify this script for use in Manila websites.

In short, the modified script will follow this pattern:

try « Give Manila first try
space picturereturn ( manilaSuite.hierarchyPage() )
else
space pictureif tryError beginsWith "!"
space picture« It's a special scriptError--pass it on.
space picturescriptError( tryError )
space picture« Do your own ONFH processing here.

For a full discussion of why this is required and how it works, see Jason Levine's article, Manila and #objectNotFoundHandler.

Another bonus script: a utility script for creating Mode 3 ONFH handlers.

Tutorial Contents
Writing an ObjectNotFoundHandler
ONFH Overview
ONFH Modes of Operation
About The Examples
Mode 1 Example
Mode 2 Example
Mode 3 Example
Mixing Modes
Misdirected URLs
ONFH Summary
ONFH Applications
ONFH Resources
Bonus: The "Penultimate" Master Script
Bonus: Mode 3 Utility Script
About the Author