Как я могу обрабатывать зависимости шаблона в Template Toolkit? - PullRequest
5 голосов
/ 23 марта 2010

Мои статические веб-страницы построены из огромного набора шаблонов, которые взаимно включаются с использованием «импорта» и «включения» Template Toolkit, поэтому page.html выглядит следующим образом:

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

Тогда сверхувозможно, в него включено еще больше файлов.

У меня очень много этих файлов, и их нужно просмотреть, чтобы создать веб-страницы на разных языках (английском, французском и т. д., а не на компьютерных языках).Это очень сложный процесс, и когда один файл обновляется, я хотел бы иметь возможность автоматически переделывать только необходимые файлы, используя make-файл или что-то подобное.

Существуют ли такие инструменты, как makedepend для файлов C, которые могут анализировать шаблоны набора шаблонов и создавать список зависимостей для использования в make-файле?

Или есть более эффективные способы автоматизации этого процесса?

Ответы [ 3 ]

3 голосов
/ 23 марта 2010

Template Toolkit поставляется со своим собственным скриптом командной строки с именем ttree для создания веб-сайтов TT ala make.

Вот файл ttree.cfgЯ часто использую проекты на веб-сайтах TT здесь, на моем 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

Просто запуск 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 голос
/ 23 марта 2010

В случае, если все, что вас волнует, - это найти имена файлов, упомянутые в директивах, таких как INCLUDE, PROCESS, WRAPPER и т. Д., Можно даже представить, используя sed или perl из командной строки для создания зависимостей .

Однако, если существуют более тонкие зависимости (например, вы ссылаетесь на изображение, используя <img> в своем HTML-документе, размер которого рассчитывается с помощью Плагин для изображения , проблема может стать гораздо менее решаемой.

Я действительно не проверял это, но что-то вроде следующего может работать:

#!/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 );
}
0 голосов
/ 24 марта 2010

Прочитав документацию по дереву, я решил создать что-то сам. Я публикую это здесь на случай, если это пригодится следующему человеку, который придет. Однако это не общее решение, а решение, которое работает только для нескольких ограниченных случаев. Он работал для этого проекта, так как все файлы находятся в одном каталоге и нет дубликатов включений. Я задокументировал недостатки как комментарии перед каждой из подпрограмм.

Если есть простой способ сделать то же самое с 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;
}
...