【问题标题】:How can I delete variable in Template Toolkit?如何删除模板工具包中的变量?
【发布时间】:2011-11-27 14:03:15
【问题描述】:

查看模板工具包手册的Template::Manual::VMethods 部分,我没有看到任何方法可以做到这一点。将 undef 分配给变量也不起作用 - variable.defined 在事后返回 true。

【问题讨论】:

    标签: perl template-toolkit


    【解决方案1】:

    好吧,谷歌搜索 "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 %]
    

    【讨论】:

    • 有趣。当我们在 TT 模板中使用来自 stash ( Catalyst? ) 的引用时,我们编写 [% var %] 而不是 [% stash.var %]。我想知道你是否已经尝试过使用[% stash.var %]
    • 以这种方式引用变量不会带来任何新的可能性,不是吗?我无法使用PERL 指令,如我找到的答案所示,因为我使用的 TT 处理器不允许内联 Perl。
    【解决方案2】:

    我查看了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 =&gt; 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。
    • 文档部分 Directives/RAWPERL 说:模板工具包解析器读取源模板并生成 Perl 子例程的文本作为输出。然后它使用 eval() 将其评估为子例程引用。除非我们在 [% RAWPERL %] 块中放置一些代码,否则这可能会阻止直接访问变量 hashref。
    • 您更新中的代码与我的答案中显示的代码有何不同?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-15
    • 2011-12-26
    • 1970-01-01
    • 2021-09-15
    • 1970-01-01
    • 2012-10-25
    • 2013-10-25
    相关资源
    最近更新 更多