Perrin Harkins <[EMAIL PROTECTED]> said something to this effect on 10/29/2001:
> > I am writing a web-based template processing service somewhat
> > like Apache::Template, which adds a few configurable behaviors
> > to TT2 to make it act somewhat more like HTML::Mason. Among
> > these are the ability for providers to search the working
> > directory of a template and all its parent directories, up to a
> > specified root directory, similar to how autohandlers and
> > dhandlers are looked for in mason.
...
> > So in order to do the current-directory-sensitive behavior, I
> > have had to subclass Template::Context, Template::Provider, and
> > Template::Document (Context keeps a stack of Documents that
> > updates in the visit/leave methods, Provider implements the new
> > search logic, Document remembers its location). I've also had
> > to extend the existing API in incompatible ways, namely
> > reverting visit/leave to an earlier behavior, and passing extra
> > args to Provider::fetch (the latter is compatible -- for now).
>
> You did all of that just to get TT to climb the directory tree
> when resolving template calls? Why don't you just vary the
> include path on each request? TT already knows how to climb
> the include path.
I had the same reaction, although I kept it to myself. :) I've
written a mod_perl handler which does this, too; it recreates the
INCLUDE_PATH on each request, based on $r->filename. The sub I
use to recreate it looks like this:
#------------------------------------------------------------------------
# _inc_path($filename)
#
# This creates a list of directories to be returned to the provider,
# and specifies how provider searches for included files. This hack
# makes the provider walk up the directory hierarchy to find the
# closest occurance of a file to include. This facilitates, for
# example, putting different headers and footers at various places
# along the tree.
#------------------------------------------------------------------------
sub _inc_path ($) {
my $f = shift;
my %uniq;
my @dir;
local $" = '/';
#
# This bit of code returns a reference to a list of directories,
# sorted in reverse order by length, starting from the directory
# in which the translated filename lives, and ending with /.
#
return [
sort { length $b <=> length $a } # reverse sorted by length
grep { ++$uniq{$_} == 1 } # (unique directories only)
map { push @dir, $_; "/@dir"; } # a growing list of dirs
($f =~ m:([^/]+)/:og) # gathered from the current
]; # translated filename
}
It gets called as:
$INCLUDE_PATH = _inc_path($r->filename);
Simple, strightforward, efficient. The only limitation is that
it goes all the way to /, which can be gotten around pretty
easily (and is left an an exercise for the reader. ;).
(darren)
--
There is a fine line between participation and mockery.