X-Git-Url: http://git.ieval.ro/?a=blobdiff_plain;f=lib%2FHTML%2FElement%2FLibrary.pm;h=cf49bfcb793ca29399d94dca4759ca81575d9454;hb=96cec2210bdf9bda69126e0bd444b982b3953ce1;hp=936840ba8a71ab11f4516cdcc1987f82ad96cd97;hpb=3caedb5b3a025561935df4403083c02425cb3845;p=html-element-library.git diff --git a/lib/HTML/Element/Library.pm b/lib/HTML/Element/Library.pm index 936840b..cf49bfc 100644 --- a/lib/HTML/Element/Library.pm +++ b/lib/HTML/Element/Library.pm @@ -37,6 +37,21 @@ sub HTML::Element::siblings { $p->content_list; } +sub HTML::Element::defmap { + my($tree,$attr,$hashref,$debug)=@_; + + while (my ($k, $v) = (each %$hashref)) { + warn "defmap looks for ($attr => $k)" if $debug; + my $found = $tree->look_down($attr => $k); + if ($found) { + warn "($attr => $k) was found.. replacing with '$v'" if $debug; + $found->replace_content( $v ); + } + } + +} + + sub HTML::Element::hash_map { my $container = shift; @@ -49,7 +64,7 @@ sub HTML::Element::hash_map { warn 'The container tag is ', $container->tag if $p{debug} ; warn 'hash' . Dumper($p{hash}) if $p{debug} ; - warn 'at_under' . Dumper(\@_); + warn 'at_under' . Dumper(\@_) if $p{debug} ; my @same_as = $container->look_down( $p{to_attr} => qr/.+/ ) ; @@ -68,14 +83,26 @@ sub HTML::Element::hash_map { } +sub HTML::Element::hashmap { + my ($container, $attr_name, $hashref, $excluding, $debug) = @_; + + $excluding ||= [] ; + + $container->hash_map(hash => $hashref, + to_attr => $attr_name, + excluding => $excluding, + debug => $debug); + +} + sub HTML::Element::passover { - my ($tree, $child_id) = @_; + my ($tree, @to_preserve) = @_; - warn "ARGS: my ($tree, $child_id)" if $DEBUG; + warn "ARGS: my ($tree, @to_preserve)" if $DEBUG; warn $tree->as_HTML(undef, ' ') if $DEBUG; - my $exodus = $tree->look_down(id => $child_id); + my $exodus = $tree->look_down(id => $to_preserve[0]); warn "E: $exodus" if $DEBUG; @@ -83,7 +110,7 @@ sub HTML::Element::passover { for my $s (@s) { next unless ref $s; - if ($s->attr('id') eq $child_id) { + if (first { $s->attr('id') eq $_ } @to_preserve) { ; } else { $s->delete; @@ -175,7 +202,6 @@ sub HTML::Element::iter { my @item = map { my $new_item = clone $p; $new_item->replace_content($_); - # $new_item->attr('id', $id_incr->( $p->attr('id') )); $new_item; } @data; @@ -656,6 +682,8 @@ sub HTML::Element::unroll_select { my $select = {}; + warn "Select Hash: " . Dumper(\%select) if $select{debug}; + my $select_node = $s->look_down(id => $select{select_label}); warn "Select Node: " . $select_node if $select{debug}; @@ -769,7 +797,77 @@ One of these days, I'll around to writing a nice C section. =head2 Tree Rewriting Methods -=head3 $elem->hash_map(hash => \%h, to_attr => $attr, excluding => \@excluded) +=head3 Mapping a hashref to HTML elements + +It is very common to get a hashref of data from some external source - flat file, database, XML, etc. +Therefore, it is important to have a convenient way of mapping this data to HTML. + +As it turns out, there are 3 ways to do this in HTML::Element::Library. +The most strict and structured way to do this is with +C. Two other methods, C and C require less manual mapping and may prove +even more easy to use in certain cases. + +As is usual with Perl, a practical example is always best. So let's take some sample HTML: + +

user data

