package A1z::HTML5::Template; use strict; use warnings; use vars qw($NAME); # ABSTRACT: Fast and Easy Web Apps sub NAME { my $self = shift; $NAME = "Fast and Easy Web Apps"; return $NAME; } our $VERSION = '0.22'; use parent qw(Exporter); require Exporter; our @ISA = ("Exporter"); our @EXPORT_OK = qw(header start_html head_title head_meta head_js_css end_head begin_body body_js_css body_topnavbar body_accordion end_body end_html head body ); sub new { my $class = shift; my $self = bless { @_ }, $class; return $self; } sub math1 { my $self = shift; my ($num1, $num2) = @_; if ($num1 eq '') { $num1 = '2'; } if ($num2 eq '') { $num2 = '4'; } my $out; my $m = $num1 * $num2; my $a = $num1 + $num2; my $s = $num1 - $num2; my $s1 = $num2 - $num1; my $d = $num1 / $num2; my $d1 = $num2 / $num1; $out .= qq{
Multiplication
$num1 x $num2 \= $m
Addition
$num1 \+ $num2 \= $a
Subtraction
$num1 \- $num2 \= $s
$num2 \- $num1 \= $s1
Division
$num1 \/ $num2 \= $d
$num2 \/ $num1 \= $d1
}; return qq{\n$out\n}; } # begin timestable sub timestable { my $self = shift; my ($num1) = @_; if ( $num1 eq '' ) { $num1 = '2'; } my $out; $out .= qq{}; for ('1'..'20') { $out .= qq{} if ($_); } $out .= qq{
$num1 x $_ = } . $num1 * $_ . qq{
}; return $out; } # end timestable # begin header sub header { my $self = shift; my @keys; if (@_) { @keys = @_; } my $args = scalar(@keys); my ($key, $key1) = @_; my %out; if ($ARGV and $ARGV > 0 and scalar(@keys) > 0) { if ($key eq 'utf8') { $out{"$key"} = qq{Content-Type: text/html;charset=utf-8\n\n}; } elsif (!defined $key or $key eq '') { $out{"$key"} = qq{Content-Type: text/html;charset=utf-8\n\n}; } else { $out{"$key"} = qq{Content-Type: text/html;charset=utf-8\n\n}; } } else { return qq{Content-Type: text/html;charset=utf-8\n\n}; } } # end header # begin start html 01 sub start_html { my $self = shift; my @keys; if (@_) { @keys = @_; } my $args = scalar @keys; my ($key, $key1) = @_; my %out; if ($args and $args >= 0) { # have your own custom header, backwards compatibility my $out; $out .= qq{@_ }; return $out; } else { my $out; $out .= qq{\n\n}; $out .= qq{\n}; return $out; } } # end start_html sub body_js_css { my $self = shift; my $key = "@_"; my @keys; if (@_) { @keys = @_; } my $args = scalar (@keys); my $out; $out .= qq^ ^; if ( $args ) { if ( $args >= 0) { my $return; for (@keys ) { chomp; if ($_ =~ /.js$/) { $return .= qq{\n}; } elsif ($_ =~ /.css$/) { $return .= qq{\n}; } else { # do nothing } } return qq{$return}; # } else { return qq{$out}; } } else { return qq{$out}; # } } # start end_html sub end_html { my $self = shift; my @keys; if (@_) { @keys = @_; } my ($key, $key1) = @_; my $out; $out .= qq{\n\n}; if ($ARGV and $ARGV > 0 or scalar(@keys) > 0) { return qq{@_}; } else { return $out; } } # end end_html # start head title 02 sub head_title { my $self = shift; my $key = "@_"; my @keys; if (@_) { @keys = @_; } my $out; $out .= qq{}; if ($ARGV and $ARGV > 0 or scalar(@keys) > 0) { if ($key) { return qq{@_\n}; } else { return qq{Template\n}; } } else { return qq{Package Html5\n}; # this works but does not ask the user } } # end head title # begin head meta 03 sub head_meta { my $self = shift; my $key = "@_"; my @keys; if (@_) { @keys = @_; } my $args = scalar @keys; my $out; $out .= qq{ }; if ($args) { if ($args >= 0) { my $return; for (@keys ) { chomp; my ( $meta_name, $meta_cont) = split(/---/, $_, 2); $return .= qq{\n}; } return qq{$return}; } else { $out .= qq{}; # add default meta if user has not called one of his own return qq{$out}; } } else { return qq{$out}; # this works but does not ask the user } } # end head meta 03 # begin body top nav bar sub body_topnavbar { my $self = shift; my %in; %in = ( file => "https://www.a1z.us/js/utils/top-nav-bar.js", name => "Menu", @_, ); my $out; $out .= qq{ }; return qq{$out\n}; # this works but does not ask the user } # end body top nav bar sub head_js_css { my $self = shift; my $key = "@_"; my @keys; if (@_) { @keys = @_; } my $args = scalar (@keys); my $out; $out .= qq{ }; if ($args) { if ($args >= 0) { my $return; for (@keys) { chomp; if ($_ =~ /.js$/) { $return .= qq{ \n \n}; } elsif ($_ =~ /.css$/) { $return .= qq{ \n \n}; } else { # do nothing return qq{@keys\n}; } } return qq{$return\n}; } else { return qq{$out\n}; } } else { return qq{$out\n}; # this works but does not ask the user } } # end head js css # begin end head sub end_head { my $self = shift; my $key = "@_"; my @keys; if (@_) { @keys = @_; } my $out; $out .= qq{}; if ($ARGV and $ARGV > 0 or scalar(@keys) > 0) { if (@_) { return qq{@_\n}; } else { return qq{$out\n}; } } else { return qq{$out\n}; # this works but does not ask the user } } # end end head # begin begin body sub begin_body { my $self = shift; my $key = "@_"; my @keys; if (@_) { @keys = @_; } my $out; $out .= qq{}; if ($ARGV and $ARGV > 0 or scalar(@keys) > 0) { if (@_) { return qq{@_\n}; } else { return qq{$out\n}; } } else { return qq{$out\n}; # this works but does not ask the user } } # end begin body # begin accordion or rather file content. Need to change name of this method sub body_accordion { my $self = shift; my $key = "@_"; my @keys; if (@_) { @keys = @_; } my $out; $out .= qq{

