package Excel::Template::Container::Loop;
use strict;
BEGIN {
use vars qw(@ISA);
@ISA = qw(Excel::Template::Container);
use Excel::Template::Container;
}
sub new
{
my $class = shift;
my $self = $class->SUPER::new(@_);
if (exists $self->{MAXITERS} && $self->{MAXITERS} < 1)
{
die "<loop> MAXITERS must be greater than or equal to 1", $/;
}
else
{
$self->{MAXITERS} = 0;
}
return $self;
}
sub _make_iterator
{
my $self = shift;
my ($context) = @_;
return Excel::Template::Factory->_create('ITERATOR',
NAME => $context->get($self, 'NAME'),
MAXITERS => $context->get($self, 'MAXITERS'),
CONTEXT => $context,
);
}
sub render
{
my $self = shift;
my ($context) = @_;
unless ($self->{ITERATOR} && $self->{ITERATOR}->more_params)
{
$self->{ITERATOR} = $self->_make_iterator($context);
}
my $iterator = $self->{ITERATOR};
$iterator->enter_scope;
while ($iterator->can_continue)
{
$iterator->next;
$self->iterate_over_children($context);
# It doesn't seem that iterate_over_children() can ever fail, because
# I'm not sure that render() can return false. In PDF::Template, where
# this module got most of its code, render() can certainly return false,
# in the case of page-breaks. I left the code in because it didn't seem
# like it would hurt.
#unless ($self->iterate_over_children($context))
#{
# $iterator->back_up;
# last;
#}
}
$iterator->exit_scope;
return 0 if $iterator->more_params;
return 1;
}
# These methods are used in PDF::Template to calculate pagebreaks. I'm not sure
# if they will ever be needed in Excel::Template.
#sub total_of
#{
# my $self = shift;
# my ($context, $attr) = @_;
#
# my $iterator = $self->_make_iterator($context);
#
# my $total = 0;
#
# $iterator->enter_scope;
# while ($iterator->can_continue)
# {
# $iterator->next;
# $total += $self->SUPER::total_of($context, $attr);
# }
# $iterator->exit_scope;
#
# return $total;
#}
#
#sub max_of
#{
# my $self = shift;
# my ($context, $attr) = @_;
#
# my $iterator = $self->_make_iterator($context);
#
# my $max = $context->get($self, $attr);
#
# $iterator->enter_scope;
# while ($iterator->can_continue)
# {
# $iterator->next;
# my $v = $self->SUPER::max_of($context, $attr);
#
# $max = $v if $max < $v;
# }
# $iterator->exit_scope;
#
# return $max;
#}
1;
__END__
=head1 NAME
Excel::Template::Container::Loop
=head1 PURPOSE
To provide looping
=head1 NODE NAME
LOOP
=head1 INHERITANCE
Excel::Template::Container
=head1 ATTRIBUTES
=over 4
=item * NAME
This is the name of the loop. It's used to identify within the parameter set
what variables to expose to the children nodes each iteration.
=back
=head1 CHILDREN
None
=head1 EFFECTS
None
=head1 DEPENDENCIES
None
=head1 USAGE
<loop name="LOOPY">
... Children here ...
</loop>
In the above example, the children nodes would have access to the LOOPY array
of hashes as parameters. Each iteration through the array would expose a
different hash of parameters to the children.
These loops work just like HTML::Template's loops. (I promise I'll give more
info here!)
There is one difference - I prefer using Perl-like scoping, so accessing of
variables outside the LOOP scope from within is perfectly acceptable. You can
also hide outside variables with inner values, if you desire, just like Perl.
=head1 AUTHOR
Rob Kinyon (rob.kinyon@gmail.com)
=head1 SEE ALSO
=cut