App-TemplateServer

 view release on metacpan or  search on metacpan

lib/App/TemplateServer.pm  view on Meta::CPAN

    },
);

has '_daemon' => (
    is       => 'ro',
    isa      => 'HTTP::Daemon',
    lazy     => 1,
    default  => sub { 
        return HTTP::Daemon->new(ReuseAddr => 1, LocalPort => shift->port);
    },
);

method run {
    print "Server started at: ". $self->_daemon->url. "\n";
    $self->_main_loop;
};

method _main_loop {
    local $SIG{CHLD} = 'IGNORE';
  app:
    while(my $c = $self->_daemon->accept){
        if(!fork){
          req:
            while (my $req = $c->get_request){
                my $res = $self->_req_handler($req);
                $c->send_response($res);
            }
            $c->close;
            exit; # exit child
        }
    }
};

method _req_handler($req) {
    my $res = eval {
        given($req->uri){
            when(m{^/(?:index(?:[.]html?)?)?$}){
                return $self->_render_index($req);
            }
            when(m{^/favicon.ico$}){
                return $self->_render_favicon($req);
            }
            default {
                return $self->_render_template($req);
            }
        }
    };
    if($@ || !$res){
        my $h = HTTP::Headers->new;
        $res = HTTP::Response->new(500, 'Internal Server Error', $h, $@);
    }
    
    return $res;
};

sub _success {
    my $content = shift;
    my $headers = HTTP::Headers->new;

    # set up utf8
    $headers->header('content-type' => 'text/html; charset=utf8');
    utf8::upgrade($content); # kill latin1
    utf8::encode($content);

    return HTTP::Response->new(200, 'OK', $headers, $content);
}

method _mk_context($req) {
    return App::TemplateServer::Context->new(
        data    => $self->_data,
        request => $req,
        server  => $self->_daemon,
    );
};

method _render_template($req) {
    my $context = $self->_mk_context($req);
    my $template = uri_unescape($req->uri->path);
    $template =~ s{^/}{};
    my $content = $self->provider->render_template($template, $context);
    return _success($content);
};

method _render_index($req) {

    my $index = App::TemplateServer::Page::Index->new(
        provider => $self->provider,
    );
    my $context = $self->_mk_context($req);
    my $content = $index->render($context);
    return _success($content);
};

method _render_favicon($req){
    return HTTP::Response->new(404, 'Not found');
};

1;
__END__

=head1 NAME

App::TemplateServer - application to serve processed templates

=head1 SYNOPSIS

   template-server --docroot project/templates --data project/test_data.yml

=head1 DESCRIPTION

Occasionally you need to give HTML templates to someone to edit
without setting up a full perl environment for them.  You can use this
application to serve templates to the browser and provide those
templates with sample data to operate on.  The template editor will
need Perl, but not a database, Apache, Catalyst, etc.  (You can build
a PAR and then they won't need Perl either.)

It's also useful for experimenting with new templating engines.  You
can start writing templates right away, without having to setup Apache
or a Catalyst application first.  Interfacing C<App::TemplateServer>
to a new templating system is a quick matter of writing a few lines of



( run in 0.459 second using v1.01-cache-2.11-cpan-39bf76dae61 )