Skip Menu |

This queue is for tickets about the HTML-Template CPAN distribution.

Report information
The Basics
Id: 32683
Status: rejected
Priority: 0/
Queue: HTML-Template

People
Owner: Nobody in particular
Requestors: ckuskie [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in:
  • 2.7
  • 2.8
  • 2.9
Fixed in: (no value)



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 {
On Sat Jan 26 13:59:24 2008, COLINK wrote: Show quoted text
> You can't use a tmpl_loop variable as a boolean, unless the variable is > used as a loop inside the conditional.
It doesn't have to be inside the conditional, just in the template somewhere. Show quoted text
> So this is legal: > > <tmpl_if myLoop><tmpl_loop myLoop><tmpl_var
Show quoted text
loopIndex></tmpl_loop></tmpl_if>
Show quoted text
> > But this isn't: > > <tmpl_if myLoop>You have a loop</tmpl_if>
There's a pretty easy workaround for this. Just put the loop in the template with nothing inside it (as long as die_on_bad_params is false). <tmpl_if myLoop>You have a loop</tmpl_if><tmpl_loop myLoop></tmpl_loop>