5

我的静态网页是由大量模板构建的,这些模板使用 Template Toolkit 的“import”和“include”相互包含,因此 page.html 如下所示:

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

然后 top 可能包含更多文件。

我有很多这些文件,必须运行它们才能以各种语言(英语、法语等,而不是计算机语言)创建网页。这是一个非常复杂的过程,当更新一个文件时,我希望能够使用 makefile 或类似的东西自动重新制作必要的文件。

是否有任何类似makedependC 文件的工具可以解析模板工具包模板并创建依赖项列表以在 makefile 中使用?

或者有没有更好的方法来自动化这个过程?

4

3 回答 3

3

Template Toolkit确实带有自己的命令行脚本ttree,用于构建 TT 网站 ala make。

这是ttree.cfg我在 Mac 上的 TT 网站项目中经常使用的文件:

# 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

仅运行ttree -f ttree.cfg将重建站点,dest仅更新源(in src)或我的库(in lib)中更改的内容。

有关更细粒度的依赖关系,请查看Template Dependencies.

更新- 这是我通过子类化获取依赖列表的尝试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;

上面的代码显示了所有调用的依赖项(通过 INCLUDE、INSERT、PROCESS 和 WRAPPER)以及从整个root.tt树中调用的位置。所以从这里你可以建立一个ttree依赖文件。

/I3az/

于 2010-03-23T12:53:51.767 回答
1

如果您关心的只是查找指令中提到的文件名,例如,INCLUDE等,可以想象甚至使用或从命令行生成依赖项。PROCESSWRAPPERsedperl

但是,如果存在更细微的依赖关系(例如,您<img>在 HTML 文档中引用了使用Image 插件计算大小的图像,则问题可能会变得更难处理。

我还没有真正测试过它,但类似以下的东西可能会起作用:

#!/usr/bin/perl

use strict; use warnings;

use File::Find;
use File::Slurp;
use Regex::PreSuf;

my ($top) = @ARGV;

my $directive_re = presuf qw( INCLUDE IMPORT PROCESS );

my $re = qr{
    \[%-? \s+ $directive_re \s+ (\S.+) \s+ -?%\]
}x;

find(\&wanted => $top);

sub wanted {
    return unless /\.html\z/i;

    my $doc = read_file $File::Find::name;
    printf "%s : %s\n", $_, join(" \\\n", $doc =~ /$re/g );
}
于 2010-03-23T13:16:54.533 回答
0

在阅读了 ttree 文档后,我决定自己创建一些东西。我把它贴在这里,以防它对下一个出现的人有用。但是,这不是通用解决方案,而是仅适用于少数有限情况的解决方案。它适用于这个项目,因为所有文件都在同一个目录中,并且没有重复的包含。我已将缺陷记录为每个例程之前的注释。

如果有一种简单的方法可以对我错过的 ttree 执行此操作,请告诉我。

my @dependencies = make_depend ("first_file.html.tmpl");

# Bugs:
# Insists files end with .tmpl (mine all do)
# Does not check the final list for duplicates.

sub make_depend
{
    my ($start_file) = @_;
    die unless $start_file && $start_file =~ /\.tmpl/ && -f $start_file;
    my $dir = $start_file;
    $dir =~ s:/[^/]*$::;
    $start_file =~ s:\Q$dir/::;
    my @found_files;
    find_files ([$start_file], \@found_files, $dir);
    return @found_files;
}

# Bugs:
# Doesn't check for including the same file twice.
# Doesn't allow for a list of directories or subdirectories to find the files.
# Warning about files which aren't found switched off, due to
# [% INCLUDE $file %]

sub find_files
{
    my ($files_ref, $foundfiles_ref, $dir) = @_;
    for my $file (@$files_ref) {
        my $full_name = "$dir/$file";
        if (-f $full_name) {
            push @$foundfiles_ref, $full_name;
            my @includes = get_includes ($full_name);
            if (@includes) {
                find_files (\@includes, $foundfiles_ref, $dir);
            }
        } else {
#            warn "$full_name not found";
        }
    }
}

# Only recognizes two includes, [% INCLUDE abc.tmpl %] and [% INCLUDE "abc.tmpl" %]

sub get_includes
{
    my ($start_file) = @_;
    my @includes;
    open my $input, "<", $start_file or die "Can't open $start_file: $!";
    while (<$input>) {
        while (/\[\%-?\s+INCLUDE\s+(?:"([^"]+)"|(.*))\s+-?\%\]/g) {
            my $filename = $1 ? $1 : $2;
            push @includes, $filename;
        }
    }
    close $input or die $!;
    return @includes;
}
于 2010-03-24T00:21:13.960 回答