The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Tags::HTML::Tree - Tags helper for Tree.

SYNOPSIS

 use Tags::HTML::Tree;

 my $obj = Tags::HTML::Tree->new(%params);
 $obj->cleanup;
 $obj->init($tree);
 $obj->prepare;
 $obj->process;
 $obj->process_css;

DESCRIPTION

Tags helper to print HTML page of tree structure defined by Tree instance.

The page contains clickable tree with usage of Javascript code.

METHODS

new

 my $obj = Tags::HTML::Tree->new(%params);

Constructor.

cleanup

 $obj->cleanup;

Cleanup module to init state.

Returns undef.

init

 $obj->init($tree);

Set Tree instance defined by $tree to object.

Returns undef.

prepare

 $obj->prepare;

Process initialization before page run.

Preparing is about adding javascript used in helper to "script_js" in Tags::HTML method.

Returns undef.

process

 $obj->process;

Process Tags structure for output with message.

Returns undef.

process_css

 $obj->process_css;

Process CSS::Struct structure for output.

Returns undef.

ERRORS

 new():
         From Class::Utils::set_params():
                 Unknown parameter '%s'.
         From Mo::utils::check_required():
                 Parameter '%s' is required.
         From Mo::utils::CSS::check_css_class():
                 Parameter 'css_class' has bad CSS class name.
                         Value: %s
                 Parameter 'css_class' has bad CSS class name (number on begin).
                         Value: %s
         From Mo::utils::CSS::check_css_unit():
                 Parameter 'indent' contain bad unit.
                         Unit: %s
                         Value: %s
                 Parameter 'indent' doesn't contain unit name.
                         Value: %s
                 Parameter 'indent' doesn't contain unit number.
                         Value: %s
         From Tags::HTML::new():
                 Parameter 'tags' must be a 'Tags::Output::*' class.
         Parameter 'css_class' is required.

 init():
         Data object must be a 'Tree' instance.

 process():
         From Tags::HTML::process():
                 Parameter 'tags' isn't defined.

EXAMPLE1

 use strict;
 use warnings;

 use CSS::Struct::Output::Raw;
 use Tags::HTML::Tree;
 use Tags::HTML::Page::Begin;
 use Tags::HTML::Page::End;
 use Tags::Output::Raw;
 use Tree;
 use Unicode::UTF8 qw(decode_utf8 encode_utf8);

 my $css = CSS::Struct::Output::Raw->new;
 my $tags = Tags::Output::Raw->new(
         'preserved' => ['style', 'script'],
         'xml' => 1,
 );

 my $tags_tree = Tags::HTML::Tree->new(
         'css' => $css,
         'tags' => $tags,
 );
 $tags_tree->prepare;

 my $begin = Tags::HTML::Page::Begin->new(
         'author' => decode_utf8('Michal Josef Špaček'),
         'css' => $css,
         'generator' => 'Tags::HTML::Tree',
         'lang' => {
                 'title' => 'Tree',
         },
         'script_js' => $tags_tree->script_js,
         'tags' => $tags,
 );
 my $end = Tags::HTML::Page::End->new(
         'tags' => $tags,
 );

 # Example tree object.
 my $tree = Tree->new('Root');
 $tree->meta({'uid' => 0});
 my $count = 0;
 my %node;
 foreach my $node_string (qw/H I J K L M N O P Q/) {
          $node{$node_string} = Tree->new($node_string);
          $node{$node_string}->meta({'uid' => ++$count});
 }
 $tree->add_child($node{'H'});
 $node{'H'}->add_child($node{'I'});
 $node{'I'}->add_child($node{'J'});
 $node{'H'}->add_child($node{'K'});
 $node{'H'}->add_child($node{'L'});
 $tree->add_child($node{'M'});
 $tree->add_child($node{'N'});
 $node{'N'}->add_child($node{'O'});
 $node{'O'}->add_child($node{'P'});
 $node{'P'}->add_child($node{'Q'});

 # Init.
 $tags_tree->init($tree);

 # Process CSS.
 $tags_tree->process_css;

 # Process HTML.
 $begin->process;
 $tags_tree->process;
 $end->process;

 # Print out.
 print encode_utf8($tags->flush);

 # Output:
 # <!DOCTYPE html>
 # <html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><meta name="author" content="Michal Josef Špaček" /><meta name="generator" content="Tags::HTML::Tree" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><script type="text/javascript">
 # window.addEventListener('load', (event) => {
 #     let toggler = document.getElementsByClassName("caret");
 #     for (let i = 0; i < toggler.length; i++) {
 #         toggler[i].addEventListener("click", function() {
 #             this.parentElement.querySelector(".nested").classList.toggle("active");
 #             this.classList.toggle("caret-down");
 #         });
 #     }
 # });
 # </script><title>Tree</title><style type="text/css">
 # ul, .tree{list-style-type:none;padding-left:2em;}.caret{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.caret::before{content:"⯈";color:black;display:inline-block;margin-right:6px;}.caret-down::before{transform:rotate(90deg);}.nested{display:none;}.active{display:block;}
 # </style></head><body><ul class="tree"><li><span class="caret">Root</span><ul class="nested"><li><span class="caret">H</span><ul class="nested"><li><span class="caret">I</span><ul class="nested"><li>J</li></ul></li><li>K</li><li>L</li></ul></li><li>M</li><li><span class="caret">N</span><ul class="nested"><li><span class="caret">O</span><ul class="nested"><li><span class="caret">P</span><ul class="nested"><li>Q</li></ul></li></ul></li></ul></li></ul></li></ul></body></html>

