HTML-Pen
view release on metacpan or search on metacpan
lib/HTML/Pen.pm view on Meta::CPAN
glob. Since the glob is C<*states>, each element is accessed as
a scalar with the same name, C<$states>.
As a slightly more complicated example, define @states this way:
@states = ( [ AL => "Alabama" ] .. [ WY => "Wyoming" ] )
<: &iterator( *states )>
<: &block( *SELECT, 'end' )><!--
<option value="&( $$states[0] )"><: &( $$states[1] )></option>
end -->
<: &iterate( *states, @SELECT )>
=over
Or if each element is a hash reference:
=back
<: &block( *SELECT, 'end' )><!--
<option value="&( $$states{abbreviation} )">
<: &( $$states{name} )></option>
end -->
<: &iterate( *states, @SELECT )>
Regardless of whether the data set elements are scalars or referenced data
structures, a one dimensional array is fairly easy to implement as an
iterator.
Iterators are designed to handle multi-dimensional arrays as well. To display
the 50 states in a table of 10 rows and 5 columns, first construct a tabular
data set, then define an HTML table consisting of a block of rows and a
block of columns:
<: &script('end')><%
@states = qw( Alabama .. Wyoming ) ;
@table = () ;
push @table, [ splice @states, 0, 5 ] while @states ;
iterator( *states, @table ) ; ## warning: obliterates @states
end %>
<: &block( *COLUMN, 'end' )><%
<td><: &( $states )></td>
end %>
<: &block( *ROW, 'end' )><%
<!-- &( $states ) - displays "ARRAY(0xa19b0a8)" -->
<tr><: &iterate( *states, @COLUMN )></tr>
end %>
<table>
<: &iterate( *states, @ROW )>
</table>
This example illustrates blocks that are nested to correspond with the data
set, in parent-child relationships. Each block recurses by calling
C<iterate()> with the common iterator and the name of the child
block.
L<HTML::Pen::Iterator> illustrates a relatively sophisticated example of a
4 dimensional data set calendar to be presented as a table. The iterator data
consists of an array of weeks; each week consists of an array of days; each
day consists of an array of times; each time consists of an array of events.
Each event is represented by an event object that is a blessed hash reference.
With a Pen iterator, the rendering code is a few simple lines of HTML. The
complexity is absorbed in the data structure, which should be defined as
follows:
\@week -> \@day -> \@time -> \%event
In this example, each day has an integer property (1-31) and each time
object has a property (hh::mm) which cannot be included within an array
definition. The solution is for each event object to inherit all the
properties of its forebears, so that it includes both day and time
values.
=head2 iteratorValue
The advantage of this approach is that every recursion can access the
same property values, regardless of its position in the stack, by
calling C<iteratorValue()>. This subroutine takes the iterator as its
first argument, and a property string as its second. C<iteratorValue()>
returns the corresponding value of the bottom-most hash object.
The disadvantage is that every object's properties are replicated across
all its descendents. The redundancy cost in the size of the data footprint
may be quite high. Alternatively, define each object as a hash reference,
and maintain its descendents in an array reference named I<elements>. Then
redefine the scalar before calling C<iterate()>:
<: &comment()><!-- for every block -->
<: &undef( $event = $event->{elements} )>
<: &iterate( *event, @CHILDBLOCK )>
Note: C<iteratorValue()> is not extended to cover these more complex
data structures.
When C<iterate()> is called, the scalar representation of the iterator
glob must be an array reference or the subroutine does nothing. This
mechanism ensures that no output is displayed for empty data sets.
=head1 EXPORT
None by default.
=head1 SEE ALSO
Mention other useful documentation such as the documentation of
related modules or operating system documentation (such as man pages
in UNIX), or any relevant external documentation such as RFCs or
standards.
If you have a mailing list set up for your module, mention it here.
If you have a web site set up for your module, mention it here.
=head1 AUTHOR
( run in 0.975 second using v1.01-cache-2.11-cpan-39bf76dae61 )