Matt S Trout > HTML-Zoom-0.009004 > HTML::Zoom::FilterBuilder

Download:
HTML-Zoom-0.009004.tar.gz

Dependencies

Annotate this POD

CPAN RT

New  3
Open  1
View/Report Bugs
Source   Latest Release: HTML-Zoom-0.009008_01

NAME ^

HTML::Zoom::FilterBuilder - Add Filters to a Stream

SYNOPSIS ^

Create an HTML::Zoom instance:

  use HTML::Zoom;
  my $root = HTML::Zoom
      ->from_html(<<MAIN);
  <html>
    <head>
      <title>Default Title</title>
    </head>
    <body bad_attr='junk'>
      Default Content
    </body>
  </html>
  MAIN

Create a new attribute on the body tag:

  $root = $root
    ->select('body')
    ->set_attribute(class=>'main');

Add a extra value to an existing attribute:

  $root = $root
    ->select('body')
    ->add_to_attribute(class=>'one-column');

Set the content of the title tag:

  $root = $root
    ->select('title')
    ->replace_content('Hello World');

Set content from another HTML::Zoom instance:

  my $body = HTML::Zoom
      ->from_html(<<BODY);
  <div id="stuff">
      <p>Well Now</p>
      <p id="p2">Is the Time</p>
  </div>
  BODY

  $root = $root
    ->select('body')
    ->replace_content($body);

Set an attribute on multiple matches:

  $root = $root
    ->select('p')
    ->set_attribute(class=>'para');

Remove an attribute:

  $root = $root
    ->select('body')
    ->remove_attribute('bad_attr');

will produce:

  <html>
    <head>
      <title>Hello World</title>
    </head>
    <body class="main one-column"><div id="stuff">
      <p class="para">Well Now</p>
      <p id="p2" class="para">Is the Time</p>
  </div>
  </body>
  </html>

DESCRIPTION ^

Given a HTML::Zoom stream, provide methods to apply filters which alter the content of that stream.

METHODS ^

This class defines the following public API

set_attribute

Sets an attribute of a given name to a given value for all matching selections.

    $html_zoom
      ->select('p')
      ->set_attribute(class=>'paragraph')
      ->select('div')
      ->set_attribute(name=>'class', value=>'divider');

Overrides existing values, if such exist. When multiple "set_attribute" calls are made against the same or overlapping selection sets, the final call wins.

add_to_attribute

Adds a value to an existing attribute, or creates one if the attribute does not yet exist.

    $html_zoom
      ->select('p')
      ->set_attribute(class=>'paragraph')
      ->then
      ->add_to_attribute(name=>'class', value=>'divider');

Attributes with more than one value will have a dividing space.

remove_attribute

Removes an attribute and all its values.

    $html_zoom
      ->select('p')
      ->set_attribute(class=>'paragraph')
      ->then
      ->remove_attribute('class');

Removes attributes from the original stream or events already added.

collect

Collects and extracts results of "select" in HTML::Zoom. It takes the following optional common options as hash reference.

into [ARRAY REFERENCE]

Where to save collected events (selected elements).

    $z1->select('#main-content')
       ->collect({ into => \@body })
       ->run;
    $z2->select('#main-content')
       ->replace(\@body)
       ->memoize;
filter [CODE]

Run filter on collected elements (locally setting $_ to stream, and passing stream as an argument to given code reference). Filtered stream would be returned.

    $z->select('.outer')
      ->collect({
        filter => sub { $_->select('.inner')->replace_content('bar!') },
        passthrough => 1,
      })

It can be used to further filter selection. For example

    $z->select('tr')
      ->collect({
        filter => sub { $_->select('td') },
        passthrough => 1,
      })

is equivalent to (not implemented yet) descendant selector combination, i.e.

    $z->select('tr td')
passthrough [BOOLEAN]

Extract copy of elements; the stream is unchanged (it does not remove collected elements). For example without 'passthrough'

    HTML::Zoom->from_html('<foo><bar /></foo>')
      ->select('foo')
      ->collect({ content => 1 })
      ->to_html

returns '<foo></foo>', while with passthrough option

    HTML::Zoom->from_html('<foo><bar /></foo>')
      ->select('foo')
      ->collect({ content => 1, passthough => 1 })
      ->to_html

