package HTTP::AppServer::Plugin::PlainHTML;
# Plugin for HTTP::AppServer that creates static html pages for
# a given set of database tables to make a website better accessable
# for search engine crawlers and drive SEO.
# 2010 by Tom Kirchner

use 5.010000;
use strict;
use warnings;
use HTTP::AppServer::Plugin;
use base qw(HTTP::AppServer::Plugin);

our $VERSION = '0.01';

my $Tables = {
	# <tablename> => {
	#   url => <url>,
	#   title => <string>,
	#   description => <string>,
	# }
};

my $JavaScriptURL = '';

# called by the server when the plugin is installed
# to determine which routes are handled by the plugin
sub init
{
	my ($class, $server, %options) = @_;

	# all database tables that should be able to be dumped
	$Tables = $options{'Tables'} if exists $options{'Tables'};

	# the url the integrated JS should redirect to
	$JavaScriptURL = $options{'JavaScriptURL'} if exists $options{'JavaScriptURL'};
	
	# the plugin installs a URL handler
	my @handlers = ();
	foreach my $tablename (keys %{$Tables}) {
		my $info = $Tables->{$tablename};
		   $info->{'tablename'} = $tablename;
		push @handlers, 
			($info->{'url'}, 
				sub { 
					my ($server, $cgi) = @_; 
					return _dump_as_html($server, $cgi, $info); 
				});
	}
	return @handlers;
}

sub _dump_as_html
{
	my ($server, $cgi, $info) = @_;
	my @rows = $server->findall(-tables => [$info->{'tablename'}]);

	print "HTTP/1.0 200 Ok\r\n";
	print $cgi->header('text/html');
	print '<html><head><title>'.ucfirst($info->{'title'}).'</title></head><body>';
	print '<script>window.location = "'.$JavaScriptURL.'";</script>'
		if length $JavaScriptURL;
	print '<h1>'.ucfirst($info->{'title'}).'</h1>';
	print '<p>'.ucfirst($info->{'description'}).'</p>';
	foreach my $row (@rows) {
		print '<dl>';
		foreach my $key (sort keys %{$row}) {
			print '<dt>'.ucfirst($key).':</dt><dd>'.$row->{$key}.'</dd>';
		}
		print '</dl>';
	}
	print '</body></html>';
	return 1;
}

1;
__END__
=head1 NAME

HTTP::AppServer::Plugin::PlainHTML - Plugin for HTTP::AppServer that creates static html pages for a given set of database tables to make a website better accessable for search engine crawlers and drive SEO.

=head1 SYNOPSIS

  use HTTP::AppServer;
  my $server = HTTP::AppServer->new();
  $server->plugin('PlainHTML'
    JavaScriptURL => '/',
    Tables => {
      'table1' => {
        'url' => '^\/tab1\.html$',
        'title' => '...',
        'description' => '...',
      },
      'table2' => {
        'url' => '^\/tab2\.html$',
        'title' => '...',
        'description' => '...',
      },
    },  
  );

=head1 DESCRIPTION

Plugin for HTTP::AppServer that creates static html pages for a given set 
of database tables to make a website better accessable for search engine 
crawlers and drive SEO.

Pure AJAX driven sites sometimes have the problem that the content
cannot be easily provided to search engine crawlers. This plugin dumps
all content from specific database tables as semantic HTML for
non-JavaScript clients, sich as crawlers. Whenever a JavaScript-enabled
client accesses such a dump-page its forwarded to the actual homepage
(which is then AJAX driven).

=head2 Plugin configuration

=head3 JavaScriptURL => I<URL>

All HTML pages generated by the plugin contain a javascript code
that forwards the browser to this URL. This is due to the fact of
the intention of this module, see above. 

=head3 Tables => I<hash>

Tables contains an entry for every table that should be dumped.
An entry may look like this:

  'table2' => {
    'url' => '^\/tab2\.html$',
    'title' => '...',
    'description' => '...',
  },

This means "table2" will be dumped as semantic HTML under the URL
"/tab2.html".

=head2 Installed URL handlers

For each table there the plugin installs an URL handler.

=head2 Installed server properties

None.

=head2 Installed server methods

None.

=head1 SEE ALSO

HTTP::AppServer, HTTP::AppServer::Plugin

=head1 AUTHOR

Tom Kirchner, E<lt>tom@tkirchner.comE<gt>

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2010 by Tom Kirchner

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.10.0 or,
at your option, any later version of Perl 5 you may have available.


=cut
