Added more tests and fixed formats to work correctly w/multiple templates.
[p5sagit/Excel-Template.git] / lib / Excel / Template / Container / Loop.pm
1 package Excel::Template::Container::Loop;
2
3 use strict;
4
5 BEGIN {
6     use vars qw(@ISA);
7     @ISA = qw(Excel::Template::Container);
8
9     use Excel::Template::Container;
10 }
11
12 sub new
13 {
14     my $class = shift;
15     my $self = $class->SUPER::new(@_);
16
17     if (exists $self->{MAXITERS} && $self->{MAXITERS} < 1)
18     {
19         die "<loop> MAXITERS must be greater than or equal to 1", $/;
20     }
21     else
22     {
23         $self->{MAXITERS} = 0;
24     }
25
26     return $self;
27 }
28
29 sub _make_iterator
30 {
31     my $self = shift;
32     my ($context) = @_;
33
34     return Excel::Template::Factory->_create('ITERATOR',
35         NAME     => $context->get($self, 'NAME'),
36         MAXITERS => $context->get($self, 'MAXITERS'),
37         CONTEXT  => $context,
38     );
39 }
40
41 sub render
42 {
43     my $self = shift;
44     my ($context) = @_;
45
46     unless ($self->{ITERATOR} && $self->{ITERATOR}->more_params)
47     {
48         $self->{ITERATOR} = $self->_make_iterator($context);
49     }
50     my $iterator = $self->{ITERATOR};
51
52     $iterator->enter_scope;
53
54     while ($iterator->can_continue)
55     {
56         $iterator->next;
57
58         $self->iterate_over_children($context);
59
60         # It doesn't seem that iterate_over_children() can ever fail, because
61         # I'm not sure that render() can return false. In PDF::Template, where
62         # this module got most of its code, render() can certainly return false,
63         # in the case of page-breaks. I left the code in because it didn't seem
64         # like it would hurt.
65         #unless ($self->iterate_over_children($context))
66         #{
67         #    $iterator->back_up;
68         #    last;
69         #}
70     }
71
72     $iterator->exit_scope;
73
74     return 0 if $iterator->more_params;
75
76     return 1;
77 }
78
79 # These methods are used in PDF::Template to calculate pagebreaks. I'm not sure
80 # if they will ever be needed in Excel::Template.
81 #sub total_of
82 #{
83 #    my $self = shift;
84 #    my ($context, $attr) = @_;
85 #
86 #    my $iterator = $self->_make_iterator($context);
87 #
88 #    my $total = 0;
89 #
90 #    $iterator->enter_scope;
91 #    while ($iterator->can_continue)
92 #    {
93 #        $iterator->next;
94 #        $total += $self->SUPER::total_of($context, $attr);
95 #    }
96 #    $iterator->exit_scope;
97 #
98 #    return $total;
99 #}
100 #
101 #sub max_of
102 #{
103 #    my $self = shift;
104 #    my ($context, $attr) = @_;
105 #
106 #    my $iterator = $self->_make_iterator($context);
107 #
108 #    my $max = $context->get($self, $attr);
109 #
110 #    $iterator->enter_scope;
111 #    while ($iterator->can_continue)
112 #    {
113 #        $iterator->next;
114 #        my $v = $self->SUPER::max_of($context, $attr);
115 #
116 #        $max = $v if $max < $v;
117 #    }
118 #    $iterator->exit_scope;
119 #
120 #    return $max;
121 #}
122
123 1;
124 __END__
125
126 =head1 NAME
127
128 Excel::Template::Container::Loop
129
130 =head1 PURPOSE
131
132 To provide looping
133
134 =head1 NODE NAME
135
136 LOOP
137
138 =head1 INHERITANCE
139
140 Excel::Template::Container
141
142 =head1 ATTRIBUTES
143
144 =over 4
145
146 =item * NAME
147
148 This is the name of the loop. It's used to identify within the parameter set
149 what variables to expose to the children nodes each iteration.
150
151 =back
152
153 =head1 CHILDREN
154
155 None
156
157 =head1 EFFECTS
158
159 None
160
161 =head1 DEPENDENCIES
162
163 None
164
165 =head1 USAGE
166
167   <loop name="LOOPY">
168     ... Children here ...
169   </loop>
170
171 In the above example, the children nodes would have access to the LOOPY array
172 of hashes as parameters. Each iteration through the array would expose a
173 different hash of parameters to the children.
174
175 These loops work just like HTML::Template's loops. (I promise I'll give more
176 info here!)
177
178 There is one difference - I prefer using Perl-like scoping, so accessing of
179 variables outside the LOOP scope from within is perfectly acceptable. You can
180 also hide outside variables with inner values, if you desire, just like Perl.
181
182 =head1 AUTHOR
183
184 Rob Kinyon (rob.kinyon@gmail.com)
185
186 =head1 SEE ALSO
187
188 =cut