5

私の静的Webページは、Template Toolkitの「import」と「include」を使用して相互に含まれる膨大な数のテンプレートから構築されているため、page.htmlは次のようになります。

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

その場合、topにはさらに多くのファイルが含まれる可能性があります。

私はこれらのファイルを非常に多く持っており、さまざまな言語(コンピューター言語ではなく、英語、フランス語など)でWebページを作成するためにそれらを実行する必要があります。これは非常に複雑なプロセスであり、1つのファイルが更新されたときに、makefileなどを使用して、必要なファイルのみを自動的に再作成できるようにしたいと思います。

makedependテンプレートツールキットテンプレートを解析し、makefileで使用するための依存関係リストを作成できるCファイルのようなツールはありますか?

または、このプロセスを自動化するためのより良い方法はありますか?

4

3 に答える 3

3

Template ToolkitttreeTTWebサイトを構築するために呼び出される独自のコマンドラインスクリプトが付属しています。

これは、ttree.cfg私のMacのTTWebサイトプロジェクトでよく使用するファイルです。

# 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でサイトが再構築されます。destsrclib

よりきめ細かい依存関係については、を参照してください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、、などのディレクティブで言及されているファイル名を見つけることだけが気になる場合はPROCESS、コマンドラインを使用して、またはコマンドラインから依存関係を生成することWRAPPERを想像してみてください。sedperl

ただし、より微妙な依存関係がある場合(たとえば、 HTMLドキュメントでImageプラグイン<img>を使用してサイズが計算された画像を参照する場合、問題ははるかに扱いにくくなる可能性があります。

私は実際にはテストしていませんが、次のようなものが機能する可能性があります。

#!/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 に答える