forked from simoncozens/kirin
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathMicroMaypole.pm
93 lines (80 loc) · 2.7 KB
/
MicroMaypole.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package MicroMaypole;
use Template;
use Plack::App::File;
use Plack::Request;
use Plack::Response;
use strict;
use warnings;
sub app {
my ($self, %args) = @_;
if (!$args{model_prefix}) { die "You didn't pass a model prefix!" }
my $t = Template->new({
INCLUDE_PATH => $args{template_path} || "templates",
PRE_PROCESS => "header",
POST_PROCESS => "footer",
COMPILE_DIR => $args{compiled_templates},
COMPILE_EXT => ".ttc"
});
sub {
my $env = shift;
my $req = Plack::Request->new($env);
# Fake static middleware because it won't let us have multiple
# paths
if ($req->path =~ /^\/static/) {
for (@{ref($args{template_path}) ? $args{template_path} : [$args{template_path}]}) {
next unless -f "$_/".$req->path;
my $file = Plack::App::File->new({ root => $_ });
return $file->call({ %$env, PATH_INFO => $env->{PATH_INFO} });
}
return [404, ['Content-Type' => 'text/plain'], ['not found']];
}
my $m = $self->new(%args);
$m->{template_engine} = $t;
$m->handler($req)->finalize;
}
}
sub new { my $self = shift; return bless {@_} , $self }
sub authenticate {}
sub do404 {
my $res = shift->respond("404handler");
$res->status(404);
$res;
}
sub default_nounverb {}
sub handler {
my ($self, $req) = @_;
$self->{req} = $req;
if (my $resp = $self->authenticate()) { return $resp }
my $path = $req->path; $path =~ s/^\/+//; $req->path($path);
my ($noun, $verb, @args) = split /\//, $path;
if (!$noun) { ($noun, $verb) = $self->default_nounverb }
$self->{req}{noun} = $noun;
$self->{req}{verb} = $verb;
# Convert "noun" to model prefix
$req->{template} = "$noun/$verb";
$noun =~ s/_(\w)/\U$1/g; my $class = $self->{model_prefix}."::".ucfirst($noun);
# Does this class even exist?
if (!$class->isa("UNIVERSAL")) { return $self->do404(); }
if ($verb =~ /^_/) { return $self->do404(); } # No you don't
if (!$class->can($verb)) {
warn "Can't call method $verb on class $class" ;
return $self->do404();
}
$class->$verb($self, @args);
}
sub additional_args {}
sub param { my ($self, $name) = @_; $self->{req}->parameters->{$name}; }
sub respond {
my ($self, $template, @args) = @_;
my $out;
$template ||= $self->{req}->{template};
my $res = Plack::Response->new(200);
$res->content_type("text/html");
$self->{template_engine}->process($template, {
self => $self,
@args,
$self->additional_args()
}, \$out) ? $res->body($out) : $res->body(die $self->{template_engine}->error);
return $res;
}
1;