EXAMPLE2

 use strict;
 use warnings;

 use CSS::Struct::Output::Indent;
 use Tags::HTML::Tree;
 use Tags::HTML::Page::Begin;
 use Tags::HTML::Page::End;
 use Tags::Output::Indent;
 use Tree;
 use Unicode::UTF8 qw(decode_utf8 encode_utf8);

 my $css = CSS::Struct::Output::Indent->new;
 my $tags = Tags::Output::Indent->new(
         'preserved' => ['style', 'script'],
         'xml' => 1,
 );

 my $tags_tree = Tags::HTML::Tree->new(
         'css' => $css,
         'tags' => $tags,
 );
 $tags_tree->prepare;

 my $begin = Tags::HTML::Page::Begin->new(
         'author' => decode_utf8('Michal Josef Špaček'),
         'css' => $css,
         'generator' => 'Tags::HTML::Tree',
         'lang' => {
                 'title' => 'Tree',
         },
         'script_js' => $tags_tree->script_js,
         'tags' => $tags,
 );
 my $end = Tags::HTML::Page::End->new(
         'tags' => $tags,
 );

 # Example tree object.
 my $tree = Tree->new('Root');
 $tree->meta({'uid' => 0});
 my $count = 0;
 my %node;
 foreach my $node_string (qw/H I J K L M N O P Q/) {
          $node{$node_string} = Tree->new($node_string);
          $node{$node_string}->meta({'uid' => ++$count});
 }
 $tree->add_child($node{'H'});
 $node{'H'}->add_child($node{'I'});
 $node{'I'}->add_child($node{'J'});
 $node{'H'}->add_child($node{'K'});
 $node{'H'}->add_child($node{'L'});
 $tree->add_child($node{'M'});
 $tree->add_child($node{'N'});
 $node{'N'}->add_child($node{'O'});
 $node{'O'}->add_child($node{'P'});
 $node{'P'}->add_child($node{'Q'});

 # Init.
 $tags_tree->init($tree);

 # Process CSS.
 $tags_tree->process_css;

 # Process HTML.
 $begin->process;
 $tags_tree->process;
 $end->process;

 # Print out.
 print encode_utf8($tags->flush);

 # Output:
 # <!DOCTYPE html>
 # <html lang="en">
 #   <head>
 #     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 #     <meta name="author" content="Michal Josef Špaček" />
 #     <meta name="generator" content="Tags::HTML::Tree" />
 #     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 #     <script type="text/javascript">
 # window.addEventListener('load', (event) => {
 #     let toggler = document.getElementsByClassName("caret");
 #     for (let i = 0; i < toggler.length; i++) {
 #         toggler[i].addEventListener("click", function() {
 #             this.parentElement.querySelector(".nested").classList.toggle("active");
 #             this.classList.toggle("caret-down");
 #         });
 #     }
 # });
 # </script>    <title>
 #       Tree
 #     </title>
 #     <style type="text/css">
 # ul, .tree {
 #      list-style-type: none;
 #      padding-left: 2em;
 # }
 # .caret {
 #      cursor: pointer;
 #      -webkit-user-select: none;
 #      -moz-user-select: none;
 #      -ms-user-select: none;
 #      user-select: none;
 # }
 # .caret::before {
 #      content: "⯈";
 #      color: black;
 #      display: inline-block;
 #      margin-right: 6px;
 # }
 # .caret-down::before {
 #      transform: rotate(90deg);
 # }
 # .nested {
 #      display: none;
 # }
 # .active {
 #      display: block;
 # }
 # </style>
 #   </head>
 #   <body>
 #     <ul class="tree">
 #       <li>
 #         <span class="caret">
 #           Root
 #         </span>
 #         <ul class="nested">
 #           <li>
 #             <span class="caret">
 #               H
 #             </span>
 #             <ul class="nested">
 #               <li>
 #                 <span class="caret">
 #                   I
 #                 </span>
 #                 <ul class="nested">
 #                   <li>
 #                     J
 #                   </li>
 #                 </ul>
 #               </li>
 #               <li>
 #                 K
 #               </li>
 #               <li>
 #                 L
 #               </li>
 #             </ul>
 #           </li>
 #           <li>
 #             M
 #           </li>
 #           <li>
 #             <span class="caret">
 #               N
 #             </span>
 #             <ul class="nested">
 #               <li>
 #                 <span class="caret">
 #                   O
 #                 </span>
 #                 <ul class="nested">
 #                   <li>
 #                     <span class="caret">
 #                       P
 #                     </span>
 #                     <ul class="nested">
 #                       <li>
 #                         Q
 #                       </li>
 #                     </ul>
 #                   </li>
 #                 </ul>
 #               </li>
 #             </ul>
 #           </li>
 #         </ul>
 #       </li>
 #     </ul>
 #   </body>
 # </html>

