+package Gruntmaster::Page;
+
+use 5.014000;
+use strict;
+use warnings;
+use parent qw/Exporter/;
+our @EXPORT_OK = qw/generate header footer/;
+
+use File::Basename qw/fileparse/;
+use File::Slurp qw/write_file/;
+use IO::Compress::Gzip qw/gzip/;
+
+our $VERSION = '0.001';
+our @generators;
+
+use constant LANGUAGES => [ 'en' ];
+use constant CONTENT_TYPES => {
+ html => 'text/html; charset=UTF-8',
+ txt => 'text/plain; charset=UTF-8',
+};
+
+my %header_templates = (
+ en => <<'HTML',
+<!DOCTYPE html>
+<title>TITLE_GOES_HERE</title>
+<link rel="stylesheet" href="/gm.css">
+<script src="/jquery-2.0.3.min.js"></script>
+<script src="/view.js"></script>
+<meta charset="utf-8">
+
+<span id="admin"></span>
+<div id="title"><span class="i">i</span><span class="Eval">Eval</span></div>
+<div id="subtitle">TITLE_GOES_HERE</div>
+
+<nav><ul><li><a href="/">Home</a><li><a href="/log/">View job log</a><li><a href="/submit.var">Submit job</a><li><a href="/pb/">Problem list</a></ul></nav>
+
+HTML
+);
+
+my %footer_templates = (
+ en => <<'HTML',
+
+<footer>
+Dilmom: Why don't you call your product the Gruntmaster 6000?
+Dilbert: What kind of product do you see when you imagine a Gruntmaster 6000?
+Dilmom: Well, it's a stripped-down version of the Gruntmaster 9000, of course. But it's software-upgradeable.
+</footer>
+HTML
+);
+
+sub header{
+ my ($language, $title) = @_;
+ $header_templates{$language} =~ s/TITLE_GOES_HERE/$title/ger;
+}
+
+sub footer{
+ $footer_templates{$_[0]};
+}
+
+sub declaregen{
+ my ($generator, $regex) = @_;
+ $generator = "Gruntmaster::Page::$generator";
+ eval "require $generator";
+ my $gensub = $generator->can('generate') or die "No such generator: $generator";
+ push @generators, [$regex, $gensub];
+}
+
+declaregen Index => qr'^index$';
+declaregen Log => qr'^log/index$';
+declaregen 'Log::Entry' => qr'^log/.*/index$';
+declaregen Submit => qr'^submit$';
+declaregen Pb => qr'^pb/index$';
+declaregen 'Pb::Entry' => qr'^pb/.*/index$';
+
+sub generate{
+ my ($path) = @_;
+ my ($path_noext, $ext) = $path =~ m/^(.*)\.(.*)$/;
+ my $basename = fileparse $path_noext;
+
+ open my $typemap, ">$path_noext.var";
+ say $typemap "URI: $basename\n";
+ for my $gen(@generators) {
+ my ($regex, $generator) = @$gen;
+ next unless $path_noext =~ $regex;
+ for my $lang (@{LANGUAGES()}) {
+ my $page = $generator->($path, $lang);
+ write_file "$path_noext.$lang.$ext", $page;
+ say $typemap "URI: $basename.$lang.$ext\nContent-Language: $lang\nContent-Type: " . CONTENT_TYPES->{$ext} . "\n";
+ gzip \$page => "$path_noext.$lang.gz.$ext", Minimal => 1;
+ say $typemap "URI: $basename.$lang.gz.$ext\nContent-Language: $lang\nContent-Encoding: gzip\nContent-Type: " . CONTENT_TYPES->{$ext} . "\n";
+ }
+ }
+ close $typemap;
+}
+
+1;
+__END__
+# Below is stub documentation for your module. You'd better edit it!
+
+=head1 NAME
+
+Gruntmaster::Page - Perl extension for blah blah blah
+
+=head1 SYNOPSIS
+
+ use Gruntmaster::Page;
+ blah blah blah
+
+=head1 DESCRIPTION
+
+Stub documentation for Gruntmaster::Page, created by h2xs. It looks like the
+author of the extension was negligent enough to leave the stub
+unedited.
+
+Blah blah blah.
+
+=head2 EXPORT
+
+None by default.
+
+
+
+=head1 SEE ALSO
+
+Mention other useful documentation such as the documentation of
+related modules or operating system documentation (such as man pages
+in UNIX), or any relevant external documentation such as RFCs or
+standards.
+
+If you have a mailing list set up for your module, mention it here.
+
+If you have a web site set up for your module, mention it here.
+
+=head1 AUTHOR
+
+Marius Gavrilescu, E<lt>marius@E<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2013 by Marius Gavrilescu
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.18.1 or,
+at your option, any later version of Perl 5 you may have available.
+
+
+=cut