Text :: Template模板中的“for”循环

时间:2011-05-06 06:26:34

标签: perl templates texttemplate

我正在尝试将perl Text::Template用于短模板,并且到目前为止无法让它迭代一个数组。

这是我编写的一个简短的测试程序,用于演示我正在尝试做的事情:

#!/usr/bin/perl
use Text::Template;
my $template = Text::Template->new(TYPE => 'STRING', SOURCE => <<'__EOT__');
array[0]: { $array[0] }
{ foreach my $i (@array) { }
 {$i}
}
__EOT__
print $template->fill_in(HASH => { array => [qw(item1 item2)]});

根据Text :: Template手册,我希望打印出来:     array [0]:item1     ITEM1     ITEM2 但相反它打印     array [0]:item1

(即循环外第一行的输出和空行)。

我无法在网络上的任何地方找到任何人在模板中实际使用循环的例子,尽管文档说它应该“正常工作”。

我错过了什么?

2 个答案:

答案 0 :(得分:1)

my $template = Text::Template->new(TYPE => 'STRING', SOURCE => <<'__EOT__',  DELIMITERS => [qw(<% %>)],);

选择不同的分隔符。文档建议您出于各种原因多次这样做,主要是为了更容易使用,因为Perl代码也使用{}括号。它还说:

  

由于缺少反斜杠转义简化了模板的解析,因此使用备用DELIMITERS可以将解析过程加速20-25%。这表明我原来选择的{和}非常糟糕。

Just {$i}在这里不起作用,因为它在void上下文中。文档说:

  

执行的最后一个语句的结果将在标量上下文中进行评估;这个语句的结果是一个字符串,它被插入到模板中代替程序片段本身。

使用$OUT变量重写它:

<% foreach my $i (@array) {
    $OUT .= $i
} %>

文档说:

  

您附加到此变量的任何内容都将显示在模板的输出中。此外,如果在程序片段中使用$ OUT,则禁用用其返回值替换片段的正常行为;而是将片段替换为$ OUT的值。

<% $OUT .= $_ for @array %>

结果相同,但更短。

答案 1 :(得分:0)

几个实验表明:

{ stuff }

变成(有效)像这样的伪perl:

my $x = eval(stuff);
$template =~ s/{ stuff }/$x/;

所以“stuff”需要是一个表达式,以便返回一些东西放入模板中。你的“东西”是一个foreach循环,它没有值,所以你的模板没有做任何有趣的事情。

如果你看一下Text::Template的测试(总是去测试套件的例子,CPAN包的测试套件对于学习如何工作是非常宝贵的),你会看到这样的事情:

{ $t = ''; foreach $n (1 .. 20) { $t .= $n . ' ' } $t }

请注意$t的使用方式。这表明您希望模板更像这样:

array[0]: { $array[0] }
{ $t = ''; foreach my $i (@array) { $t .= "\t$i\n" } }

还有$OUT特殊变量,它可以代替上面的$t。 CPAN软件包的文档通常非常好,非常值得一读,当你使用其他语言时,你会错过它。