Who is it for

For those who know/uderstand Perl/HTML/jQuery

What about a bigger number?

Sure. Use the custom form to get the times table for a number greater than 30?

How about any number/range?

Yes, of course! Once again, use the custom form bearing the heading "Or enter your own"

Can I customize it for own use?

In that case, you need to purchase the software and/or order a customization
}; if ($ARGV and $ARGV > 0 or scalar(@keys) > 0) { if (@_) { return qq{\n@_\n}; } else { return qq{\n$out\n}; } } else { return qq{\n$out\n}; # } } # end accordion sub body_article { my $self = shift; my $out; my %in; %in = ( content => "", type => "article", header => "Content Header", @_, ); if ( !defined $in{content} or $in{content} eq '' ) { return qq{ No Content }; } else { return qq{

$in{header}

$in{content}
}; } } # begin begin body sub end_body { my $self = shift; my $key = "@_"; my @keys; if (@_) { @keys = @_; } my $out; $out .= qq{\n\n}; if ($ARGV and $ARGV > 0 or scalar(@keys) > 0) { if (@_) { return qq{@_\n}; } else { return qq{$out\n}; } } else { return qq{$out\n}; # this works but does not ask the user } } # end end body # begin content folder to select form sub body_form { my $self = shift; my $out; my @keys; if (@_) { @keys = @_; } my ($vars, $vals) = (''); for (@keys) { $vars = $_ if ($_ =~ /^vars/); # $vals not used $vals = $_ if ($_ =~ /^vals/); } my @form_vars = split(/\;/, $vars); my @form_vals = split(/\;/, $vals); # get params for hidden fields if given my @hidden; if ($form_vars[4] and $form_vars[4] =~ /\,/) { @hidden = split(/\,/, $form_vars[4]); } else { @hidden = ("No", "Vals"); } # if SELECT .... my $select; if ($form_vars[3] and $form_vars[3] =~ /^select/) { # get the params for the form # select, my ($sel_key, $sel_name, $sel_default, $folder_or_file, $selectLabelText) = split(/\,/, $form_vars[3], 5); $select .= qq{
\t\n\t
\n}; } else { # no select $select .= qq{}; } $out .= qq{
}; # add hidden fields/values # from $form_vars[4] for (@hidden) { my ($name, $value) = split(/\-\-\-/, $_, 2) if $_; $out .= qq{\n\t} if $_; } # add select $out .= qq{$select}; $out .= qq{\n\t\n
\n}; return qq{
$out
}; } # end body_form sub defaults_begin { my $self = shift; my $out; $out .= sprintf header(), start_html(), head_title("$_[0]"), head_meta(), head_meta("$_[1]"), head_js_css(), head_js_css("$_[2]"), end_head(), begin_body(), body_topnavbar() ; return $out; } sub defaults_end { my $self = shift; my $out; $out .= sprintf body_js_css(), body_js_css("$_[0]"), end_body(), end_html() ; return $out; } # HTML my %HTML; %HTML = ( -defaultjquery => qq{\n }, -default_LastItem => qq{}, ); sub html_bootstrap_css { return qq{ }; } sub html_jqueryui_css { # jquery ui theme jquery-ui.css #1.12.0 return qq{}; } sub html_shim_respond { return qq{ }; } sub html_navbar { #my $self = shift; #serverName, pageName, menuName, dropDownLinks my %in; %in = ( -nbMenuName => "", -nbPageName => "", -nbServer => "", -nbLinks => "blog-support-help-contact-sale", @_, ); return qq{ }; } sub html_bootstrap_js { # jquery:3.3.0 ui:1/12/1 return qq{ }; } sub html_js_css { } sub html_jquery { } sub html_setTitle { my $out; my %in; %in = ( ta => qq{}, tb => qq{}, tc => qq{}, @_, ); $out .= qq{ }; return $out; } sub html_humanejs_css { return qq{ }; } sub html_bootstrap_bluimp { return qq{ }; } # end sub html_bootstrap_bluimp sub head { my $self = shift; my $out; my %in = ( -type => "Content-Type: text/html;charset=utf-8\n\n", -bootstrap => html_bootstrap_css, -jqueryui => html_jqueryui_css, -htmlshim => html_shim_respond, -humanejs => html_humanejs_css, -title => "A1Z .us", -cssLinks => "https://code.jquery.com/ui/1.11.4/themes/ui-lightness/jquery-ui.css,https://blueimp.github.io/Gallery/css/blueimp-gallery.min.css,https://www.a1z.us/A1z/HTML5/Template.css", -cssCode => "", -mobilemeta => qq{ }, -charsetmeta => qq{}, -usermeta => "", -titleRotatingText => qq{text1,text2,text3}, @_, ); # rotating title function and text my $setTitle; if ( $in{-titleRotatingText} and $in{-titleRotatingText} =~ /\,/ ) { my @a; @a = split(/\,/, $in{-titleRotatingText}, 3); $setTitle = html_setTitle(ta => "$a[0]", tb => "$a[1]", tc => "$a[2]"); } else { $setTitle = html_setTitle(ta => "Text01", tb => "text02", tc => "text03"); } # css multiple links/files my $css; my @css; if ($in{-cssLinks} ) { if ( $in{-cssLinks} =~ /\,/ ) { @css = split(/\,/, $in{-cssLinks}); for (@css) { if ($_ =~ /\.css$/) { $css .= qq{\n} ; } else { $css = ''; } } } } else { $css = qq{}; } return qq{$in{-type} $in{-title} $in{-charsetmeta} $in{-mobilemeta} $in{-usermeta} $in{-bootstrap} $in{-jqueryui} $in{-htmlshim} $in{-humanejs} $css $setTitle }; # thats orderly } # end head sub body { my $self = shift; my $out; my %in; %in = ( -h1 => qq{A1Z .us}, -onload => qq{setTitle();}, -nbhead => qq{}, -nbpage => qq{}, -nbmenu => qq{More}, -defaultjquery => qq{$HTML{-defaultjquery}}, -humanejs => qq{ $in{-bootstrapbluimp} $in{-h1} $in{-content} $in{-footer} $in{-defaultjquery} $in{-humanejs} }; } # end body sub open_file { my $self =shift; my %in; %in = ( file => "", output_header => "", output_format => "", @_, ); my $file = "$in{file}" || "$_[0]"; my $output_format = "$in{output_format}" || "$_[1]"; my $output_header = "$in{output_header}" || "$_[2]"; my $out; my $div4tabs; my @data; if (-e -f "$file") { open(FILE, "$file") or die "$!"; $out .= qq{\n\n
\n}; # Step 1 # set the header as per format if ($output_format eq 'table') { $out .= qq{ }; } elsif ($output_format eq 'accordion') { $out .= qq{

