[Templates] New user & question regarding two-pass processing / persistent data

Randal L. Schwartz merlyn@stonehenge.com
12 Jan 2003 09:14:51 -0800


>>>>> "Lars" == Lars Marowsky-Bree <lars@marowsky-bree.de> writes:

Lars> However, I obviously want to go beyond what SSI could
Lars> do. Namely, I want things like menus to be generated
Lars> automatically ("generate <ul> with all pages which have 'foo' in
Lars> their metadata") or site-internal links to be generated
Lars> automatically (so I can do [% MySite.Link("PageID") %] without
Lars> worrying which path the page actually is at, and also add a
Lars> small language icon to links based on the metadata of the target
Lars> etc).

Lars> I want to build upon ttree to do my bidding, however, for the
Lars> former I need a way to store the metadata in files read
Lars> persistently.

Lars> The simple approach would be to build a big hash with all
Lars> metadata and dump at the end / reread that at startup; this
Lars> would be rather similar to how LaTeX does things and would seem
Lars> to be the simplest approach.

www.stonehenge.com does something like this.  I'm using a makefile to
"build" the site from sources.  One part of the result is top
navigation bar info, and depends on all input html files.  I wrote
small Perl program to examine the tt2 META data for each of the input
files, and generate a resulting tt2 nested hash.  (Each html input
file provides the local and regional navigation information.  If it's
absent, I put the file in a generic navigation location.)  The
resulting nested hash data structure is then processed at page
delivery time (cached in each process) to produce the navbar
appropriate for a particular page.

You could do something similar... you just need to store the
information obtained at build time into some data structure or plugin
that you can grab at run time.  The only tricky part was processing
the HTML files with TT just enough so that I could get at the meta
info.  Here's what I came up with, essentially:

  my $context = Template->new({ RELATIVE => 1, ABSOLUTE => 1})->service->context;

  for (@ARGV) {
    my $document = $context->template($_);
    my $thing1 = $document->thing1 || "some default";
    my $thing2 = $document->thing2 || "some default";
    ...
  }

This extracts the values within the template that look like:

[% META
   thing1 = "this value"
   thing2 = "that value"
%]

>From there, you should be able to tag a particular URL during
build time, and then generate some data structure from that
so that you can point at it at delivery time.

Hope this helps... if you want to see more of the actual code, I'll
tar up my current CVS and send it to you.

(Note to self: make sure that doesn't reveal any security holes. :)

-- 
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!