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;

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 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.02