我的静态网页是由一大堆模板构建的,这些模板是使用Template Toolkit的“import”和“include”包含在内的,因此page.html看起来像这样:
[% INCLUDE top %]
[% IMPORT middle %]
然后top可能会包含更多文件。
我有很多这些文件,他们必须运行以创建各种语言的网页(英语,法语等,而不是计算机语言)。这是一个非常复杂的过程,当一个文件被更新时,我希望能够使用makefile或类似的东西自动重新制作必要的文件。
对于C文件,是否有像makedepend
这样的工具可以解析模板工具包模板并创建依赖关系列表以供在makefile中使用?
还是有更好的方法来自动化这个过程吗?
答案 0 :(得分:3)
Template Toolkit
附带了自己的名为ttree
的命令行脚本,用于构建TT网站。
以下是我在Mac上的TT网站项目中经常使用的ttree.cfg
文件:
# 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
重建网站,只更新源代码(src
)或我的库(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 /
答案 1 :(得分:1)
如果你关心的是找到INCLUDE
,PROCESS
,WRAPPER
等指令中提到的文件名,可以想象甚至使用sed
或{{1从命令行生成依赖项。
但是,如果存在更微妙的依赖关系(例如,您在HTML文档中使用perl
引用图像,其大小是使用Image plugin计算的,则问题可能变得不那么容易处理。
我还没有真正测试过,但以下内容可能会有效:
<img>
答案 2 :(得分: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;
}