#!/usr/bin/perl
use strict;
use warnings;
use HTML::Widgets::NavMenu ();
use File::Path qw/ mkpath /;
use Template ();
my $css_style = <<"EOF";
a:hover { background-color : palegreen; }
.body {
float : left;
width : 70%;
padding-bottom : 1em;
padding-top : 0em;
margin-left : 1em;
background-color : white;
}
.navbar {
float : left;
background-color : moccasin;
width : 20%;
border-color : black;
border-width : thick;
border-style : double;
padding-left : 0.5em;
}
.navbar ul
{
font-family: sans-serif;
font-size : small;
margin-left : 0.3em;
padding-left : 1em;
}
.navlinks
{
background-color:
#30C020;
margin-bottom : 0.2em;
padding-left: 0.5em;
padding-bottom: 0.2em;
border-style: solid;
border-width: thin;
border-color: black;
}
.breadcrumb
{
background-color: #4190e1;
padding-bottom: 0.3em;
padding-left: 0.5em;
padding-top: 0.3em;
margin-bottom: 0.2em;
border-style: solid;
border-width: thin;
border-color: #FF8080;
font-size: 80%;
}
.breadcrumb :link
{
color: #FFFF00 ;
}
.breadcrumb :link:hover
{
color: red;
}
.breadcrumb :visited
{
color: #F5F5DC;
}
.breadcrumb :visited:hover
{
color: #800000;
}
EOF
my $nav_menu_tree = {
'host' => "default",
'text' => "HTML-Widgets-NavMenu Example",
'title' => "HTML-Widgets-NavMenu",
'subs' => [
{
'text' => "Home",
'url' => "",
},
{
'text' => "About Myself",
'url' => "me/",
'subs' => [
{
'text' => "Bio",
'url' => "personal.html",
'title' => "A Short Biography of Myself",
},
{
'text' => "Contact",
'url' => "me/contact-me/",
'title' => "How to Contact me in Every Conceivable Way",
},
{
'text' => "My Resumés",
'url' => "me/resumes/",
'subs' => [
{
'text' => "English Resumé",
'url' => "resume.html",
'skip' => 1,
},
{
'text' => "Detailed English Resumé",
'url' => "resume_detailed.html",
'skip' => 1,
},
],
},
],
},
{
'text' => "Humour",
'url' => "humour/",
'title' => "My Humorous Creations",
'show_always' => 1,
'subs' => [
{
'text' => "The Enemy",
'url' => "humour/TheEnemy/",
'title' => "The Enemy and How I Helped to Fight It",
},
{
'text' => "TOWTF",
'url' => "humour/TOWTF/",
'title' => "The One with the Fountainhead",
},
{
'text' => "The Pope",
'url' => "humour/Pope/",
'title' => "The Pope Died on Sunday",
},
{
'text' => "Humour Archive",
'title' => "Archive of Humorous Bits I came up with",
'url' => "humour.html",
},
{
'text' => "Fortune Cookies Collection",
'title' =>
"Collection of Files for Input to the UNIX 'fortune' Program",
'url' => "humour/fortunes/",
},
],
},
{
'text' => "Math-Ventures",
'url' => "MathVentures/",
'title' => "Mathematical Riddles and their Solutions",
},
{
'text' => "Computer Art",
'url' => "art/",
'title' => "Computer art I created while explaining how.",
'subs' => [
{
'text' => "Back to my Homepage",
'url' => "art/bk2hp/",
'title' =>
"A Back to my Homepage logo not unlike the one from the movie "Back to the Future"",
},
{
'text' => "Linux Banner",
'url' => "art/linux_banner/",
'title' =>
"Linux - Because Software Problems should not Cost Money",
},
],
},
{
'text' => "Software",
'url' => "open-source/",
'expand' => { 're' => "^(open-source|perl)/", },
'title' => "Pages related to Software (mostly Open-Source)",
'subs' => [
{
'text' => "Freecell Solver",
'url' => "open-source/projects/freecell-solver/",
},
{
'text' => "MikMod for Java",
'title' =>
"A Player for MOD Files (a type of Music Files) for the Java Environment",
'url' => "jmikmod/",
},
{
'text' => "FCFS RWLock",
'title' => "A First-Come First-Served Readers/Writers Lock",
'url' => "rwlock/",
},
{
'text' => "Quad-Pres",
'title' => "A Tool for Creating HTML Presentations",
'url' => "open-source/projects/quad-pres/",
},
{
'text' => "Favourite OSS",
'title' => "Favourite Open-Source Software",
'url' => "open-source/favourite/",
},
{
'text' => "Interviews",
'title' => "Interviews with Open-Source People",
'url' => "open-source/interviews/",
},
{
'text' => "Contributions",
'title' =>
"Contributions to Other Projects, that I did not Start",
'url' => "open-source/contributions/",
},
{
'text' => "Bits and Bobs",
'title' => "Various Small-Scale Open-Source Works",
'url' => "open-source/bits.html",
},
{
'text' => "Portability Libraries",
'title' => "Cross-Platform Abstraction Libraries",
'url' => "abstraction/",
'hide' => 1,
},
{
'text' => "Software Tools",
'title' => "Software Construction and Management Tools",
'url' => "software-tools/",
'hide' => 1,
},
],
},
{
'text' => "Lectures",
'url' => "lecture/",
'expand' => { 're' => "^lecture/", },
'title' => "Presentations I Wrote (Mostly Technical)",
'subs' => [
{
'text' => "Perl for Newbies",
'url' => "lecture/Perl/Newbies/",
},
{
'text' => "Freecell Solver",
'url' => "lecture/Freecell-Solver/",
},
{
'text' => "Lambda Calculus",
'title' =>
"A presentation about a Turing-complete programming environment with only two primitives",
'url' => "lecture/lc/",
},
{
'text' => "The Gimp",
'title' =>
"A Presentation about the GNU Image Manipulation Program",
'url' => "lecture/Gimp/",
},
{
'text' => "GNU Autotools",
'url' => "lecture/Autotools/",
},
{
'text' => "Web Meta Lecture",
'title' => "A Presentation about the Web Meta Language",
'url' => "lecture/WebMetaLecture/",
},
],
},
{
'text' => "Essays",
'url' => "essays/",
'title' =>
"Various Essays and Articles about Technology and Philosophy in General",
'subs' => [
{
'text' => "Index to Essays",
'url' => "essays/Index/",
'title' => "Index to Essays and Articles I wrote.",
},
{
'text' => "Open Source",
'url' => "essays/open-source/",
'title' => "Essays about Open-Source",
},
{
'text' => "Life",
'url' => "essays/life/",
'title' => "Essays about Life, the Universe and Everything",
},
],
},
{
'text' => "Cool Links",
'url' => "links.html",
'title' => "An incomplete list of links I find cool and/or useful.",
},
{
'text' => "Site Map",
'url' => "site-map/",
'title' => "A site map for the site with all the pages",
},
],
};
my %hosts = (
'hosts' => {
'default' => {
'base_url' => (
"http://web-cpan.berlios.de/modules/"
. "HTML-Widgets-NavMenu/article/examples/simple/dest/"
),
},
},
);
my @page_paths = (
"",
"me/",
"personal.html",
"me/contact-me/",
"me/resumes/",
"resume.html",
"resume_detailed.html",
"humour/",
"humour/TheEnemy/",
"humour/TOWTF/",
"humour/Pope/",
"humour.html",
"humour/fortunes/",
"MathVentures/",
"art/",
"art/bk2hp/",
"art/linux_banner/",
"open-source/",
"open-source/projects/freecell-solver/",
"jmikmod/",
"rwlock/",
"open-source/projects/quad-pres/",
"open-source/favourite/",
"open-source/interviews/",
"open-source/contributions/",
"open-source/bits.html",
"abstraction/",
"software-tools/",
"lecture/",
"lecture/Perl/Newbies/",
"lecture/Freecell-Solver/",
"lecture/lc/",
"lecture/Gimp/",
"lecture/Autotools/",
"lecture/WebMetaLecture/",
"essays/",
"essays/Index/",
"essays/open-source/",
"essays/life/",
"links.html"
);
my @pages = (
map {
+{
'path' => $_,
'title' => "Title for $_",
'content' => "<p>Content for $_</p>"
}
} @page_paths
);
# Add the site-map page.
{
my $site_map_path = "site-map/";
my $site_map_generator = HTML::Widgets::NavMenu->new(
path_info => "/$site_map_path",
current_host => "default",
hosts => \%hosts,
tree_contents => $nav_menu_tree
);
push @pages,
{
'path' => $site_map_path,
'title' => "Site Map",
'content' => join( "\n", @{ $site_map_generator->gen_site_map() } ),
};
};
push @pages,
(
{
'path' => "perl/japhs/",
'title' => "Perl JAPHs",
'content' => "<p>JAPHs for fun and profit.</p>",
},
{
'path' => "open-source/yowza/",
'title' => "A Wonderful Yowza",
'content' => "<p>Yowza is da-bomb man!</p>",
}
);
foreach my $page (@pages)
{
my $path = $page->{'path'};
my $nav_menu = HTML::Widgets::NavMenu->new(
path_info => "/$path",
current_host => "default",
hosts => \%hosts,
tree_contents => $nav_menu_tree,
);
my $nav_menu_results = $nav_menu->render();
my $file_path = $path;
if ( ( $file_path =~ m{/$} ) || ( $file_path eq "" ) )
{
$file_path .= "index.html";
}
my $full_path = "dest/$file_path";
$full_path =~ m{^(.*)/[^/]+$};
# mkpath() throws an exception if it isn't successful, which will cause
# this program to terminate. This is what we want.
mkpath( $1, 0, oct('0755'), );
open my $out, ">", $full_path
or die "Could not open \"$full_path\" for writing!";
my $template = Template->new(
{
'POST_CHOMP' => 1,
}
);
my $vars = {
'title' => $page->{'title'},
'css_style' => $css_style,
'nav_menu_text' => join( "\n", @{ $nav_menu_results->{'html'} } )
. "\n",
'content' => $page->{'content'} . "\n",
'breadcrumbs' => $nav_menu_results->{leading_path},
'nav_links' => $nav_menu_results->{'nav_links_obj'},
};
my $nav_links_template = <<'EOF';
[% USE HTML %]
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>[% title %]</title>
<style type="text/css">
[% css_style %]
</style>
[% FOREACH key = nav_links.keys.sort %]
<link rel="[% key %]"
href="[% HTML.escape(nav_links.$key.direct_url()) %]"
title="[% nav_links.$key.title() %]" />
[% END %]
</head>
<body>
<div class="breadcrumb">
[% FOREACH c = breadcrumbs %]
[% UNLESS loop.first %] → [% END %]
<a href="[% HTML.escape(c.direct_url) %]"
[% IF c.title %] title="[% c.title %]"[% END %]
>[% c.label %]</a>
[% END %]
</div>
<div class="navlinks">
[% FOREACH key = nav_links.keys.sort %]
<a href="[% HTML.escape(nav_links.$key.direct_url()) %]"
title="[% nav_links.$key.title() %]">[% key %]</a>
[% END %]
</div>
<div class="navbar">
[% nav_menu_text %]
</div>
<div class="body">
<h1>[% title %]</h1>
[% content %]
</div>
</body>
</html>
EOF
$template->process( \$nav_links_template, $vars, $out );
close($out);
}