Как я могу обработать шаблонные зависимости в Шаблонном Инструментарии?

Мои статические веб-страницы создаются из огромного набора шаблонов, которые межвключены с помощью Шаблонного Инструментария "импорт" и "включают", таким образом, page.html похож на это:

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

Затем вершина могла бы иметь еще больше включенных файлов.

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

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

Или есть ли лучшие способы автоматизировать этот процесс?

5
задан 24 March 2010 в 00:49
поделиться

3 ответа

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 :: 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 /

3
ответ дан 15 December 2019 в 00:57
поделиться

Прочитав документацию по 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;
}
0
ответ дан 15 December 2019 в 00:57
поделиться

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

Однако, если есть более тонкие зависимости (например, вы ссылаетесь на изображение с помощью в своем 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 );
}
1
ответ дан 15 December 2019 в 00:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: