2010-03-23 24 views
5

trang web tĩnh của tôi được xây dựng từ một bó lớn các mẫu mà là liên bao gồm việc sử dụng "nhập khẩu" Template Toolkit và "bao gồm", vì vậy page.html trông như thế này:Tôi có thể xử lý các phụ thuộc mẫu trong Bộ công cụ mẫu như thế nào?

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

Sau đó, đầu có thể có thậm chí nhiều tệp hơn.

Tôi có rất nhiều tệp này và chúng phải được chạy qua để tạo trang web bằng nhiều ngôn ngữ khác nhau (tiếng Anh, tiếng Pháp, v.v., không phải ngôn ngữ máy tính). Đây là một quá trình rất phức tạp và khi một tập tin được cập nhật, tôi muốn có thể tự động làm lại chỉ những tập tin cần thiết, sử dụng một makefile hoặc một cái gì đó tương tự.

Có bất kỳ công cụ nào như makedepend cho các tệp C có thể phân tích cú pháp mẫu của bộ công cụ mẫu và tạo danh sách phụ thuộc để sử dụng trong tệp makefile không?

Hoặc có cách nào tốt hơn để tự động hóa quá trình này?

Trả lời

3

Template Toolkit không có tập lệnh dòng lệnh riêng được gọi là ttree để xây dựng trang web TT mà chúng tôi thực hiện.

Dưới đây là một tập tin ttree.cfg tôi sử dụng thường xuyên sử dụng trên TT dự án trang web ở đây trên máy Mac của tôi:

# 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 

Chỉ cần chạy ttree -f ttree.cfg sẽ xây dựng lại trang web trong dest chỉ cập nhật whats được thay đổi tại nguồn (trong src) hoặc trong thư viện của tôi (trong lib).

Đối với các phụ thuộc hạt mịn hơn, hãy xem Template Dependencies.

Cập nhật - Và đây là đâm của tôi lúc nhận được danh sách phụ thuộc bởi subclassing 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; 

Đoạn mã trên hiển thị tất cả phụ thuộc gọi (thông qua BAO GỒM NHỮNG SỰ, INSERT, QUY TRÌNH và wrapper) và nơi gọi từ bên trong toàn bộ cây root.tt. Vì vậy, từ đây bạn có thể xây dựng một tệp phụ thuộc ttree.

/I3az/

+0

Tôi tìm thấy 'depend' trong' .ttreerc' một chút flaky và bất tiện với danh sách dài các phụ thuộc. Tôi nên tìm trong 'ttree' để xem họ đối phó với nó như thế nào. –

+0

@Aaahh, nó sử dụng 'Text :: ParseWords' để phân tích cú pháp các phụ thuộc. Bây giờ, điều đó giải thích rất nhiều ;-) Trong mọi trường hợp, tôi nghĩ rằng OP muốn biết liệu anh ta có thể tự động tạo thông tin phụ thuộc đó dựa trên các chỉ thị '[% - INCLUDE -%]' etc trong các tệp khuôn mẫu hay không. Tuy nhiên, +1 để chỉ ra '.ttreerc'. –

+0

@ Sinan: Tôi đã có 2-3 ý tưởng về bit phụ thuộc nhưng cảm thấy tốt nhất để nó ra cho đến khi tôi có một cái gì đó cụ thể. Xem cập nhật của tôi. – draegtun

1

Trong trường hợp tất cả các bạn quan tâm đến việc tìm kiếm được tên tập tin đề cập trong chỉ thị như INCLUDE, PROCESS, WRAPPER vv, một tưởng tượng thậm chí sử dụng sed hoặc perl từ dòng lệnh để tạo ra phụ thuộc.

Tuy nhiên, nếu có phụ thuộc tinh vi hơn (ví dụ, bạn tham khảo một hình ảnh sử dụng <img> trong tài liệu HTML của bạn có kích thước được tính bằng cách sử dụng Image plugin, vấn đề có thể trở nên ít nhiều dể làm.

tôi đã không thực sự thử nghiệm nó nhưng một cái gì đó như sau có thể làm việc:

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

Có rất nhiều và nhiều phụ thuộc như '' một trong những bạn đã đề cập, nhưng tôi muốn ít nhất là bắt đầu kéo chúng ra khỏi tệp. Tôi giữ thiếu phụ thuộc từ makefile của tôi, và sau đó xây dựng không phản ánh thay đổi khi các mẫu được chỉnh sửa. –

0

Sau khi đọc các tài liệu hướng dẫn ttree, tôi quyết định tạo ra một cái gì đó bản thân mình tôi đăng nó ở đây trong trường hợp nó là hữu ích để người kế tiếp dám đến cùng Tuy nhiên, đây.. không phải là một giải pháp chung, nhưng một giải pháp chỉ hoạt động trong một vài trường hợp giới hạn.Nó làm việc cho dự án này vì tất cả các tệp nằm trong cùng một thư mục và không có bản sao nào được bao gồm. Tôi đã ghi lại những thiếu sót như bình luận trước mỗi thói quen.

Nếu có cách đơn giản để làm việc này với ttree mà tôi đã bỏ lỡ, vui lòng cho tôi biết.

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; 
} 
Các vấn đề liên quan