|Frontier Tutorials / Writing an ObjectNotFoundHandler / Misdirected URLs|
The Mode 1 scripts described in the Mode 1 Example can result in incorrect URLs being generated on the page. In fact, since the Master ONFH handler described in Mixing Modes defaults to function as a similar Mode 1 script, it will also exhibit this behavior.
This happens when the objectNotFoundHandler is at a different level than that which The Walk reached before giving up and rendering the objectNotFoundHandler.
To see why this is so, let's posit a website with this structure:
And let's see what happens when the requested URL is http://theSite/subs/notThere.
The Walk terminates at @theSite.subs when mainResponder.respond fails to locate an entry named notThere. But it finds your #objectNotFoundHandler in the page table. So mainResponder.respond puts lastNomad=@theSite.subs and remainingPath="notThere" in the page table, and calls the ONFH script.
The ONFH script does its thing, and returns the expected text, which the website framework inserts into the template. But when the template's navbar macro is expanded, the information in the page table indicates that it's at the top level of the website (where the #objectNotFoundHandler appears) rather than inside the subs subdirectory, and generates the relative links accordingly.
The browser then interprets these relative links as being relative to the page that was returned, which appears (to the browser) to be at http://theSite/subs/notThere. Voila--Bogus URLs!
We'd see the same behavior if the quoted string (would-be link) to "Site Outline" were expanded.
The basic problem is that the ONFH handler isn't necessarily in the same table or subtable that The Walk reached before giving up and rendering the ONFH handler. To resolve the problem, therefore, we need to make sure that the page table reflects the actual location of the ONFH handler.
The simplest solution to this is to not use a Mode 1 ONFH. Instead, simply redirect to another URL within the website, such as a search page. This is the basis of Mode 2 ONFH scripts, as described in the Mode 2 Example.
However, it is possible to fix this within a Mode 1 ONFH.
The easy and obvious fix isn't available to us: we could simply set adrPageTable^.adrObject to the address of an existing page entry within the table pointed to by adrPageTable^.lastNomad. This would take care of most of the bad URLs, because most (if not all) scripts that generate relative URLs read the current page address from adrObject. However, in scripts such as the navbar macro, this would result in an un-linked entry instead of a real, linked entry.
There is a fix, but it takes us halfway to Mode 2.
The fix is to redirect to a nonexistent page in the same table/directory as the #objectNotFoundHandler. This will result in another rendering of the #objectNotFoundHandler, but from the directory in which it resides. Once we have done that, the relative links will be properly rendered.
Let's work with the with the master ONFH script from Mixing Modes, since that gives us the greatest leverage. The following is the master script after modification.
There are three major blocks in the revised script.
The second block is unchanged from the original script. It simply calls any number of Mode 2 & 3 handlers.
The third block does a Mode 2 redirect back to the #objectNotFoundHandler (actually, to a nonexistent page in the same table as the #objectNotFound handler, but the effect is the same). It tacks the missing subpath onto the URL as a search argument.
The first block checks for the presence of the "whatObjectNotFound" field in the searchArgs. If it finds the field, it generates and returns a page-not-found page (Mode 1), as in the expanded script in the Mode 1 Example.
The third and first blocks, in combination, fix the misdirected-URLs problem.