Глядя на раздел Template::Manual::VMethods руководства по Template Toolkit, я не не вижу никакого метода, делающего это. Также не работает присвоение undef
переменной - variable.defined
возвращает true постфактум.
Как я могу удалить переменную в Template Toolkit?
Ответы (2)
Что ж, гугление "delete variable" site:mail.template-toolkit.org/pipermail/templates/
принесло вопрос [Templates] Могу ли я «УДАЛИТЬ some_var ”? от Фелипе Гаспера с двумя ответами от Петра Данихлика. Петр предлагает:
[% SET foo = 1 %]
[% IF foo.defined %] defined1 [% END %]
[% PERL %]
delete($stash->{foo});
[% END %]
[% IF foo.defined %] defined2 [% END %]
[% var %]
вместо [% stash.var %]
. Мне интересно, пробовали ли вы уже возиться с [% stash.var %]
.
- person Marco De Lellis; 29.09.2011
PERL
, как показано в ответе, который я нашел, потому что процессор TT, который я использую, не допускает встроенный Perl.
- person Piotr Dobrogost; 29.09.2011
Я просмотрел 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 View, внутри аргументов 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
, которое является ложным в логическом контексте.
- person Piotr Dobrogost; 29.09.2011
[% RAWPERL %]
.
- person Marco De Lellis; 29.09.2011
[% RAWPERL %]
более эффективен, чем [% PERL %]
: Директива RAWPERL позволяет вам писать код Perl, который интегрируется непосредственно в сгенерированный текст подпрограммы Perl. Он оценивается один раз во время компиляции и сохраняется в кэшированной форме как часть подпрограммы скомпилированного шаблона. Это делает блоки RAWPERL более эффективными, чем блоки PERL. Я думаю, вы должны принять свой собственный ответ, который был хорошей возможностью заглянуть под прикрытие TT.
- person Marco De Lellis; 30.09.2011