如何删除 Template Toolkit 中的变量?

发布于 2024-12-07 04:38:11 字数 228 浏览 4 评论 0原文

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

Looking at Template::Manual::VMethods section of the Template Toolkit manual I don't see any method doing this. Also assigning undef to variable doesn't work - variable.defined returns true after the fact.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

美人如玉 2024-12-14 04:38:11

好吧,谷歌搜索“删除变量”站点:mail.template-toolkit.org/pipermail/templates/带来了问题[模板] 我可以“DELETE some_var”吗? 来自 Felipe Gasper,来自 Petr 的两个答案丹尼利克.彼得建议:

[% SET foo = 1 %]
[% IF foo.defined %] defined1 [% END %]
[% PERL %]
delete($stash->{foo});
[% END %]
[% IF foo.defined %] defined2 [% END %]

Well, googling "delete variable" site:mail.template-toolkit.org/pipermail/templates/ brought the question [Templates] Can I “DELETE some_var”? from Felipe Gasper with two answers from Petr Danihlik. Petr suggests:

[% SET foo = 1 %]
[% IF foo.defined %] defined1 [% END %]
[% PERL %]
delete($stash->{foo});
[% END %]
[% IF foo.defined %] defined2 [% END %]
卸妝后依然美 2024-12-14 04:38:11

我查看了 Catalyst::View: TT 代码,以便理解变量上下文。

我总结了以下子例程,它负责渲染工作:

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 %]

第一行删除变量,第二行进行正确的测试。

更新

如果您可以添加EVAL_PERL => 1 标志在 Catalyst 视图的 config() 参数内,

__PACKAGE__->config({
    # ...
    EVAL_PERL => 1
});

然后您可以在模板中使用 [% RAWPERL %] 指令,这使您可以直接访问Template::Context 对象:那么您可以删除变量,并且 .define() VMethod 会做正确的事情。

[%- RAWPERL %]
    delete $context->stash->{ 'resultset_rs' };
[%- END %]
[%- IF ( resultset_rs.defined ) %]
    <h3>defined: [% resultset_rs %]<h3>
[%- ELSE %]
    <h3>undefined: [% resultset_rs %]<h3>
[%- END %]

I looked at Catalyst::View:TT code, in order to understand variables context.

The following subroutine, which I summarized a little bit does the rendering work:

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() is called with copies of variables in $c->stash, so why do we need to mess with $c->stash to get rid of a local copy? Maybe we don't.

Moreover, TT define() VMethod, like other methods, seem to have been built for lists. Scalars are auto-promoted to single element list when a VMethod is called on them: maybe for this reason the IF test returns always true.

I did some tests with variables carrying references to DBIx::Class::ResultSet objects, and this seems to work while testing for a variable:

[%- resultset_rs = undef %]
[%- IF ( resultset_rs ) %]
    <h3>defined</h3>
[%- END %]

The first line deletes the variable, and the second does proper test.

UPDATE

If you can add EVAL_PERL => 1 flag in your Catalyst View, inside config() argumets,

__PACKAGE__->config({
    # ...
    EVAL_PERL => 1
});

then you can use [% RAWPERL %] directive in templates, which gives you direct access to the Template::Context object: then you can delete vars and .defined() VMethod does the right thing.

[%- RAWPERL %]
    delete $context->stash->{ 'resultset_rs' };
[%- END %]
[%- IF ( resultset_rs.defined ) %]
    <h3>defined: [% resultset_rs %]<h3>
[%- ELSE %]
    <h3>undefined: [% resultset_rs %]<h3>
[%- END %]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文