EXAMPLE3

 use strict;
 use warnings;
 
 use CSS::Struct::Output::Indent;
 use Plack::App::Tags::HTML;
 use Plack::Runner;
 use Tags::HTML::Tree;
 use Tags::Output::Indent;
 use Tree;

 # Example tree object.
 my $data_tree = Tree->new('Root');
 my %node;
 foreach my $node_string (qw/H I J K L M N O P Q/) {
          $node{$node_string} = Tree->new($node_string);
 }
 $data_tree->add_child($node{'H'});
 $node{'H'}->add_child($node{'I'});
 $node{'I'}->add_child($node{'J'});
 $node{'H'}->add_child($node{'K'});
 $node{'H'}->add_child($node{'L'});
 $data_tree->add_child($node{'M'});
 $data_tree->add_child($node{'N'});
 $node{'N'}->add_child($node{'O'});
 $node{'O'}->add_child($node{'P'});
 $node{'P'}->add_child($node{'Q'});
 
 my $css = CSS::Struct::Output::Indent->new;
 my $tags = Tags::Output::Indent->new(
         'xml' => 1,
         'preserved' => ['script', 'style'],
 );
 my $app = Plack::App::Tags::HTML->new(
         'component' => 'Tags::HTML::Tree',
         'data_init' => [$data_tree],
         'css' => $css,
         'tags' => $tags,
 )->to_app;
 Plack::Runner->new->run($app);

 # Output screenshot is in images/ directory.
Web app example

DEPENDENCIES

Class::Utils, English, Error::Pure, Mo::utils, Mo::utils::CSS, Scalar::Util, Unicode::UTF8, Tags::HTML.

REPOSITORY

https://github.com/michal-josef-spacek/Tags-HTML-Tree

AUTHOR

Michal Josef Špaček mailto:skim@cpan.org

http://skim.cz

LICENSE AND COPYRIGHT

© 2024 Michal Josef Špaček

BSD 2-Clause License

VERSION

0.05