[Templates] hierarchical nav toolbars - work in progress
Randal L. Schwartz
merlyn@stonehenge.com
22 Mar 2002 10:31:53 -0800
OK, I hit an interesting breakthrough yesterday... I'm redesigning
stonehenge.com to use Template, and at the same time, I wanted to
change the look and feel to have more-or-less automatic navbars.
I think I've talked about this once or twice before.
The solution I've stumbled is to build hierarchical navbars using
static templates like this:
** stonehenge/nav/top **
[%
'Welcome to stonehenge.com!' WRAPPER stonehenge/nav_master buttons = [
{ link = '/merlyn/' text = 'Randal' },
{ link = '/' text = 'Stonehenge' },
];
%]
** stonehenge/nav/merlyn **
[%
INCLUDE stonehenge/nav/top select='Randal';
'Randal L. Schwartz' WRAPPER stonehenge/nav_master buttons = [
{ link = '/merlyn/columns.html' text = 'Columns' },
{ link = '/merlyn/references.html' text = 'References' },
];
%]
** stonehenge/nav/columns **
[%
INCLUDE stonehenge/nav/merlyn select='Columns';
'Columns by Randal' WRAPPER stonehenge/nav_master buttons = [
{ link = '/merlyn/WebTechniques/' text = 'WT Columns' },
];
%]
(stonehenge/nav_master is my hacked version of spash/menubar
with the same invocation parameters, if you want to follow along.)
and so on. Notice that invoking stonehenge/nav/columns first
puts the upper part of the hierarchy above it, then does the detail
level.
These get invoked from a "style" sheet, like so
** stonehenge/style/columns **
[%
PROCESS stonehenge/nav/columns select=template.instance;
content
%]
and the style sheet gets invoked from my top-level wrapper like so:
myclass = template.class or 'default';
PROCESS $template WRAPPER "stonehenge/style/$myclass";
So columns.html has meta like:
[% META
class='columns'
instance='Columns'
superclass='merlyn'
%]
Thus saying that this page has a style of 'columns', and is specifically
the 'Columns' instance. All pages with common nav bars and layouts
use the same 'style' sheet.
Ahh, but how are the superclass entries used? That's the cool part.
I have a Perl script that walks through and *compiles* all the
pages to extract the meta info (snippet):
use File::Find;
my @files;
find sub {
return if $File::Find::name eq "$DOCROOT/play.html";
push @files, $File::Find::name if /\.html$/;
}, $DOCROOT;
my %bars;
use Template;
my $c = Template->new({
RELATIVE => 1,
ABSOLUTE => 1,
})->service->context;
for (@files) {
my $d = $c->template($_);
my $class = $d->class || "NONE";
my $instance = $d->instance || "NONE";
my $title = $d->title || "NONE";
if (my $super = $d->superclass) {
$bars{$class}{super} = $super;
$bars{$class}{instance} = $instance;
$bars{$class}{title} = $title;
$class = $super;
}
push @{$bars{$class}{buttons}}, [$_, $instance, $title];
}
Looky that. I extract the class/instance/title for all pages, and
also the superclass. If it's a super node, then it gets hoisted to
the parent bar as one of the down-links. I then just need to
dump the data out:
for my $class (sort keys %bars) {
my $hash = $bars{$class};
my $instance = $hash->{instance};
my $title = $hash->{title};
my $filepath = "$TEMPLATEROOT/$NAVPREFIX/$class";
open STDOUT, ">$filepath.tmp" or die;
print "[%\n";
if (my $super = $hash->{super}) {
print " INCLUDE $NAVPREFIX/$super select='$instance';\n";
}
print " '$title' WRAPPER stonehenge/nav_master buttons = [\n";
warn "processing $class\n";
if ($hash->{buttons}) {
my @buttons = @{$hash->{buttons}};
warn "$class has ".@buttons." buttons\n";
for my $item (sort {$a->[1] cmp $b->[1]} @buttons) {
my ($link, $text) = @$item;
$link =~ s/^\Q$DOCROOT//;
$link =~ s/\/index\.html$/\//;
print " { link = '$link' text = '$text' },\n";
}
}
print " ];\n";
print "%]\n";
close STDOUT;
rename "$filepath.tmp", $filepath or die "Cannot rename $filepath: $!";
}
I've still got to deal with string-quoting and a few other issues
(like how to get a left-nav bar instead of a top-bar some of the
time), but this is pretty exciting now. It's extremely flexible,
driven entirely by meta-doc info in the tree.
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!