X-Git-Url: http://git.ieval.ro/?a=blobdiff_plain;f=lib%2FHTML%2FElement%2FLibrary.pod;fp=lib%2FHTML%2FElement%2FLibrary.pod;h=0000000000000000000000000000000000000000;hb=0b6e6b6947c21eb8b3d3df71100bdbe2ba576866;hp=3196dce1ba4f42981ad337b0554e2b9f2dc0ea40;hpb=c06c181f2f67d85d185745967e604b25fecf17c3;p=html-element-library.git diff --git a/lib/HTML/Element/Library.pod b/lib/HTML/Element/Library.pod deleted file mode 100644 index 3196dce..0000000 --- a/lib/HTML/Element/Library.pod +++ /dev/null @@ -1,1193 +0,0 @@ -=encoding utf-8 - -=head1 NAME - -HTML::Element::Library - HTML::Element convenience functions - -=head1 SYNOPSIS - - use HTML::Element::Library; - use HTML::TreeBuilder; - -=head1 DESCRIPTION - -This method provides API calls for common actions on trees when using -L. - -=head1 METHODS - -The test suite contains examples of each of these methods in a file -C - -=head2 Positional Querying Methods - -=head3 $elem->siblings - -Return a list of all nodes under the same parent. - -=head3 $elem->sibdex - -Return the index of C<$elem> into the array of siblings of which it is -a part. L calls this method C but I don't -think that is a descriptive name. And such naming is deceptively close -to the C
function of C. HOWEVER, in the -interest of backwards compatibility, both methods are available. - -=head3 $elem->addr - -Same as sibdex - -=head3 $elem->position() - -Returns the coordinates of this element in the tree it inhabits. This -is accomplished by succesively calling addr() on ancestor elements -until either a) an element that does not support these methods is -found, or b) there are no more parents. The resulting list is the -n-dimensional coordinates of the element in the tree. - -=head2 Element Decoration Methods - -=head3 HTML::Element::Library::super_literal($text) - -In L, Sean Burke discusses super-literals. They are -text which does not get escaped. Great for includng Javascript in -HTML. Also great for including foreign language into a document. - -So, you basically toss C your text and back comes your -text wrapped in a C<~literal> element. - -One of these days, I'll around to writing a nice C section. - -=head2 Tree Rewriting Methods - -=head3 "de-prepping" HTML - -Oftentimes, the HTML to be worked with will have multiple sample rows: - -
    -
  1. bread -
  2. butter -
  3. beer -
  4. bacon -
- -But, before you begin to rewrite the HTML with your model data, you -typically only want 1 or 2 sample rows. - -Thus, you want to "crunch" the multiple sample rows to a specified -amount. Hence the C method: - - $tree->crunch(look_down => [ '_tag' => 'li' ], leave => 2) ; - -The C argument defaults to 1 if not given. The call above would -"crunch" the above 4 sample rows to: - -
    -
  1. bread -
  2. butter -
