This is a follow-up on a question that I asked a couple of
months ago. The subject was "executing a cgi from within a
handler (templating redux)", dated 8/23/00.
The gist of the matter is that we need a handler which will
serve html pages ('content files') inside of other html
files ('template files'), while sticking other files and
scripts ('component files') into the template at the same
time. Quasi-frames, if you will. We've already covered
why we didn't pick one of the readily-available packages to
do this.
We've had a working handler that does _almost_everything it
needs to do. When the user requests a page, it figures out
which template to use (based on the page requested), which
component set to use (based on the user and the page),
rolls the whole thing together and sends it along.
The wrapper can handle both static files and scripts as
components or content files, and works really well most of
the time. However, we've run into a problem when a page
needs to redirect after execution, such as a login page.
The problem is that when a component or content file is a
script, the server executes that script when it encounters
it in the template, a'la
- hey, the user wants foo.html
- the user is a member of group 'coders', and their
component path is
/www/htdocs/components/coders/
- foo.html wants template set 1,
- go get /www/htdocs/components/coders/tmpl_1, and open
- begin printing the template file to the browser. As the
file goes by,
watch for <[tags]> containing insertion points.
- hey, there's <[head]>, print or execute
/www/htdocs/components/coders/head_1
- hey, there's <[tool]>, print or execute
/www/htdocs/components/coders/tool_1
- hey, there's <[cont]>, print or execute foo.html
- hey, there's <[foot]>, print or execute
/www/htdocs/components/coders/foot_1
- finish printing /www/htdocs/components/coders/tmpl_1 and
close
If /www/htdocs/components/coders/tool_1 has a redirect call
in it, it's too late for the browser to actually do
anything about it.
I managed to corner Nathan in New York (thanks, Nathan!).
He recommended a two-stage handler, one that processes the
components and content, and another that actually handles
the printing. Using $r->notes, the second handler could be
aware of what it needed to do before printing
anything. This is a really good idea, but it's turning out
to be more difficult than I anticipated.
The only way I can think of doing this is adding a third
handler, in the middle, that executes any scripts and
stores the output somewhere. Then it would check the
output for a Location: header and set something like
$notes->{'redirect'} if it finds anything. The third
handler would then check that value before printing
anything. If it's there, do it; if not, grab the output
and the static files and print them to the user.
I'm concerned about putting large amounts of data into
$r->notes. Some of our script output can be pretty
heavy. If $r->notes can only take simple strings, how
large of a simple string is it safe to put in it? Is there
a better way to do this?
cheers and thanks,
Todd