returns '<foo><bar /></foo>'.

content [BOOLEAN]

Collect content of the element, and not the element itself.

For example

    HTML::Zoom->from_html('<h1>Title</h1><p>foo</p>')
      ->select('h1')
      ->collect
      ->to_html

would return '<p>foo</p>', while

    HTML::Zoom->from_html('<h1>Title</h1><p>foo</p>')
      ->select('h1')
      ->collect({ content => 1 })
      ->to_html

would return '<h1></h1><p>foo</p>'.

See also "collect_content".

flush_before [BOOLEAN]

Generate flush event before collecting, to ensure that the HTML generated up to selected element being collected is flushed throught to the browser. Usually used in "repeat" or "repeat_content".

collect_content

Collects contents of "select" in HTML::Zoom result.

    HTML::Zoom->from_file($foo)
              ->select('#main-content')
              ->collect_content({ into => \@foo_body })
              ->run;
    $z->select('#foo')
      ->replace_content(\@foo_body)
      ->memoize;

Equivalent to running "collect" with content option set.

add_before

Given a "select" in HTML::Zoom result, add given content (which might be string, array or another HTML::Zoom object) before it.

    $html_zoom
        ->select('input[name="foo"]')
        ->add_before(\ '<span class="warning">required field</span>');

add_after

Like "add_before", only after "select" in HTML::Zoom result.

    $html_zoom
        ->select('p')
        ->add_after("\n\n");

You can add zoom events directly

    $html_zoom
        ->select('p')
        ->add_after([ { type => 'TEXT', raw => 'O HAI' } ]);

prepend_content

    TBD

append_content

    TBD

replace

Given a "select" in HTML::Zoom result, replace it with a string, array or another HTML::Zoom object. It takes the same optional common options as "collect" (via hash reference).

replace_content

Given a "select" in HTML::Zoom result, replace the content with a string, array or another HTML::Zoom object.

    $html_zoom
      ->select('title, #greeting')
      ->replace_content('Hello world!');

repeat

    $zoom->select('.item')->repeat(sub {
      if (my $row = $db_thing->next) {
        return sub { $_->select('.item-name')->replace_content($row->name) }
      } else {
        return
      }
    }, { flush_before => 1 });

Run $repeat_for, which should be iterator (code reference) returning subroutines, reference to array of subroutines, or other zoom-able object consisting of transformations. Those subroutines would be run with $_ local-ized to result of "select" in HTML::Zoom (of collected elements), and with said result passed as parameter to subroutine.

You might want to use iterator when you don't have all elements upfront

    $zoom = $zoom->select('.contents')->repeat(sub {
      while (my $line = $fh->getline) {
        return sub {
          $_->select('.lno')->replace_content($fh->input_line_number)
            ->select('.line')->replace_content($line)
        }
      }
      return
    });

You might want to use array reference if it doesn't matter that all iterations are pre-generated

    $zoom->select('table')->repeat([
      map {
        my $elem = $_;
        sub {
          $_->select('td')->replace_content($e);
        }
      } @list
    ]);

In addition to common options as in "collect", it also supports

repeat_between [SELECTOR]

Selects object to be repeated between items. In the case of array this object is put between elements, in case of iterator it is put between results of subsequent iterations, in the case of streamable it is put between events (->to_stream->next).

See documentation for "repeat_content"

repeat_content

Given a "select" in HTML::Zoom result, run provided iterator passing content of this result to this iterator. Accepts the same options as "repeat".

Equivalent to using contents option with "repeat".

    $html_zoom
       ->select('#list')
       ->repeat_content(
          [
             sub {
                $_->select('.name')->replace_content('Matt')
                  ->select('.age')->replace_content('26')
             },
             sub {
                $_->select('.name')->replace_content('Mark')
                  ->select('.age')->replace_content('0x29')
             },
             sub {
                $_->select('.name')->replace_content('Epitaph')
                  ->select('.age')->replace_content('<redacted>')
             },
          ],
          { repeat_between => '.between' }
       );

ALSO SEE ^

HTML::Zoom

AUTHORS ^

See HTML::Zoom for authors.

LICENSE ^

See HTML::Zoom for the license.

syntax highlighting: