Search code examples
perlmakefiletemplate-toolkit

How can I handle template dependencies in Template Toolkit?


My static web pages are built from a huge bunch of templates which are inter-included using Template Toolkit's "import" and "include", so page.html looks like this:

[% INCLUDE top %]
[% IMPORT middle %]

Then top might have even more files included.

I have very many of these files, and they have to be run through to create the web pages in various languages (English, French, etc., not computer languages). This is a very complicated process and when one file is updated I would like to be able to automatically remake only the necessary files, using a makefile or something similar.

Are there any tools like makedepend for C files which can parse template toolkit templates and create a dependency list for use in a makefile?

Or are there better ways to automate this process?


Solution

  • Template Toolkit does come with its own command line script called ttree for building TT websites ala make.

    Here is an ttree.cfg file I use often use on TT website projects here on my Mac:

    # directories
    src = ./src
    lib = ./lib
    lib = ./content
    dest = ./html
    
    # pre process these site file
    pre_process = site.tt
    
    # copy these files
    copy = \.(png|gif|jpg)$
    
    # ignore following
    ignore = \b(CVS|RCS)\b
    ignore = ^#
    ignore = ^\.DS_Store$
    ignore = ^._
    
    # other options
    verbose
    recurse
    

    Just running ttree -f ttree.cfg will rebuild the site in dest only updating whats been changed at source (in src) or in my libraries (in lib).

    For more fine grained dependencies have a look a Template Dependencies.

    Update - And here is my stab at getting dependency list by subclassing Template::Provider:

    {
        package MyProvider;
        use base 'Template::Provider';
    
        # see _dump_cache in Template::Provider
        sub _dump_deps {
            my $self = shift;
    
            if (my $node = $self->{ HEAD }) {
                while ($node) {
                    my ($prev, $name, $data, $load, $next) = @$node;
            
                    say {*STDERR} "$name called from " . $data->{caller}
                        if exists $data->{caller};
            
                    $node = $node->[ 4 ];
                }
            }
        }
    }
    
    
    use Template;
    
    my $provider = MyProvider->new;
    
    my $tt = Template->new({
        LOAD_TEMPLATES => $provider,
    });
    
    $tt->process( 'root.tt', {} ) or die $tt->error;
    
    $provider->_dump_deps;
    

    The code above displays all dependencies called (via INCLUDE, INSERT, PROCESS and WRAPPER) and where called from within the whole root.tt tree. So from this you could build a ttree dependency file.

    /I3az/