$output_header

\n
\n}; } elsif ($output_format eq 'menu') { $out .= qq{
\n}; } elsif ($output_format eq 'accordion') { # Keep only those items that have -- in the beginning if ( $h1 =~ /^\s+/ or $div =~ /^\s+/ ) { next unless ($h1 =~ /^\s+--/ or $div =~ /^\s+--/); $div =~ s!^\s+--!!g; $h1 =~ s!^\s+--!!g; } else { next unless ($h1 =~ /^--/ or $div =~ /^--/); $div =~ s!^--!!g; $h1 =~ s!^--!!g; } $out .= qq{\t

$h1

\n\t
$div
\n} if $line; } elsif ($output_format eq 'menu') { # the first item will be used as link title and name # the second item will be used as the actual link # no extensions added automatically by the script # an id for each link/li is also provided in case, may be it is not needed # Remove items with a # in the beginning; Sat Feb 21 18:48:19 2015 next if ($h1 =~ /^#http/ or $div =~ /^#http/); # Keep only those items that have a 'http' in the beginning if ( $h1 =~ /^\s+/ or $div =~ /^\s+/ ) { next unless ($h1 =~ /^\s+http/ or $div =~ /^\s+http/); #$div =~ s!^\s+http!!g; #$h1 =~ s!^\s+http!!g; } else { next unless ($h1 =~ /^http/ or $div =~ /^http/); #$div =~ s!^http!!g; #$h1 =~ s!^http!!g; } $out .= qq{\t
  • $h1
  • \n}; } elsif ($output_format eq 'tabs') { # Keep only those items that have a == in the beginning if ( $h1 =~ /^\s+/ or $div =~ /^\s+/ ) { next unless ($h1 =~ /^\s+==/ or $div =~ /^\s+==/); $div =~ s!^\s+==!!g; $h1 =~ s!^\s+==!!g; } else { next unless ($h1 =~ /^==/ or $div =~ /^==/); $div =~ s!^==!!g; $h1 =~ s!^==!!g; } # Mismatching fragment identifier. See 1797. # $div not available here as is not open here. $out .= qq{\t

    $div

    \n}; } elsif ($output_format eq 'dialog') { # includes everything; So, no filtering. # But, just remove symbols in both $h1 and $div $div =~ s!^(==|\#|--)!!g; $h1 =~ s!^(==|\#|--)!!g; $out .= qq{\t\t

    $h1

    \n\t\t
    $div
    \n}; } else { $out .= qq{$h1 $div}; # or $line } } # add an extra item at the end of file output # Step 3 # set the output ending as per format if ($output_format eq 'table') { $out .= qq{\n
    \n
    $output_header
    $h1$div
    \n\n}; } elsif ($output_format eq 'accordion') { $out .= qq{\n
    \n\n}; } elsif ($output_format eq 'menu') { $out .= qq{}; } elsif ($output_format eq 'tabs') { $out .= qq{\n}; } elsif ($output_format eq 'dialog') { $out .= qq{\n}; } else { $out .= qq{\n\n}; } # end file output wrapper $out .= qq{\n}; return $out; } else { my $out; $out .= qq{\n\n
    \n}; while ( my $line = ) { chomp $line; my ($h1, $div) = (''); ($h1, $div) = split(/\t+/, $line, 2) if $line; $out .= qq{\t

    $h1

    \n\t
    $div
    \n} if $line; } $out .= qq{\t

    Powered by

    \n\t
    Perl/CPAN
    \n}; $out .= qq{
    \n\n}; return $out; } close FILE; } # end open_file sub edit_file { my $self = shift; my $out; my %in; %in = ( file => "", error => "", action => "TemplateAdmin.cgi", serial => '', output_type => '', @_, ); if (-e -f "$in{file}") { open(FILE, "$in{file}") or $in{error} = "unable to open $in{file}"; my @file = ; close FILE; $out .= qq{
    }; for (@file) { chomp; next if $_ =~ /^$/; $in{serial}++ if $_; my ( $type, $content ) = split(/\|/, $_, 2); $type =~ s!\s+$!!g; my $identifiers = substr "$content", 0, 4; # has to be 4 to cover 'http.' Also, assuming no spaces in the beginning (removed by write_file) # determine output type if ( $identifiers =~ /^\#/ ) { $in{output_type} = 'Table'; } elsif ( $identifiers =~ /^\-/ ) { $in{output_type} = 'Accordion'; } elsif ( $identifiers =~ /^\=/ ) { $in{output_type} = 'Tabs'; } elsif ( $identifiers =~ /^http/ ) { $in{output_type} = 'Menu'; } else { $in{output_type} = 'None'; } # remove all nonmeta characters for web page display $identifiers =~ s!(\s+|[a-zA-z0-9])!!g; # removes http also. $content =~ s!\!>\;!g; $content =~ s! RN !\r\n!g; # $out .= qq`
    $in{serial} $type $identifiers Type:$in{output_type}

    `; } $out .= qq{
    }; return $out; } } sub write_file { my $self = shift; my $out; my %in; %in = ( file => "", error => "", powershell => "C:/WINDOWS/system32/WindowsPowerShell/v1.0/powershell.exe ", @_, ); my %vars; use CGI; my $q = new CGI; %vars = $q->Vars(); my $action = $q->param('action'); if ( $action eq 'write') { if (-e -f "$in{file}") { # First, get file content to backup to another file open(F, "$in{file}") or $in{error} .= "#1565 Unable to open file for reading. '$!'
    "; my @f = ; # save original file content to backup file open(BAK, ">$in{file},bak.txt") or $in{error} .= "#1570 Unable to create backup file '$in{file},bak.txt' '$!'
    "; for (@f) { print BAK qq{$_}; } close BAK; close F; # recreate file, thereby deleting original content open(DEL, ">$in{file}") or $in{error} .= "#1579 Unable to recreate file '$in{file}' '$!'
    "; print DEL "File ReCreated"; close DEL; my %out; for (keys %vars) { chomp $_; chomp $vars{$_}; next if $_ eq 'action'; my ( $name, $value ) = split(/\,/, $vars{"$_"}, 2); $name =~ s!(\r\n+|\n+)! RN !g; $value =~ s!(\r\n+|\n+)! RN !g; $value =~ s!^\s+!!g; $out{"$name"} = "$value"; } # Insert/Add new content open(FILE, ">$in{file}") or $in{error} .= "#1582 Error writing to file '$in{file}' '$!'
    "; for (keys %out) { print FILE qq{$_\|$out{$_}\n}; } close FILE; if (-e -f "$in{file},bak.txt" and -e -f "$in{file}") { return "
    Saved
    $in{error}
    "; } else { return "
    #1605 Error saving file '$in{file}'
    $in{error}
    "; } } else { return "File not found"; } } elsif ( $action eq 'newItem' ) { return "$action"; } else { return '* ' x 10; } } # end write_file sub display_gallery_thumbnails { my $self = shift; my $out; my %in; %in = ( error => "", images_dir => "/images/a1z-html5-template/", thumbs_dir => "/images/a1z-html5-template/thumbs", images_url => "/images/a1z-html5-template", thumbs_url => "/thumbs/a1z-html5-template/thumbs", width => "100", height => "100", @_, ); if (-e -d "$in{images_dir}" and "$in{thumbs_dir}" ) { opendir(TH, "$in{thumbs_dir}") or $in{error} .= qq{

    $!

    }; my @thumbs = readdir(TH); close TH; foreach ( @thumbs ) { if ( $_ and $_ =~ /(.jpg|.gif|.jpeg|.png|.tiff)$/ ) { $out .= qq{\n Image $_ \n}; } } } else { $in{error} .= qq{

    Image directory does not exist or is inaccessible. Make sure you provided the correct path.

    }; $out = $in{error}; } return $out; } # end display gallery thumbnails 1; __END__ =pod =encoding UTF-8 =head1 NAME A1z::HTML5::Template - Fast and easy Web Apps =head1 VERSION version 0.22 =head1 SYNOPSIS use A1z::HTML5::Template; my $h = A1z::HTML5::Template->new(); This directory should be writable by the web server, required to create/hold page content files. This may also contain your custom JavaScript/CSS libraries. Works for both Windows and Linux use lib '/home/user/path/to/app'; or use lib 'C:/Inetpub/wwwroot/path/to/app'; # for features like 'say' use 5.10.0; my $h = A1z::HTML5::Template->new(); Fast, Easy, and Simple: Just Two Lines! say $h->head( -title => "My Brand Name" ); say $h->body( -content => qq{ Coming Soon }); For More Control/Customization: Not for the lazy! say $h->header('utf8'); say $h->start_html(); say $h->head_title("My New App"); say $h->head_meta(); Load basic/required JavaScript/CSS libraries say $h->head_js_css(); Add your own custom JavaScript/CSS files say $h->head_js_css('/url/to/app/Template.css'); say $h->end_head(); say $h->begin_body(); say qq{

    My New App/Website

    }; say qq{
    }; # output file content as menu say $h->body_accordion( $h->open_file("/home/user/path/to/app/open_file_example.txt", 'menu', 'Menu') ); # as a HTML5 table say $h->body_accordion( $h->open_file("$sys{cgibase}/open_file_example.txt", 'table', 'Table Header') ); # Simple mathematics say $h->body_article( header => "Simple Mathematics", content => $h->math1("2", "4") ); # Times Table say $h->body_article( header => "Times Table", content => $h->timestable("2") ); say qq{
    }; Required/Default JavaScript libraries. say $h->body_js_css(); Add your own JavaScript libraries: say $h->body_js_css("complete-url_or_path-to-js-css-libraries") say $h->end_body(); say $h->end_html(); =head1 NAME Fast and Easy Web Apps "A1z::HTML5::Template" provides customizable HTML5 tags for creating "Fast and Easy Web Apps." =head2 VERSION 0.22 =head1 Installation cpan install A1z::HTML5::Template or cpanm A1z::HTML5::Template =head1 METHODS header start_html head_title head_meta head_js_css end_head begin_body body_js_css body_topnavbar body_accordion end_body end_html =head2 new use A1z::HTML5::Template; my $h = A1z::HTML5::Template->new(); =head2 math1 $h->math1(num1, num2); $h->body_article( header => "Math", content => $h->math1(num1, num2) ); =head2 timestable $h->timestable("Number"); =head2 header Provides HTML Content-Header $h->header(""); =head2 start_html Provides doctype html Default includes utf-8 $h->start_html(); Or, add your own charset to your app: $h->start_html('DifferentCharset'); =head2 body_js_css Add/include javascript and css files just above section Typically, CSS files should/are not be used here. Default behavior: $h->body_js_css(); Includes jquery 1.12.4, jquery ui 1.11.4, bootstrap 3.3.0, javascript for #dialog function, #menu, #accordion, #tabs Add your own .js file: use $h->body_js_css("/path/to/js/file.js"); You can use both to include default .js files and your own custom .js file. =head2 end_html Provides =head2 head_title Provides $h->head_title("App/Page Title"); =head2 head_meta Provides . Includes the following by default: IE=Edge HandheldFriendly viewport $h->head_meta(); Just like body_js_css, you can use both to add default values and your own meta =head2 body_topnavbar Provides top nav bar optionally. By default it is loaded from www.a1z.us which probably be removed in a future version. So, get a copy from bootstrap 3 and store it on your server. =head2 head_js_css provides the ability to add/include .js/.css files in the tag. $h->head_js_css(); Default includes the following: bootstrap 3.3.0 .css from maxcdn navbar-fixed-top.css from www.a1z.us jquery 1.12.1 smoothness theme from code.jquery.com Shim and Respond.js from maxcdn $h->head_js_css("/path/to/.js") $h->head_js_css("/path/to/.css") =head2 end_head Provides $h->end_head(); =head2 begin_body provides tag. $h->begin_body(); =head2 body_accordion The accordion in 'body_accordion' is misleading. It is not limited to just an accordion but all kinds of content. Cbody_accordion( $h->open_file("/path/to/app/open_file_example.txt", 'Type', 'Heading') );> Cbody_accordion( $h->open_file("/path/to/app/open_file_example.txt", "table", "Name and Price"); Cbody_accordion( $h->open_file("/path/to/app/open_file_example.txt", "tabs", "Space Saving Tabs"); =head2 body_article provides the ability to add content into
    tags. $h->body_article( header => "", content => ""); =head2 end_body provides tag. $h->end_body(); =head2 body_form Form, lists items from a directory in a neat drop-down list with each item's file size in KB! Should be in the exact format like below: $h->body_form("vars;METHOD;Action.cgi;select,NameForSelectTag,DefaultOptionSelected,AbsPathToDir,TextForSelectLabel;hidN1---hidV1,hidN2---hidV2,hidN3---hidV3"); =head2 defaults_begin Internal Use Only Provides defaults for very lightweight template for those in a hurry; Can be used for apps/sites that are under construction! $h->defaults_begin(); =head2 defaults_end Internal Use Only. provides defaults for lightweight or under construction app/website. $h->defaults_end(); =head1 HTML Hash For Internal/Future Use Hash contains -defaultjquery which is used in body. -defaultjquery includes jquery 1.12.4 from code.jquery jquery ui 1.11.4 bootstrap 3.3.0 from maxcdn blueimp-gallery ie-10 workaround from a1z.us functions tabs, dialog, menu, accordion =head2 html_bootstrap_css For Internal/Future Use Used in $h->head and $h->body internally. All methods starting with 'html_' are used internally! Include bootstrap.min.css, #3.3.0 from maxcdn and navbar-fixed-top.css from a1z.us $h->html_bootstrap_css() =head2 html_jqueryui_css For Internal/Future Use Includes jquery ui theme jquery-ui.css #1.12.0 =head2 html_shim_respond For Internal/Future Use html5shiv.min.js #3.7.2 respond.min.js #1.4.2 =head2 html_navbar For Internal/Future Use Customizations for top-nav-bar.js from a1z.us $h->html_navbar( -nbMenuName => "menuName", -nbPageName => "pageName", -nbServer => "serverName", -nbLinks => "dropDownLinks: URLs separated by a dash, mostly relative URLs. E.g., blog-support-help-contact-sale" ); =head2 html_bootstrap_js For Internal/Future Use bootstrap.min.js, #3.3.0, from maxcdn =head2 html_setTitle For Internal/Future Use setTitle javascript function Used in body Includes the C