Я посмотрел на Catalyst :: View: TT code , чтобы понять контекст переменных.
Следующая подпрограмма, которую я немного суммировал, делаетработа рендеринга:
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 %]
Первая строка удаляет переменную, а вторая выполняет правильный тест.
UPDATE
Если вы можете добавить флаг EVAL_PERL => 1
в вашем представлении Catalyst, внутри config()
аргументов,
__PACKAGE__->config({
# ...
EVAL_PERL => 1
});
, тогда вы можете использовать директиву [% RAWPERL %]
в шаблонах, что дает вам прямой доступ к Template::Context
объект: тогда вы можете удалить Vars и .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 %]