- -=head3 Simplifying calls to HTML::FillInForm - -Since HTML::FillInForm gets and returns strings, using HTML::Element -instances becomes tedious: - - 1. Seamstress has an HTML tree that it wants the form filled in on - 2. Seamstress converts this tree to a string - 3. FillInForm parses the string into an HTML tree and then fills in the form - 4. FillInForm converts the HTML tree to a string - 5. Seamstress re-parses the HTML for additional processing - -I've filed a bug about this: -L - -This function, fillinform, allows you to pass a tree to fillinform -(along with your data structure) and get back a tree: - - my $new_tree = $html_tree->fillinform($data_structure); - -=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: - - - - - - - -
1(877) 255-3239*********
- -In the table above, there are several attributes named C<< smap >>. If -we have a hashref whose keys are the same: - - my %data = (people_id => 888, phone => '444-4444', password => 'dont-you-dare-render'); - -Then a single API call allows us to populate the HTML while excluding -those ones we dont: - - $tree->hashmap(smap => \%data, ['password']); - -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. - -=head3 $elem->replace_content(@new_elem) - -Replaces all of C<$elem>'s content with C<@new_elem>. - -=head3 $elem->wrap_content($wrapper_element) - -Wraps the existing content in the provided element. If the provided -element happens to be a non-element, a push_content is performed -instead. - -=head3 $elem->set_child_content(@look_down, $content) - -This method looks down $tree using the criteria specified in -@look_down using the the HTML::Element look_down() method. - -After finding the node, it detaches the node's content and pushes -$content as the node's content. - -=head3 $tree->content_handler(%id_content) - -This is a convenience method. Because the look_down criteria will -often simply be: - - id => 'fixme' - -to find things like: - - replace_content - -You can call this method to shorten your typing a bit. You can simply -type - - $elem->content_handler( fixme => 'new text' ) - -Instead of typing: - - $elem->set_child_content(sid => 'fixme', 'new text') - -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', - balance => 666, - content => $main_content); - $tree->content_handler(%id_content); - -=head3 $tree->highlander($subtree_span_id, $conditionals, @conditionals_args) - -This allows for "if-then-else" style processing. Highlander was a -movie in which only one would survive. Well, in terms of a tree when -looking at a structure that you want to process in C -style, only one child will survive. For example, given this HTML -template: - - - - Hello, does your mother know you're - using her AOL account? - - - Sorry, you're not old enough to enter - (and too dumb to lie about your age) - - - Welcome - - - -We only want one child of the C tag with id C to -remain based on the age of the person visiting the page. - -So, let's setup a call that will prune the subtree as a function of -age: - - sub process_page { - my $age = shift; - my $tree = HTML::TreeBuilder->new_from_file('t/html/highlander.html'); - - $tree->highlander - (age_dialog => - [ - under10 => sub { $_[0] < 10}, - under18 => sub { $_[0] < 18}, - welcome => sub { 1 } - ], - $age - ); - -And there we have it. If the age is less than 10, then the node with -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) - -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 began to tackle tougher and tougher processing problems. It -became clear that a more powerful highlander was needed... one that -not only snipped the tree of the nodes that should not survive, but -one that allows for post-processing of the survivor node. And one that -was more flexible with how to find the nodes to snip. - -Thus (drum roll) C. - -So let's look at our HTML which requires post-selection processing: - - - - Hello, little AGE-year old, - does your mother know you're using her AOL account? - - - Sorry, you're only AGE - (and too dumb to lie about your age) - - - Welcome, isn't it good to be AGE years old? - - - -In this case, a branch survives, but it has dummy data in it. We must -take the surviving segment of HTML and rewrite the age C with -the age. Here is how we use C to do so: - - sub replace_age { - my $branch = shift; - my $age = shift; - $branch->look_down(id => 'age')->replace_content($age); - } - - my $if_then = $tree->look_down(id => 'age_dialog'); - - $if_then->highlander2( - cond => [ - under10 => [ - sub { $_[0] < 10} , - \&replace_age - ], - under18 => [ - sub { $_[0] < 18} , - \&replace_age - ], - welcome => [ - sub { 1 }, - \&replace_age - ] - ], - cond_arg => [ $age ] - ); - -We pass it the tree (C<$if_then>), an arrayref of conditions (C) -and an arrayref of arguments which are passed to the Cs and to -the replacement subs. - -The C, C and C are id attributes in the -tree of the siblings of which only one will survive. However, should -you need to do more complex look-downs to find the survivor, then -supply an array ref instead of a simple scalar: - - $if_then->highlander2( - cond => [ - [class => 'r12'] => [ - sub { $_[0] < 10} , - \&replace_age - ], - [class => 'z22'] => [ - sub { $_[0] < 18} , - \&replace_age - ], - [class => 'w88'] => [ - sub { 1 }, - \&replace_age - ] - ], - cond_arg => [ $age ] - ); - -=head3 $tree->overwrite_attr($mutation_attr => $mutating_closures) - -This method is designed for taking a tree and reworking a set of nodes -in a stereotyped fashion. For instance let's say you have 3 remote -image archives, but you don't want to put long URLs in your img src -tags for reasons of abstraction, re-use and brevity. So instead you do -this: - - - - - -and then when the tree of HTML is being processed, you make this call: - - my %closures = ( - lnc => sub { my ($tree, $mute_node, $attr_value)= @_; "http://lnc.usc.edu$attr_value" }, - playboy => sub { my ($tree, $mute_node, $attr_value)= @_; "http://playboy.com$attr_value" } - foobar => sub { my ($tree, $mute_node, $attr_value)= @_; "http://foobar.info$attr_value" } - ) - - $tree->overwrite_attr(fixup => \%closures) ; - -and the tags come out modified like so: - - - - - -=head3 $tree->mute_elem($mutation_attr => $mutating_closures, [ $post_hook ] ) - -This is a generalization of C. C -assumes the return value of the closure is supposed overwrite an -attribute value and does it for you. C is a more general -function which does nothing but hand the closure the element and let -it mutate it as it jolly well pleases :) - -In fact, here is the implementation of C to give you a -taste of how C is used: - - sub overwrite_action { - my ($mute_node, %X) = @_; - - $mute_node->attr($X{local_attr}{name} => $X{local_attr}{value}{new}); - } - - - sub HTML::Element::overwrite_attr { - my $tree = shift; - - $tree->mute_elem(@_, \&overwrite_action); - } - -=head2 Tree-Building Methods - -=head3 Unrolling an array via a single sample element (
    container) - -This is best described by example. Given this HTML: - - Here are the things I need from the store: -
      -
    • Sample item
    • -
    - -We can unroll it like so: - - my $li = $tree->look_down(class => 'store_items'); - - my @items = qw(bread butter vodka); - - $tree->iter($li => @items); - -To produce this: - - - - Here are the things I need from the store: -
      -
    • bread
    • -
    • butter
    • -
    • vodka
    • -
    - - - -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 (e.g. definition lists) -need a more general function to make them easy to do. Hence -C. This function will be explained by example of unrolling a -simple definition list. - -So here's our mock-up HTML from the designer: - -
    -
    Artist
    -
    A person who draws blood.
    - -
    Musician
    -
    A clone of Iggy Pop.
    - -
    Poet
    -
    A relative of Edgar Allan Poe.
    - -
    sample header
    -
    sample data
    -
    - - -And we want to unroll our data set: - - my @items = ( - ['the pros' => 'never have to worry about service again'], - ['the cons' => 'upfront extra charge on purchase'], - ['our choice' => 'go with the extended service plan'] - ); - - -Now, let's make this problem a bit harder to show off the power of -C. Let's assume that we want only the last
    and it's -accompanying
    (the one with "sample data") to be used as the -sample data for unrolling with our data set. Let's further assume that -we want them to remain in the final output. - -So now, the API to C will be discussed and we will explain -how our goal of getting our data into HTML fits into the API. - -=over 4 - -=item * wrapper_ld - -This is how to look down and find the container of all the elements we -will be unrolling. The
    tag is the container for the dt and dd -tags we will be unrolling. - -If you pass an anonymous subroutine, then it is presumed that -execution of this subroutine will return the HTML::Element -representing the container tag. If you pass an array ref, then this -will be dereferenced and passed to C. - -default value: C<< ['_tag' => 'dl'] >> - -Based on the mock HTML above, this default is fine for finding our -container tag. So let's move on. - -=item * wrapper_data - -This is an array reference of data that we will be putting into the -container. You must supply this. C<@items> above is our -C. - -=item * wrapper_proc - -After we find the container via C, we may want to -pre-process some aspect of this tree. In our case the first two sets -of dt and dd need to be removed, leaving the last dt and dd. So, we -supply a C which will do this. - -default: undef - -=item * item_ld - -This anonymous subroutine returns an array ref of Cs -that will be cloned and populated with item data (item data is a "row" -of C). - -default: returns an arrayref consisting of the dt and dd element -inside the container. - -=item * item_data - -This is a subroutine that takes C and retrieves one -"row" to be "pasted" into the array ref of Cs found via -C. I hope that makes sense. - -default: shifts C. - -=item * item_proc - -This is a subroutine that takes the C and the -Cs found via C and produces an arrayref of -Cs which will eventually be spliced into the container. - -Note that this subroutine MUST return the new items. This is done So -that more items than were passed in can be returned. This is useful -when, for example, you must return 2 dts for an input data item. And -when would you do this? When a single term has multiple spellings for -instance. - -default: expects C to be an arrayref of two elements and -C to be an arrayref of two Cs. It replaces -the content of the Cs with the C. - -=item * splice - -After building up an array of C<@item_elems>, the subroutine passed as -C will be given the parent container HTML::Element and the -C<@item_elems>. How the C<@item_elems> end up in the container is up -to this routine: it could put half of them in. It could unshift them -or whatever. - -default: C<< $container->splice_content(0, 2, @item_elems) >> In other -words, kill the 2 sample elements with the newly generated @item_elems - -=back - -So now that we have documented the API, let's see the call we need: - - $tree->iter2( - # default wrapper_ld ok. - wrapper_data => \@items, - wrapper_proc => sub { - my ($container) = @_; - - # only keep the last 2 dts and dds - my @content_list = $container->content_list; - $container->splice_content(0, @content_list - 2); - }, - - # default item_ld is fine. - # default item_data is fine. - # default item_proc is fine. - splice => sub { - my ($container, @item_elems) = @_; - $container->unshift_content(@item_elems); - }, - debug => 1, - ); - -=head3 Select Unrolling - -The C method has this API: - - $tree->unroll_select( - select_label => $id_label, - option_value => $closure, # how to get option value from data row - option_content => $closure, # how to get option content from data row - option_selected => $closure, # boolean to decide if SELECTED - data => $data # the data to be put into the SELECT - data_iter => $closure # the thing that will get a row of data - debug => $boolean, - append => $boolean, # remove the sample