Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Lady_Aleena's scratchpad

by Lady_Aleena (Chaplain)
on Sep 07, 2007 at 20:54 UTC ( #637756=scratchpad: print w/ replies, xml ) Need Help??

package Base::HTML::Element; use strict; use warnings FATAL => qw( all ); use Exporter qw(import); our @EXPORT_OK = qw(html head script style body div main section artic +le aside nav header footer heading pre paragraph anchor img span rparagraph blockquote item +list definition_list caption row table form fieldset selection input inputs textarea noscrip +t); use Base::Line qw(rline line); my @ics = qw(id class style lang); my @java = qw(onclick ondblclick onkeypress onkeydown onkeyup onmouseo +ver onmousedown onmouseup onmousemove onmouseout); sub get_attributes { my ($options, $valid) = @_; my @attributes; for (@{$valid}) { my $value = $options->{$_}; push @attributes, qq($_="$value") if defined($options->{$_}); } return join(' ',('',@attributes)); } sub open_tag { my ($tag,$opt,$attributes) = @_; my $tag_attributes = get_attributes($opt,$attributes); return $tag.$tag_attributes; } sub break { my ($value, $break) = @_; my $line = $value; $line =~ s/$break/<br>/g; return $line; } # plain_element is used in the following functions: # term, caption, label, option, legend, heading sub plain_element { my ($tag,$attributes,$tab,$value,$opt) = @_; my $open = open_tag($tag,$opt,$attributes); return rline($tab,"<$open>$value</$tag>"); } # code_element is used in the following functions: # body, main, section, article, nav, aside, div, noscript, form, pre, +header, footer sub code_element { my ($tag,$attributes,$tab,$value,$opt) = @_; my $open = open_tag($tag,$opt,$attributes); line($tab,"<$open>"); header( $tab + 1, @{$opt->{'header'}}) if ($opt->{'header'} && $ta +g !~ /(?:header|footer|pre)/); heading($tab + 1, @{$opt->{'heading'}}) if ($opt->{'heading'} && $ta +g !~ /pre/); ref($value) eq 'CODE' ? &$value : paragraph($tab + 2, $value, { 'sep +arator' => $opt->{'separator'} }); footer( $tab + 1, @{$opt->{'footer'}}) if ($opt->{'footer'} && $ta +g !~ /(?:header|footer|pre)/); line($tab,"</$tag>"); } # Start elements sub anchor { my ($value,$opt) = @_; my $tag = 'a'; my $open = open_tag($tag,$opt,['href','target','title',@ics,@java,'t +abindex']); return "<$open>$value</$tag>"; } sub img { my ($opt) = @_; my $tag = 'img'; my $open = open_tag($tag,$opt,['src','alt',@ics,@java,'tabindex']); return "<$open>"; } sub span { my ($value, $opt) = @_; my $tag = 'span'; my $open = open_tag($tag,$opt,[@ics,@java]); return "<$open>$value</$tag>"; } # Start elements for head. sub title { my ($tab,$value,$opt) = @_; my $tag = 'title'; my $open = $tag; line($tab,"<$open>$value</$tag>"); } sub meta { my ($tab,$metas) = @_; my $tag = 'meta'; for (@$metas) { my $open = open_tag($tag,$_,['name','http-equiv','lang','content'] +); line($tab,"<$open>"); } } sub base { my ($tab,$links) = @_; my $tag = 'base'; my $open = open_tag($tag,$_,['href','target']); line($tab,"<$open>"); } sub links { my ($tab,$links) = @_; my $tag = 'link'; for (@$links) { my $open = open_tag($tag,$_,['rel','rev','type','href']); line($tab,"<$open>"); } } sub script { my ($tab,$opt) = @_; my $tag = 'script'; my $open = open_tag($tag,$opt,['type','src']); line($tab,"<$open></$tag>"); } sub scripts { my ($tab,$scripts) = @_; for (@$scripts) { script($tab,$_); } } sub noscript { code_element('noscript',[@ics,@java],@_); } sub style { my ($tab,$value,$opt) = @_; my $tag = 'style'; my $open = open_tag($tag,$opt,['type']); my $sep = $opt->{separator} ? $opt->{separator} : "\n"; line($tab,"<$open>"); for (grep(length,split(/$sep/,$value))) { $_ =~ s/^\s+//; line($tab + 1, $_); } line($tab,"</$tag>"); } sub head { my ($tab,$opt) = @_; my $tag = 'head'; my $open = open_tag($tag,$opt,['profile']); line($tab,"<$open>"); $tab++; title($tab, $opt->{title}); base($tab, $opt->{base}) if $opt->{base}; meta($tab, $opt->{meta}) if $opt->{meta}; links($tab, $opt->{links}) if $opt->{links}; scripts($tab, $opt->{scripts}) if $opt->{scripts}; style($tab, @{$opt->{style}}) if $opt->{style}; noscript($tab, $opt->{noscript}) if $opt->{noscript}; $tab--; line($tab,"</$tag>"); } # End elements for head. # Begin elements for body. # HTML5 elements which need to be added: figure, figcaption, main. # Begin paragraphs sub rparagraph { my ($tab,$value,$opt) = @_; my $tag = 'p'; my $open = open_tag($tag,$opt,[@ics,@java]); my $sep = $opt->{'separator'} ? $opt->{'separator'} : "\n"; my $line; for (grep(length, split(/$sep/, $value))) { my $paragraph = $opt->{'break'} ? break($_, $opt->{'break'}) : $_; $line .= rline($tab, "<$open>"); $line .= rline($tab + 1, $paragraph); $line .= rline($tab, "</$tag>"); } return $line; } sub paragraph { print rparagraph(@_); } # End paragraphs # Begin blockquotes sub blockquote { my ($tab,$value,$opt) = @_; my $tag = 'blockquote'; my $open = open_tag($tag, $opt, ['value', @ics, @java]); line($tab, "<$open>"); paragraph($tab + 1, $value); line($tab,"</$tag>"); } # End blockquotes # Begin elements for ordered and unordered lists. sub item { my ($tab,$value,$opt) = @_; my $tag = 'li'; my $open = open_tag($tag, $opt, ['value', @ics, @java]); line($tab, "<$open>"); line($tab + 1, $value); if ($opt->{inlist}) { list($tab + 1, @{$opt->{inlist}}); } line($tab,"</$tag>"); } sub list { my ($tab,$type,$list,$opt) = @_; my $tag = $type.'l'; my $open = open_tag($tag,$opt,[@ics,@java]); line($tab,"<$open>"); for my $item (@$list) { if (ref($item) eq 'ARRAY') { item($tab + 1,$item->[0],$item->[1]); } else { item($tab + 1,$item); } } line($tab,"</$tag>"); } # End elements for ordered and unordered lists. # Begin elements for definition lists. sub term { print plain_element('dt',[@ics,@java],@_); } sub definition { my ($tab,$value,$opt) = @_; my $tag = 'dd'; my $open = open_tag($tag,$opt,[@ics,@java]); line($tab,"<$open>"); line($tab + 1,$value); line($tab,"</$tag>"); } sub definition_list { my ($tab,$definition_list,$opt) = @_; my $tag = 'dl'; my $open = open_tag($tag,$opt,[@ics,@java]); line($tab,"<$open>"); for my $item (@$definition_list) { term($tab + 1,$item->{term}); if (!$opt->{headings}) { definition($tab + 2,$item->{definition}); } else { for my $heading (@{$opt->{headings}}) { my $upheading = ucfirst $heading; definition($tab + 2,qq(<strong>$upheading:</strong> ).$item->{ +$heading}); } } } line($tab,"</$tag>"); } # End elements for definition lists. # Begin elements for tables. sub caption { print plain_element('caption',['align',@ics,@java],@_); } sub cell { my ($tab,$type,$value,$opt) = @_; $type = $opt->{type_override} ? $opt->{type_override} : $type; my $tag = 't'.$type; my $open = open_tag($tag,$opt,['colspan','rowspan',@ics,@java]); line($tab,"<$open>"); if ($value eq 'list') { list($tab + 1,@{$opt->{list}}); } else { line($tab + 1,$value); } line($tab,"</$tag>"); } sub row { my ($tab,$type,$cells,$opt) = @_; my $tag = 'tr'; my $open = open_tag($tag,$opt,[@ics,@java]); my %types = ( header => 'h', data => 'd', whead => 'd' ); line($tab,"<$open>"); if ($type eq 'whead') { my $cell = shift @{$cells}; if (ref($cell) eq 'ARRAY') { cell($tab + 1,'h',ucfirst $cell->[0], { class => 'row_header', $ +cell->[1] }); } else { cell($tab + 1,'h',ucfirst $cell, { class => 'row_header' }); } } my $cell_type = $types{$type}; for my $cell (@{$cells}) { if (ref($cell) eq 'ARRAY') { cell($tab + 1,$cell_type,$cell->[0],$cell->[1]); } else { cell($tab + 1,$cell_type,$cell); } } line($tab,"</$tag>"); } sub col { my ($tab,$opt) = @_; my $tag = 'col'; my $open = open_tag($tag,$opt,['span',@ics,@java]); line($tab,"<$open>"); } sub cols { my ($tab,$cols) = @_; col($tab,$_) for @{$cols}; } sub table { my ($tab,$opt) = @_; my $tag = 'table'; my $open = open_tag($tag,$opt,[@ics,@java]); line($tab,"<$open>"); if ($opt->{caption}) { if (ref($opt->{caption}) eq 'ARRAY') { caption($tab + 1, $opt->{caption}->[0],$opt->{caption}->[1]); } else { caption($tab + 1, $opt->{caption}); } } if ($opt->{cols}) { col($tab + 1, $_) for @{$opt->{cols}}; } for my $rowgroup (@{$opt->{rows}}) { my $type = $rowgroup->[0]; my @rows = $rowgroup->[1]; my $attributes = $rowgroup->[2]; if ($type eq 'header') { row($tab + 1, $type , @rows, $attributes); } else { for my $row (@rows) { row($tab + 1, $type , $_, $attributes) for @$row; } } } line($tab,"</$tag>"); } # End elements for tables. # Begin elements for forms. sub label { print plain_element('label',['for',@ics,@java],@_); } sub option { print plain_element('option',['value',@ics,@java],@_); } sub selection { my ($tab,$options,$opt) = @_; my $tag = 'select'; my $open = open_tag($tag,$opt,['name','multiple',@ics,@java,'tabinde +x']); label($tab,@{$opt->{label}}) if ($opt->{label} && $opt->{place_label +} eq 'before'); line($tab,"<$open>"); for (@$options) { option($tab + 1,@$_); } line($tab,"</$tag>"); label($tab,@{$opt->{label}}) if ($opt->{label} && $opt->{place_label +} eq 'after'); } sub textarea { my ($tab,$value,$opt) = @_; my $tag = 'textarea'; my $open = open_tag($tag,$opt,['name','rows','cols',@ics,@java,'tabi +ndex']); label($tab,@{$opt->{label}}) if ($opt->{label} && $opt->{place_label +} eq 'before'); line($tab,"<$open>$value</$tag>"); label($tab,@{$opt->{label}}) if ($opt->{label} && $opt->{place_label +} eq 'after'); } sub input { my ($tab,$opt) = @_; my $tag = 'input'; my $open = open_tag($tag,$opt,['type','value','name','placeholder',@ +ics,@java,'tabindex']); my $text = $opt->{text} ? "$opt->{text} " : ''; label($tab,@{$opt->{label}}) if ($opt->{label} && $opt->{place_label +} eq 'before'); line($tab,"$text<$open>"); label($tab,@{$opt->{label}}) if ($opt->{label} && $opt->{place_label +} eq 'after'); } sub inputs { my ($tab,$inputs) = @_; input($tab, $_) for @$inputs; } sub legend { print plain_element('legend',[@ics,@java],@_); } sub fieldset { my ($tab,$code,$opt) = @_; my $tag = 'fieldset'; my $open = open_tag($tag,$opt,[@ics,@java]); line($tab,"<$open>"); legend($tab,$opt->{legend}) if $opt->{legend}; &$code; line($tab,"</$tag>"); } sub form { code_element('form',['action','method',@ics,@java],@_); } # End elements for forms. sub heading { my ($tab,$level,$value,$opt) = @_; my $tag = 'h'.$level; print plain_element($tag,[@ics,@java],$tab,$value,$opt); } sub pre { code_element('pre',[@ics,@java],@_); } sub div { code_element('div',[@ics,@java],@_); } sub header { code_element('header',[@ics,@java],@_); } sub footer { code_element('footer',[@ics,@java],@_); } sub aside { code_element('aside',[@ics,@java],@_); } sub section { code_element('section',[@ics,@java],@_); } sub article { code_element('article',[@ics,@java],@_); } sub nav { code_element('nav',[@ics,@java],@_); } sub main { code_element('main',[@ics,@java],@_); } sub body { code_element('body',[@ics,@java],@_); } # End elements for body. sub html { my ($tab,$opt) = @_; my $tag = 'html'; my $open = $tag; print "content-type: text/html \n\n"; line(0,'<!DOCTYPE html>'); line($tab,"<$open>"); head($tab + 1, $opt->{'head'}) if $opt->{'head'}; body($tab + 1, @{$opt->{'body'}}) if $opt->{'body'}; line($tab,"</$tag>"); } # End elements =head1 NAME B<HTML::Element> generates HTML tags for most of the HTML elements. =head1 SYNOPSIS To use B<HTML::Element> to print HTML tags, use the following. All fun +ctions are exported only upon request. use Base::HTML::Element qw( title heading script anchor paragraph rparagraph list definition_l +ist table form fieldset selection input textarea div pre html ); my @list = ( 'white', ['red, { style => 'color:#ff0000' }], ['green', { style => 'color:#00ff00' }], ['blue', { style => 'color:#0000ff' }], 'black' ); $tab = 0; html($tab, { 'head' => { 'title' => 'My page title', 'links' => [{ rel => 'stylesheet', type => 'text/css', href = +> 'css/style.css' }], 'scripts' => [{ type => 'text/javascript', src => 'javascript/sc +ript.js' }], }, 'body' => [ sub { $tab++; nav($tab, sub { list($tab + 2, 'u', \@nav_array); }, { 'heading' => [1, 'Nav heading'], 'id' => 'nav_id', 'class' => 'nav_class', 'style' => 'nav_style' } ); article($tab, sub { $tab++; section($tab, sub { paragraph($tab + 2, 'I did not give this section a hea +der or footer for my sanity.'); aside($tab + 2, sub { paragraph($tab + 1, 'And now for a ramble on somet +hing tangential.'); } ); }, { 'heading' => [2, 'Section 1 heading'], 'id' => 'section_1', 'class' => 'section', 'style' => 'section_1_style' } ); section($tab, sub { paragraph($tab + 2, 'I did not give this section a hea +der or footer either for my sanity.'); list($tab + 2, 'u', \@list); }, { 'heading' => [2, 'Section 2 has a list of colors'], 'id' => 'section_2', 'class' => 'section', 'style' => 'section_2_style' } ); $tab--; }, { 'id' => 'article_id', 'class' => 'article_class', 'style' => 'article_class', 'header' => [sub { paragraph($tab + 2, 'Opening remarks in article.', { 'id' => 'article_open_remarks', 'class' => 'remarks', 'style' => 'article_open_style' }); }, { 'heading' => [1, 'Article heading'], 'id' => 'article_header_id', 'class' => 'article_header_class', 'style' => 'article_header_style' }], 'footer' => [sub { $tab++; paragraph($tab, 'Closing remarks in article', { 'id' => 'article_close_remarks', 'class' => 'remarks', 'style' => 'article_close_style' }); address($tab, anchor('return to top', { href => '#body_h +eader_id' })); $tab--; }, { 'id' => 'body_footer_id', 'class' => 'body_footer_class', 'style' => 'body_footer_style' }] } ); $tab--; }, { 'id' => 'body_id', 'class' => 'body_class', 'style' => 'body_style' 'header' => [sub { $tab++; paragraph($tab + 2, 'Opening remarks in body.', { 'id' => 'body_open_remarks', 'class' => 'remarks', 'style' => 'font-weight:bold' }); $tab--; }, { 'heading' => [1, 'Body heading'], 'id' => 'body_header_id', 'class' => 'body_header_class', 'style' => 'body_header_style' }], 'footer' => [sub { $tab++; paragraph($tab, 'Closing remarks in body', { 'id' => 'body_close_remarks', 'class' => 'remarks', 'style' => 'font-size:bigger' }); address($tab, anchor('My email', { href => 'mailto:my@email. +com' })); $tab--; }, { 'id' => 'body_footer_id', 'class' => 'body_footer_class', 'style' => 'body_footer_style' }] } ], }); =head1 ELEMENTS All of the functions C<print> the elements with the exception of C<anc +hor> which returns the anchor and C<rparagraph> which returns a parag +raph for use in other functions. As with the Perl community, the HTML community expects some indentatio +n so tabs, the first parameter of every function, are included with e +ach element except where noted. The last parameter of every element is a hash reference with named opt +ions except where noted. Most elements have the C<id>, C<class>, C<st +yle>, C<lang>, and scripting options (such as C<onclick>). Only the o +ptions specific to the element will be noted. =head2 C<html> B<C<html>> has the tab and several optional parameters C<head> and C<b +ody>. C<head> is a hash reference with the same optional parameters o +f C<L<head|/head>> below. C<body> is an array reference with the same + values as C<L<body|/body>> below. B<Do not> include the C<$tab> para +meters in either. html($tab, { 'head' => { }, 'body' => [ ], }); See the L<synopsis|/SYNOPSIS> for how B<C<html>> could be used. =head2 C<head> B<C<head>> is available in case you do not want to use the C<L<html|/h +tml>> function. It has the required parameter C<title> and optional p +arameters C<base>, C<meta>, C<links>, C<scripts>, C<style>, and C<pro +file>. head($tab, { 'title' => 'My page title', 'base' => { href => 'www.mysite.com', target => '_self' }, 'meta' => \@array_of_meta_hashes, 'links' => \@array_of_link_hashes, 'scripts' => \@array_of_script_hashes, 'style' => \@array_of_style_data, }); =head3 Setting up C<base> The base can have a C<href>, C<target>, or both. base => { href => 'www.mysite.com', target => '_blank' } =head3 Setting up C<meta> Each meta hash would look mostly like the following. The optional para +meters are C<name>, C<content>, C<http-equiv>, and C<lang>. meta => [ { 'http-equiv' => 'Content-Type', 'content' => 'text/html; charset=windows-1252' }, { 'name' => 'author', 'content' => 'My name, 'lang' => 'en' } ], =head3 Setting up C<links> Each link hash would look mostly like the following. Since there is a +conflict between the perl funcion C<link>, this function takes a list + of them. links => [{ rel => 'stylesheet, type => 'text/css', href => 'css/css.css' }], =head3 Setting up C<scripts> Each script hash would look mostly like the following. scripts => [{ type => 'text/javascript', src => 'javascript/javascript.js' }], =head3 Setting up C<style> The style array would look mostly like the following. style => [ ' p { font-size: 10pt; } ul { list-style-type: disc; } ', { type => 'text/css' } ], =head2 C<body>, C<main>, C<section>, C<article>, C<nav>, C<aside>, C<d +iv>, C<noscript>, and C<pre> =head3 C<body> B<C<body>> is available in case you do not want to use the C<L<html|/h +tml>> function. It has code and optional parameters. body($tab, sub { paragraph($tab, 'I have something to say.'); definition_list($tab, @definition_list_items); table($tab, { 'caption' => 'Table caption', 'rows' => \@rows }); }, { 'id' => 'body_id', 'class' => 'body_classes', 'style' => 'body_styles' 'heading' => [$heading_level, 'My body heading'], 'header' => [sub { paragraph($tab + 2, 'A paragraph in the body header.'); }, { 'id' => 'body_header_id', 'class' => 'body_header_classes', 'style' => 'body_header_styles', 'heading' => [$heading_level + 1, 'My body header heading.'], }], 'footer' => [sub { paragraph($tab + 2, 'A paragraph in the body footer.'); address($tab + 2, anchor('My email', { 'href' => 'mailto:my@email.com' })); }, { 'id' => 'body_footer_id', 'class' => 'body_footer_classes', 'style' => 'body_footer_styles', 'heading' => [$heading_level + 1, 'My body footer heading.'], }], }); =head3 C<main>, C<section>, C<article>, C<nav>, and C<aside> B<C<main>>, B<C<section>>, B<C<article>>, B<C<nav>>, and B<C<aside>> h +ave code and optional parameters like L<body|/body>. =head4 C<main> example main($tab, sub { paragraph($tab, 1, 'This is an main I wrote.') }, { 'id' => 'main_id', 'class' => 'main_classes', 'style' => 'main_styles' 'heading' => [$heading_level, 'My aticle heading'], 'header' => [sub { paragraph($tab + 2, 'A paragraph in the main header.'); }, { 'id' => 'main_header_id', 'class' => 'main_header_classes', 'style' => 'main_header_styles', 'heading' => [$heading_level + 1, 'My main header heading.'], }], 'footer' => [sub { paragraph($tab + 2, 'A paragraph in the main footer.'); }, { 'id' => 'main_footer_id', 'class' => 'main_footer_classes', 'style' => 'main_footer_styles', 'heading' => [$heading_level + 1, 'My main footer heading.'], }], }); =head4 C<section> example section($tab, sub { paragraph($tab, 'My section contents.') }, { 'id' => 'section_id', 'class' => 'section_classes', 'style' => 'section_styles' 'heading' => [$heading_level, 'My section heading'], 'header' => [sub { paragraph($tab + 2, 'A paragraph in the section header.'); }, { 'id' => 'section_header_id', 'class' => 'section_header_classes', 'style' => 'section_header_styles', 'heading' => [$heading_level + 1, 'My section header heading.'], }], 'footer' => [sub { paragraph($tab + 2, 'A paragraph in the section footer.'); }, { 'id' => 'section_footer_id', 'class' => 'section_footer_classes', 'style' => 'section_footer_styles', 'heading' => [$heading_level + 1, 'My section footer heading.'], }], }); =head4 C<article> example article($tab, sub { paragraph($tab, 1, 'This is an article I wrote.') }, { 'id' => 'article_id', 'class' => 'article_classes', 'style' => 'article_styles' 'heading' => [$heading_level, 'My aticle heading'], 'header' => [sub { paragraph($tab + 2, 'A paragraph in the article header.'); }, { 'id' => 'article_header_id', 'class' => 'article_header_classes', 'style' => 'article_header_styles', 'heading' => [$heading_level + 1, 'My article header heading.'], }], 'footer' => [sub { paragraph($tab + 2, 'A paragraph in the article footer.'); }, { 'id' => 'article_footer_id', 'class' => 'article_footer_classes', 'style' => 'article_footer_styles', 'heading' => [$heading_level + 1, 'My article footer heading.'], }], }); =head4 C<nav> example nav($tab, sub { heading($tab, 1, 'My page navigation'); # a subheading list($tab, 'o', \@my_page_sections); heading($tab, 1, 'My site navigation'); # a subheading list($tab, 'u', \@my_site_pages); }, { 'id' => 'nav_id', 'class' => 'nav_classes', 'style' => 'nav_styles' 'heading' => [$heading_level, 'My navigation heading'], 'header' => [sub { paragraph($tab + 2, 'A paragraph in the nav header.'); }, { 'id' => 'nav_header_id', 'class' => 'nav_header_classes', 'style' => 'nav_header_styles', 'heading' => [$heading_level + 1, 'My nav header heading.'], }], 'footer' => [sub { paragraph($tab + 2, 'A paragraph in the nav footer.'); }, { 'id' => 'nav_footer_id', 'class' => 'nav_footer_classes', 'style' => 'nav_footer_styles', 'heading' => [$heading_level + 1, 'My nav footer heading.'], }], }); =head4 C<aside> example aside($tab, sub { paragraph($tab, 'Here are my tangential thoughts about the subject + of the article or section.') }, { 'id' => 'aside_id', 'class' => 'aside_classes', 'style' => 'aside_styles' 'heading' => [$heading_level, 'My aside heading'], 'header' => [sub { paragraph($tab + 2, 'A paragraph in the aside header.'); }, { 'id' => 'aside_header_id', 'class' => 'aside_header_classes', 'style' => 'aside_header_styles', 'heading' => [$heading_level + 1, 'My aside header heading.'], }], 'footer' => [sub { paragraph($tab + 2, 'A paragraph in the aside footer.'); }, { 'id' => 'aside_footer_id', 'class' => 'aside_footer_classes', 'style' => 'aside_footer_styles', 'heading' => [$heading_level + 1, 'My aside footer heading.'], }], }); =head3 C<header> and C<footer> B<C<header>> and B<C<footer>> are available if you do not want to posi +tion the C<header> at the beginning of the element and C<footer> at t +he end of the element. They have code and optional parameters. Both h +ave been built into the C<body>, C<article>, C<section>, C<nav>, and +C<aside> functions, but they can be used independently of them. =head4 C<header> example header($tab, sub { paragraph($tab, 'This is the header.'); }, { 'id' => 'header_id', 'class' => 'header_classes', 'style' => 'header_styles' 'heading' => [$heading_level, 'My header heading'], }); =head4 C<footer> example footer($tab, sub { paragraph($tab, 'This is the footer.'); }, { 'id' => 'footer_id', 'class' => 'footer_classes', 'style' => 'footer_styles' 'heading' => [$heading_level, 'My footer heading'], }); =head3 C<div> B<C<div>> has code and optional parameters. div($tab, sub { print "Text with formatting." }, { heading => [$heading_level, 'My div heading'], id => 'div_id', class => 'div_class', style => 'div_style' }); =head3 C<noscript> =head3 C<pre> B<C<pre>> has code but no optional parameters. The C<tab> will be igno +red. pre($tab, sub { print "Text without any formatting, great for data dumping to view i +n a browser." }); =head2 C<heading> B<C<heading>> has the heading level, value, and optional parameters. T +his has been built into the C<body>, C<article>, C<section>, C<nav>, +C<aside>, C<header>, and C<footer> functions but can be used independ +ently of them. heading($tab, 2, 'My second level heading', { 'id' => 'heading_id', 'class' => 'heading_classes', 'style' => 'heading_styles' }); =head2 paragraphs B<C<paragraph>> and B<C<rparagraph>> have a value and the optional par +ameter C<separator>. =head3 C<paragraph> B<C<paragraph>> prints the paragraph(s). The C<separator> option allow +s you to input more than one paragraph per use of this function. paragraph($tab, 'My paragraph(s)', { id => 'paragraph_id', class => 'paragraph_classes', style => 'paragraph_styles' separator => 'paragraph_separator' }); =head3 C<rparagraph> B<C<rparagraph>> returns paragraph(s). See L<paragraph|/paragraph>. my $favorite = rpragraph($tab,'My favorite color.'); my @list = ( ['red, { style => 'color:#ff0000' }], ['green', { style => 'color:#00ff00' }], ["blue\n$favorite", { style => 'color:#0000ff' }] # My favorite c +olor. ); =head2 C<list> B<C<list>> has type, list, and the optional parameters. C<type> is C<u> for an unordered list or C<o> for an ordered list. The + C<list> parameter is an array reference. list($tab, 'u', \@list, { id => 'list_id', class => 'list_class' style => 'list_style, }); =head3 Setting up the list items If you do not want your list items formatted, you can pass your array +as is. If you want your list items formatted, the formatted items are + also array references with the optional parameter C<inlist>. 'unformatted value', ['formatted value', { id => 'item_id', class => 'item_class', style => 'item_style', inlist => ['u', \@inner_list, { list options }] }], 'another unformatted value' =head2 C<definition_list> B<C<definition_list>> has a definition list and optional parameters. definition_list($tab, \@definitions, { id => 'definition_list_id', class => 'definition_list_class', style => 'definition_list_style', }); =head3 Setting up the definition list The definition list array refernce is arrayrefs with the definition te +rms and definitions. my @definitions = ( ['definition term one','definition for term one'], ['definition term two','definition for term two'], ['definition term foo','definition for term foo'], ); =head2 C<table> Before you go any further, if you plan on using a table for layout, B< +I<STOP!>> Tables are for tabular data, use L<div|/div> elements to la +y out your webpage. B<C<table>> has the optional parameters of C<caption>, C<cols>, and C< +rows>. C<cols> and C<rows> are array references. table($tab, { id => 'table_id', class => 'table_class', style => 'table_style', caption => 'table caption', cols => \@cols, rows => \@rows, }); =head3 Setting up the caption C<caption> is a value, as seen above, or an array refernce. The C<capt +ion> has the optional parameter C<align>. ['table caption', { id => 'caption_id', class => 'caption_class', style => 'caption_style', align => 'caption_align' }], =head3 Setting up the columns Each C<column> is an array reference of hash references and each has t +he optional parameter C<span>. { id => 'col_id', class => 'col_class', style => 'col_style' span => 2, }, =head3 Setting up the rows Each C<row> is an array reference with C<type>, C<cells>, and optional + parameters. You need to know type of cells are in the row. =over =item * C<header> is a row with only headings. There is only one row allowed i +n C<header>. =item * C<data> is a group of rows with only data. =item * C<whead> is a group of rows with a heading then data. =back rows => [ ['header',\@headings, { id => 'header_row_id', class => 'header_row_class', style => 'header_row_style }], ['data',\@data, { id => 'data_row_id', class => 'data_row_class', style => 'data_row_style }], ['whead',\@data_with_heading], ], =head4 Setting up the cells If you do not want your cells formatted, you can pass your array as is +. If you want your cells formatted, the formatted cells are also arra +y references with optional parameters C<list> and C<type_override>. T +he C<list> option is the same as the C<inlist> option for L<list item +s|/Setting up the list items>. If you need to override the row type, +use C<type_override>. 'unformatted value', ['formatted value', { id => 'cell_id', class => 'cell_class', style => 'cell_style', }], ['list', { id => 'cell_with_list_id', class => 'cell_class', style => 'cell_style', list => ['u', \@list_in_cell, { list options }] }], ['formatted value', { id => 'cell_id', class => 'cell_class', style => 'cell_style', type_override => 'h', }], 'another unformatted value' =head2 forms =head3 C<form> B<C<form>> has code and the optional paramters C<action> and C<method> +. form($tab, sub { ... form elements ... }, { action => 'form_action', method => 'form_method', id => 'form_id', class => 'form_class', style => 'form_style' }); =head3 C<fieldset> B<C<fieldset>> has code and the optional paramter C<legend>. fieldset($tab, sub { ... fieldset elements ... }, { legend => 'legend_text', id => 'fieldset_id', class => 'fieldset_class', style => 'fieldset_style' }); =head4 Setting up the legend The legend can be unformatted as above or formatted as below in an arr +ay reference with the optional parameter C<align>. legend => ['legend_text', { id => 'legend_id', class => 'legend_class', style => 'legend_style, align => 'legened_align' }], =head3 C<selection> B<C<selection>> has options and the optional parameters C<name>, C<mul +tiple>, C<label>, and C<tabindex>. selection($tab, \@options, { name => 'select_name', multiple => 'multiple', label => ['label text', { for => 'select_name', id => 'label_id', class => 'label_class', style => 'label_style' } id => 'select_id', class => 'select_class', style => 'select_style' }); =head4 Setting up the options If you do not want your options formatted, all you need to do is pass +the text and C<value> of the option. If you want formatting, you need + to pass the other optional parameters. ['unformatted option', { value => 'unformatted' }], ['formatted option', { value => 'formatted', id => 'option_id', class => 'option_class', style => 'option_style' }] =head3 C<input> B<C<input>> has the optional parameters C<type>, C<value>, C<name>, C< +label>, and C<tabindex>. =head3 C<inputs> B<C<inputs>> takes a list of parameters to print many instances of C<i +nput>. =head3 C<textarea> B<C<textarea>> has a value and the optional parameters C<name>, C<rows +>, C<cols>, C<label>, and C<tabindex>. textarea($tab, 'text in the textarea box', { name => 'textarea_name', rows => 100, cols => 100, label => ['label text', { for => 'textarea_name', id => 'label_id', class => 'label_class', style => 'label_style' } id => 'textarea_id', class => 'textarea_class', style => 'textarea_style' }); =head2 C<script> B<C<script>> has optional parameters C<type> and C<src>. script($tab, { type => 'text/javascript', # or other type src => 'script.ext' }); =head2 C<anchor> B<C<anchor>> has a value and the optional parameters C<href>, C<target +>, and C<title>. C<anchor> does not not get a C<tab>. anchor('Anchor text', { href => 'link location', target => 'where the link opens', title => 'alternate text', id => 'anchor_id', class => 'anchor_classes', style => 'anchor_styles' }); =head1 SEE ALSO L<CGI> can do all of the above with objects. Where an HTML element mat +ches a Perl function, they just uppercased the element which feels ve +ry wrong to me. L<HTML::Element> can also do all of the above with objects, but you ha +ve to build each element yourself. L<HTML::HTML5::Builder> and L<Template::Declare::Tags> also build HTML + elements. There are many other modules out there which can build and print HTML +elements, but most are object oriented. I find it easier to deal with + functions over objects when printing. =head1 AUTHOR Written by Lady Aleena (Lady underscore Aleena at xecu dot net) with a + lot of help from the L<PerlMonks|http://www.perlmonks.org>. =cut 1;

Notes to self

  • Do not print Dumper when trying to display a script in a browser without using <pre> tags.
  • Do print Dumper when something goes wrong. The data structure is usually the problem.
  • If one changes a variable, check the whole script for that variable to make sure that the results will be as expected.
  • rename will not create directories, be sure to use mkdir in conjunction with rename if the files are also being moved to a new directory.

Notes from others

  • bart: LA it's often considered good practice to increment the variable in a continue block, to prevent running out of sync when using next.
  • Intrepid: btw, i wish i could explain to a lot of people i know, how efficacious Lady_Aleena's explained strategy can be (to use coding and thinking about coding to master a disquieted state of mind)
  • ambrus: In general, use magic only when normal solutions aren't enough.
  • GrandFather: each time through its loop while asks itself "Can I loop this time? Can I? Can I Can I? Please?" and if the answer is no (false statement) while gets grumpy and stops

Things I should get a grip on

  • objects
  • testing
  • SQL
  • version control
Log In?
Username:
Password:

What's my password?
Create A New User
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (10)
As of 2014-09-16 11:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (13 votes), past polls