+ ? + ? + ? + +Now, let's say our data structure is this: + + $ref = { email => 'jim@beam.com', gender => 'lots' } ; + +And let's start with the most strict way to get what you want: + + $tree->content_handler(email => $ref->{email} , gender => $ref->{gender}) ; + + +In this case, you manually state the mapping between id tags and hashref keys and +then C retrieves the hashref data and pops it in the specified place. + +Now let's look at the two (actually 2 and a half) other hash-mapping methods. + + $tree->hashmap(id => $ref); + +Now, what this function does is super-destructive. It finds every element in the tree +with an attribute named id (since 'id' is a parameter, it could find every element with +some other attribute also) and replaces the content of those elements with the hashref +value. + +So, in the case above, the + + ? + +would come out as + + + +(it would be blank) - because there is nothing in the hash with that value, so it substituted + + $ref->{name} + +which was blank and emptied the contents. + +Now, let's assume we want to protect name from being auto-assigned. Here is what you do: + + $tree->hashmap(id => $ref, ['name']); + +That last array ref is an exclusion list. + +But wouldnt it be nice if you could do a hashmap, but only assigned things which are defined +in the hashref? C<< defmap() >> to the rescue: + + $tree->defmap(id => $ref); + +does just that, so + + ? + +would be left alone. + + +=head4 $elem->hashmap($attr_name, \%hashref, \@excluded, $debug) This method is designed to take a hashref and populate a series of elements. For example: @@ -788,11 +886,26 @@ In the table above, there are several attributes named C<< smap >>. If we have a Then a single API call allows us to populate the HTML while excluding those ones we dont: - $tree->hash_map(hash => \%data, to_attr => 'sid', excluding => ['password']); + $tree->hashmap(smap => \%data, ['password']); + -Of course, the other way to prevent rendering some of the hash mapping is to not give that element the attr +Note: the other way to prevent rendering some of the hash mapping is to not give that element the attr you plan to use for hash mapping. +Also note: the function C<< hashmap >> has a simple easy-to-type API. Interally, it calls C<< hash_map >> +(which has a more verbose keyword calling API). Thus, the above call to C results in this call: + + $tree->hash_map(hash => \%data, to_attr => 'sid', excluding => ['password']); + +=head4 $elem->defmap($attr_name, \%hashref, $debug) + +C was described above. + + +=head4 $elem->content_handler(%hashref) + +C is described below. + =head3 $elem->replace_content(@new_elem) @@ -827,7 +940,7 @@ Instead of typing: $elem->set_child_content(sid => 'fixme', 'new text') -PLEASE NOTE: you can pass a hash whose keys are Cs and whose values are the content you want there and it will perform the replacement on each hash member: +ALSO NOTE: you can pass a hash whose keys are Cs and whose values are the content you want there and it will perform the replacement on each hash member: my %id_content = (name => "Terrence Brannon", email => 'tbrannon@in.com', @@ -881,14 +994,16 @@ id C remains. For age less than 18, the node with id C remains. Otherwise our "else" condition fires and the child with id C remains. -=head3 $tree->passover($id_of_element) +=head3 $tree->passover(@id_of_element) -In some cases, you know exactly which element should survive. In this case, -you can simply call C to remove it's siblings. For the HTML +In some cases, you know exactly which element(s) should survive. In this case, +you can simply call C to remove it's (their) siblings. For the HTML above, you could delete C and C by simply calling: $tree->passover('under18'); +Because passover takes an array, you can specify several children to preserve. + =head3 $tree->highlander2($tree, $conditionals, @conditionals_args) Right around the same time that C came into being, Seamstress @@ -1066,6 +1181,17 @@ To produce this: +Now, you might be wondering why the API call is: + + $tree->iter($li => @items) + +instead of: + + $li->iter(@items) + +and there is no good answer. The latter would be more concise and it is what I +should have done. + =head3 Unrolling an array via n sample elements (
container) C was fine for awhile, but some things @@ -1725,12 +1851,14 @@ down instead: L -=head1 AUTHOR +=head1 AUTHOR / SOURCE Terrence Brannon, Etbone@cpan.orgE Many thanks to BARBIE for his RT bug report. +The source is at L + =head1 COPYRIGHT AND LICENSE Copyright (C) 2004 by Terrence Brannon