Subject: | Unable to use a LOOP variable as a boolean unless |
You can't use a tmpl_loop variable as a boolean, unless the variable is
used as a loop inside the conditional.
So this is legal:
<tmpl_if myLoop><tmpl_loop myLoop><tmpl_var loopIndex></tmpl_loop></tmpl_if>
But this isn't:
<tmpl_if myLoop>You have a loop</tmpl_if>
I've attached a test that exposes this behavior, as well as a prototype
patch from a friend.
Subject: | 12-loop-boolean.t |
use strict;
use warnings;
use Test::More
qw(no_plan);
# tests => 3;
use_ok('HTML::Template');
my ($template);
my $tmpl_string = <<EOTEMPLATE;
<TMPL_IF myLoop>You have a loop</TMPL_IF>
EOTEMPLATE
$template = HTML::Template->new_scalar_ref( \$tmpl_string );
# test for non existing param
my $value;
eval {
$value = $template->param({ myLoop => [0, 1, 2, ], });
};
TODO: {
local $TODO = 'Loops used as booleans seem to need to be used as loops inside the conditional to pass';
is($value, 'You have a loop', 'Loop used as boolean');
unlike($@,
qr/with an array ref - parameter is not a TMPL_LOOP/,
"Shouldn't have any error messages at all");
}
=head1 NAME
t/12-loop-boolean.t
=head1 OBJECTIVE
Provide a test to show that loops should be able to be used as
booleans in a TMPL_IF, unless the conditional contains a TMPL_LOOP
using that loop.
=cut
Subject: | patch-for-unknown-vartype.diff |
--- Template.pm 2007-01-29 13:32:21.000000000 -0600
+++ /data/wre/prereqs/lib/perl5/site_perl/5.8.8/HTML/Template.pm 2008-01-15 13:26:48.000000000 -0600
@@ -2020,7 +2020,7 @@
# if we already have this var, then simply link to the existing
# HTML::Template::VAR, else create a new one.
my $var;
- if (exists $pmap{$name}) {
+ if (exists $pmap{$name} and ref($pmap{$name}) ne 'HTML::Template::UNKNOWN') {
$var = $pmap{$name};
(ref($var) eq 'HTML::Template::VAR') or
die "HTML::Template->new() : Already used param name $name as a TMPL_LOOP, found in a TMPL_VAR at $fname : line $fcounter.";
@@ -2063,7 +2063,7 @@
# if we already have this loop, then simply link to the existing
# HTML::Template::LOOP, else create a new one.
my $loop;
- if (exists $pmap{$name}) {
+ if (exists $pmap{$name} and ref($pmap{$name}) ne 'HTML::Template::UNKNOWN') {
$loop = $pmap{$name};
(ref($loop) eq 'HTML::Template::LOOP') or
die "HTML::Template->new() : Already used param name $name as a TMPL_VAR, TMPL_IF or TMPL_UNLESS, found in a TMP_LOOP at $fname : line $fcounter!";
@@ -2116,8 +2116,8 @@
if (exists($pmap{$var})) {
$uc->[HTML::Template::COND::VARIABLE] = $pmap{$var};
} else {
- $pmap{$var} = HTML::Template::VAR->new();
- $top_pmap{$var} = HTML::Template::VAR->new()
+ $pmap{$var} = HTML::Template::UNKNOWN->new();
+ $top_pmap{$var} = HTML::Template::UNKNOWN->new()
if $options->{global_vars} and not exists $top_pmap{$var};
$uc->[HTML::Template::COND::VARIABLE] = $pmap{$var};
}
@@ -2357,8 +2357,8 @@
if (exists($pmap{$var})) {
$uc->[HTML::Template::COND::VARIABLE] = $pmap{$var};
} else {
- $pmap{$var} = HTML::Template::VAR->new();
- $top_pmap{$var} = HTML::Template::VAR->new()
+ $pmap{$var} = HTML::Template::UNKNOWN->new();
+ $top_pmap{$var} = HTML::Template::UNKNOWN->new()
if $options->{global_vars} and not exists $top_pmap{$var};
$uc->[HTML::Template::COND::VARIABLE] = $pmap{$var};
}
@@ -2515,6 +2515,8 @@
return undef unless (exists($param_map->{$param}) and
defined($param_map->{$param}));
+ return $param_map->{$param}->boolean() if
+ (ref($param_map->{$param}) eq 'HTML::Template::UNKNOWN');
return ${$param_map->{$param}} if
(ref($param_map->{$param}) eq 'HTML::Template::VAR');
return $param_map->{$param}[HTML::Template::LOOP::PARAM_SET];
@@ -2561,11 +2563,17 @@
# objects that are compatible underneath.
my $value_type = ref($value);
if (defined($value_type) and length($value_type) and ($value_type eq 'ARRAY' or ((ref($value) !~ /^(CODE)|(HASH)|(SCALAR)$/) and $value->isa('ARRAY')))) {
- (ref($param_map->{$param}) eq 'HTML::Template::LOOP') or
+ (ref($param_map->{$param}) eq 'HTML::Template::LOOP' or ref($param_map->{$param}) eq 'HTML::Template::UNKNOWN') or
croak("HTML::Template::param() : attempt to set parameter '$param' with an array ref - parameter is not a TMPL_LOOP!");
- $param_map->{$param}[HTML::Template::LOOP::PARAM_SET] = [@{$value}];
+ # If it's an unknown, set the boolean value
+ # Unknown works like VAR but handles LOOP
+ if (ref($param_map->{$param}) eq 'HTML::Template::UNKNOWN') {
+ ${$param_map->{$param}} = @$value;
+ } else {
+ $param_map->{$param}[HTML::Template::LOOP::PARAM_SET] = [@{$value}];
+ }
} else {
- (ref($param_map->{$param}) eq 'HTML::Template::VAR') or
+ (ref($param_map->{$param}) eq 'HTML::Template::VAR' or ref($param_map->{$param}) eq 'HTML::Template::UNKNOWN') or
croak("HTML::Template::param() : attempt to set parameter '$param' with a scalar - parameter is not a TMPL_VAR!");
${$param_map->{$param}} = $value;
}
@@ -2732,35 +2740,43 @@
$x = $line->[HTML::Template::COND::JUMP_ADDRESS]
} else {
if ($line->[HTML::Template::COND::JUMP_IF_TRUE]) {
- if ($line->[HTML::Template::COND::VARIABLE_TYPE] == HTML::Template::COND::VARIABLE_TYPE_VAR) {
- if (defined ${$line->[HTML::Template::COND::VARIABLE]}) {
- if (ref(${$line->[HTML::Template::COND::VARIABLE]}) eq 'CODE') {
- $x = $line->[HTML::Template::COND::JUMP_ADDRESS] if ${$line->[HTML::Template::COND::VARIABLE]}->($self);
- } else {
- $x = $line->[HTML::Template::COND::JUMP_ADDRESS] if ${$line->[HTML::Template::COND::VARIABLE]};
- }
- }
- } else {
- $x = $line->[HTML::Template::COND::JUMP_ADDRESS] if
- (defined $line->[HTML::Template::COND::VARIABLE][HTML::Template::LOOP::PARAM_SET] and
- scalar @{$line->[HTML::Template::COND::VARIABLE][HTML::Template::LOOP::PARAM_SET]});
- }
+ #if ($line->[HTML::Template::COND::VARIABLE_TYPE] == HTML::Template::COND::VARIABLE_TYPE_VAR) {
+ # if (ref $line->[HTML::Template::COND::VARIABLE] eq "SCALAR" && defined ${$line->[HTML::Template::COND::VARIABLE]}) {
+ # if (ref(${$line->[HTML::Template::COND::VARIABLE]}) eq 'CODE') {
+ # $x = $line->[HTML::Template::COND::JUMP_ADDRESS] if ${$line->[HTML::Template::COND::VARIABLE]}->($self);
+ # } else {
+ $x = $line->[HTML::Template::COND::JUMP_ADDRESS] if $line->[HTML::Template::COND::VARIABLE]->boolean;
+ # }
+ # } elsif (ref($line->[HTML::Template::COND::VARIABLE]) eq 'ARRAY') {
+ # $x = $line->[HTML::Template::COND::JUMP_ADDRESS] if
+ # (not defined $line->[HTML::Template::COND::VARIABLE][HTML::Template::LOOP::PARAM_SET] or
+ # not scalar @{$line->[HTML::Template::COND::VARIABLE][HTML::Template::LOOP::PARAM_SET]});
+ # }
+ #} else {
+ # $x = $line->[HTML::Template::COND::JUMP_ADDRESS] if
+ # (defined $line->[HTML::Template::COND::VARIABLE][HTML::Template::LOOP::PARAM_SET] and
+ # scalar @{$line->[HTML::Template::COND::VARIABLE][HTML::Template::LOOP::PARAM_SET]});
+ #}
} else {
- if ($line->[HTML::Template::COND::VARIABLE_TYPE] == HTML::Template::COND::VARIABLE_TYPE_VAR) {
- if (defined ${$line->[HTML::Template::COND::VARIABLE]}) {
- if (ref(${$line->[HTML::Template::COND::VARIABLE]}) eq 'CODE') {
- $x = $line->[HTML::Template::COND::JUMP_ADDRESS] unless ${$line->[HTML::Template::COND::VARIABLE]}->($self);
- } else {
- $x = $line->[HTML::Template::COND::JUMP_ADDRESS] unless ${$line->[HTML::Template::COND::VARIABLE]};
- }
- } else {
- $x = $line->[HTML::Template::COND::JUMP_ADDRESS];
- }
- } else {
- $x = $line->[HTML::Template::COND::JUMP_ADDRESS] if
- (not defined $line->[HTML::Template::COND::VARIABLE][HTML::Template::LOOP::PARAM_SET] or
- not scalar @{$line->[HTML::Template::COND::VARIABLE][HTML::Template::LOOP::PARAM_SET]});
- }
+ #if ($line->[HTML::Template::COND::VARIABLE_TYPE] == HTML::Template::COND::VARIABLE_TYPE_VAR) {
+ # if (ref $line->[HTML::Template::COND::VARIABLE] eq "SCALAR" && defined ${$line->[HTML::Template::COND::VARIABLE]}) {
+ # if (ref(${$line->[HTML::Template::COND::VARIABLE]}) eq 'CODE') {
+ # $x = $line->[HTML::Template::COND::JUMP_ADDRESS] unless ${$line->[HTML::Template::COND::VARIABLE]}->($self);
+ # } else {
+ $x = $line->[HTML::Template::COND::JUMP_ADDRESS] unless $line->[HTML::Template::COND::VARIABLE]->boolean;
+ # }
+ # } elsif (ref($line->[HTML::Template::COND::VARIABLE]) eq 'ARRAY') {
+ # $x = $line->[HTML::Template::COND::JUMP_ADDRESS] if
+ # (not defined $line->[HTML::Template::COND::VARIABLE][HTML::Template::LOOP::PARAM_SET] or
+ # not scalar @{$line->[HTML::Template::COND::VARIABLE][HTML::Template::LOOP::PARAM_SET]});
+ # } else {
+ # $x = $line->[HTML::Template::COND::JUMP_ADDRESS];
+ # }
+ #} else {
+ # $x = $line->[HTML::Template::COND::JUMP_ADDRESS] if
+ # (not defined $line->[HTML::Template::COND::VARIABLE][HTML::Template::LOOP::PARAM_SET] or
+ # not scalar @{$line->[HTML::Template::COND::VARIABLE][HTML::Template::LOOP::PARAM_SET]});
+ #}
}
}
} elsif ($type eq 'HTML::Template::NOOP') {
@@ -3029,6 +3045,17 @@
return bless(\$value, $_[0]);
}
+sub boolean {
+ my $value = shift;
+ # VAR could be a scalar or a coderef
+ if (ref $$value eq 'CODE') {
+ return 1 if $$value->($value);
+ }
+ else {
+ return 1 if $$value;
+ }
+}
+
package HTML::Template::DEFAULT;
sub new {
@@ -3042,6 +3069,11 @@
return bless([], $_[0]);
}
+sub boolean {
+ my $self = shift;
+ return 1 if $self->[PARAM_SET] && @{ $self->[PARAM_SET] };
+}
+
sub output {
my $self = shift;
my $index = shift;
@@ -3077,6 +3109,25 @@
return $result;
}
+package HTML::Template::UNKNOWN;
+
+sub new {
+ my $value;
+ return bless(\$value, $_[0]);
+}
+
+sub boolean {
+ my $value = shift;
+ # UNKNOWN boolean can be anything!
+ if (ref $value eq 'ARRAY') {
+ return 1 if @$value;
+ } elsif (ref $$value eq 'CODE') {
+ return 1 if $$value->($value);
+ } else {
+ return 1 if $$value;
+ }
+}
+
package HTML::Template::COND;
sub new {