【发布时间】:2011-11-27 14:03:15
【问题描述】:
查看模板工具包手册的Template::Manual::VMethods 部分,我没有看到任何方法可以做到这一点。将 undef 分配给变量也不起作用 - variable.defined 在事后返回 true。
【问题讨论】:
标签: perl template-toolkit
查看模板工具包手册的Template::Manual::VMethods 部分,我没有看到任何方法可以做到这一点。将 undef 分配给变量也不起作用 - variable.defined 在事后返回 true。
【问题讨论】:
标签: perl template-toolkit
好吧,谷歌搜索 "delete variable" site:mail.template-toolkit.org/pipermail/templates/ 带来了 Felipe Gasper 的问题 [Templates] Can I “DELETE some_var”? 和 Petr Danihlik 的两个答案。彼得建议:
[% SET foo = 1 %]
[% IF foo.defined %] defined1 [% END %]
[% PERL %]
delete($stash->{foo});
[% END %]
[% IF foo.defined %] defined2 [% END %]
【讨论】:
[% var %] 而不是 [% stash.var %]。我想知道你是否已经尝试过使用[% stash.var %]。
PERL 指令,如我找到的答案所示,因为我使用的 TT 处理器不允许内联 Perl。
我查看了Catalyst::View:TTcode,以了解变量上下文。
下面的子程序,我稍微总结了一下,做渲染工作:
sub render {
my ( $self, $c, $template, $args ) = @_;
# [...]
my $output; # Template rendering will end here
# Variables interpolated by TT process() are passed inside an hashref
# as copies.
my $vars = {
( ref $args eq 'HASH' ? %$args : %{ $c->stash() } ),
$self->template_vars( $c )
};
# [...]
unless ( $self->template->process( $template, $vars, \$output ) ) {
# [ ... ]
}
# [ ... ]
return $output;
}
TT process() 是用$c->stash 中的变量副本调用的,那么为什么我们需要弄乱$c->stash 来摆脱本地副本呢?也许我们没有。
此外,TT define() VMethod 和其他方法一样,似乎是为列表构建的。当对标量调用 VMethod 时,标量会自动提升为单个元素列表:也许由于这个原因,IF 测试总是返回 true。
我对带有对 DBIx::Class::ResultSet 对象的引用的变量进行了一些测试,这在测试变量时似乎有效:
[%- resultset_rs = undef %]
[%- IF ( resultset_rs ) %]
<h3>defined</h3>
[%- END %]
第一行删除变量,第二行进行适当的测试。
更新
如果您可以在 Catalyst 视图中添加 EVAL_PERL => 1 标志,在 config() 参数内,
__PACKAGE__->config({
# ...
EVAL_PERL => 1
});
然后您可以在模板中使用[% RAWPERL %] 指令,这使您可以直接访问Template::Context 对象:然后您可以删除变量并且.defined() VMethod 做正确的事情。
[%- RAWPERL %]
delete $context->stash->{ 'resultset_rs' };
[%- END %]
[%- IF ( resultset_rs.defined ) %]
<h3>defined: [% resultset_rs %]<h3>
[%- ELSE %]
<h3>undefined: [% resultset_rs %]<h3>
[%- END %]
【讨论】:
0 在布尔上下文中为 false。
[% RAWPERL %] 块中放置一些代码,否则这可能会阻止直接访问变量 hashref。