2010-03-23 15 views
5

mie pagine web statiche sono costruiti da un enorme mazzo di modelli che sono inter-incluso l'utilizzo di "importazione" di Template Toolkit e "include", in modo da page.html assomiglia a questo:Come posso gestire le dipendenze dei modelli in Template Toolkit?

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

Poi superiore potrebbe avere anche più file inclusi.

Possiedo molti di questi file e devono essere eseguiti per creare pagine Web in varie lingue (inglese, francese, ecc., Non lingue del computer). Questo è un processo molto complicato e quando un file viene aggiornato mi piacerebbe essere in grado di rifare automaticamente solo i file necessari, usando un makefile o qualcosa di simile.

Esistono strumenti come makedepend per i file C in grado di analizzare i modelli di modelli di toolkit e creare un elenco di dipendenze da utilizzare in un makefile?

O ci sono modi migliori per automatizzare questo processo?

risposta

3

Template Toolkit viene fornito con un proprio script da riga di comando chiamato ttree per la creazione di siti Web TT di marca.

Ecco un file di ttree.cfg uso spesso uso su progetti di siti web TT qui sul mio 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 

Proprio in esecuzione ttree -f ttree.cfg ricostruirà il sito in dest solo aggiornamento che cosa è stato modificato alla fonte (in src) o nelle mie librerie (in lib).

Per ulteriori dipendenze a grana fine dare un'occhiata a Template Dependencies.

Aggiornamento - Ed ecco il mio pugnalata a lista delle dipendenze arrangiarsi sottoclasse 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; 

Il codice mostrati tutte le dipendenze chiamati (via CONTENERE, INSERT, di processo e WRAPPER) e dove chiamato dall'interno l'intero albero root.tt. Quindi da questo è possibile creare un file di dipendenza ttree.

/I3az/

+0

Trovo 'depend' in' .ttreerc' un po 'instabile e scomodo con lunghe liste di dipendenze. Dovrei guardare in 'ttree' per vedere come stanno affrontando. –

+0

@Aaahh, utilizza 'Testo :: AnalisiParole' per analizzare le dipendenze. Ora, questo spiega molto ;-) In ogni caso, penso che l'OP voglia sapere se è in grado di generare automaticamente tali informazioni di dipendenza in base alle direttive '[% - INCLUDE -%]' etc nei file modello. Tuttavia, +1 per indicare '.ttreerc'. –

+0

@Sinan: avevo 2-3 idee sul bit di dipendenza ma mi sono sentito meglio lasciarlo fuori finché non avessi qualcosa di concreto. Vedi il mio aggiornamento. – draegtun

1

Nel caso in cui tutto ciò che interessa stanno trovando i nomi di file indicato nelle direttive quali INCLUDE, PROCESS, WRAPPER ecc, uno immaginare anche utilizzando sed o perl dalla riga di comando per generare le dipendenze.

Tuttavia, se ci sono le dipendenze più sottili (ad esempio, si fa riferimento a un'immagine utilizzando <img> nel documento HTML la cui dimensione è calcolato utilizzando il Image plugin, il problema può diventare molto meno trattabile.

non ho davvero provato ma qualcosa di simile al seguente potrebbe funzionare:

#!/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

Ci sono molte e molte dipendenze come la '' di cui hai parlato, ma vorrei almeno cominciare a tirarle fuori dal file. Mancano le dipendenze dal mio makefile e quindi le build non riflettono le modifiche quando i template sono modificati. –

0

Dopo aver letto la documentazione ttree, ho deciso di creare qualcosa di me stesso sto postando qui nel caso in cui è utile la prossima persona che arriva Tuttavia, questo.. non è una soluzione generale, ma una che funziona solo per pochi casi limitati.Ha funzionato per questo progetto poiché tutti i file si trovano nella stessa directory e non sono inclusi duplicati. Ho documentato le carenze come commenti prima di ciascuna delle routine.

Se c'è un modo semplice per fare ciò che fa con ttree che mi è mancato, fatemelo sapere.

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; 
} 
Problemi correlati