Skip to content

Instantly share code, notes, and snippets.

@taiyoh
Created April 6, 2013 09:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save taiyoh/5325607 to your computer and use it in GitHub Desktop.
Save taiyoh/5325607 to your computer and use it in GitHub Desktop.
diff --git a/lib/Amon2/Web/Dispatcher/RouterSimple.pm b/lib/Amon2/Web/Dispatcher/RouterSimple.pm
index ecbdb86..44ae635 100644
--- a/lib/Amon2/Web/Dispatcher/RouterSimple.pm
+++ b/lib/Amon2/Web/Dispatcher/RouterSimple.pm
@@ -10,22 +10,55 @@ sub import {
my $router = Router::Simple->new();
- no strict 'refs';
- # functions
- *{"${caller}::connect"} = sub {
+ my $connect = sub {
if (@_ == 2 && !ref $_[1]) {
- my ($path, $dest_str) = @_;
+ my ($path, $dest_str, $opt) = @_;
my ($controller, $action) = split('#', $dest_str);
- my %dest;
- $dest{controller} = $controller;
- $dest{action} = $action if defined $action;
- $router->connect($path, \%dest);
+ my $dest = { controller => $controller };
+ $dest->{action} = $action if defined $action;
+ $router->connect($path, $dest, $opt || {});
} else {
$router->connect(@_);
}
};
+
+ no strict 'refs';
+ # functions
+ *{"${caller}::connect"} = $connect;
+ my @methods = qw/GET POST PUT DELETE/;
+ my %procs;
+ for my $method (@methods) {
+ *{"${caller}::@{[lc $method]}"} = $procs{$method} = sub {
+ $connect->($_[0], $_[1], { method => $method });
+ };
+ }
+
*{"${caller}::submapper"} = sub {
- $router->submapper(@_);
+ if ($_[2] && ref($_[2]) eq 'CODE') {
+ my ($path, $controller, $callback) = @_;
+ my $submap = $router->submapper($path, { controller => $controller });
+ no warnings 'redefine';
+ *{"${caller}::connect"} = sub {
+ if (@_ >= 2 && !ref $_[1]) {
+ my ($path, $action, $opt) = @_;
+ $submap->connect($path, { action => $action }, $opt || {});
+ } else {
+ $submap->connect(@_);
+ }
+ };
+ for my $method (@methods) {
+ *{"${caller}::@{[lc $method]}"} = sub {
+ my ($path, $action) = @_;
+ $submap->connect($path, { action => $action }, { metod => $method });
+ };
+ }
+ $callback->();
+ *{"${caller}::connect"} = $connect;
+ *{"${caller}::@{[ lc $_ ]}"} = $procs{$_} for (@methods);
+ }
+ else {
+ $router->submapper(@_);
+ }
};
# class methods
*{"${caller}::router"} = sub { $router };
diff --git a/t/800_dispatcher/002_router_simple.t b/t/800_dispatcher/002_router_simple.t
index 3238562..1d80cd0 100644
--- a/t/800_dispatcher/002_router_simple.t
+++ b/t/800_dispatcher/002_router_simple.t
@@ -36,6 +36,8 @@ use Test::Requires 'Test::WWW::Mechanize::PSGI';
use warnings;
sub login { $_[1]->create_response(200, [], 'login') }
+ sub logout { $_[1]->create_response(200, [], 'logout') }
+
package MyApp::Web::Dispatcher;
use Amon2::Web::Dispatcher::RouterSimple;
@@ -47,6 +49,10 @@ use Test::Requires 'Test::WWW::Mechanize::PSGI';
connect '/blog/{year}/{month}', {controller => 'Blog', action => 'monthly'};
submapper('/account/', {controller => 'Account'})
->connect('login', {action => 'login'});
+
+ submapper '/account', 'Account', sub {
+ get '/logout', 'logout';
+ };
}
my $app = MyApp::Web->to_app();
@@ -62,6 +68,8 @@ $mech->get_ok('/blog/2010/04');
$mech->content_is("blog: 2010, 04");
$mech->get_ok('/account/login');
$mech->content_is("login");
+$mech->get_ok('/account/logout');
+$mech->content_is("logout");
done_testing;
package Amon2::Web::Dispatcher::RouterSimple;
use strict;
use warnings;
use Router::Simple 0.03;
sub import {
my $class = shift;
my %args = @_;
my $caller = caller(0);
my $router = Router::Simple->new();
my $connect = sub {
if (@_ == 2 && !ref $_[1]) {
my ($path, $dest_str, $opt) = @_;
my ($controller, $action) = split('#', $dest_str);
my $dest = { controller => $controller };
$dest->{action} = $action if defined $action;
$router->connect($path, $dest, $opt || {});
} else {
$router->connect(@_);
}
};
no strict 'refs';
# functions
*{"${caller}::connect"} = $connect;
my @methods = qw/GET POST PUT DELETE/;
my %procs;
for my $method (@methods) {
*{"${caller}::@{[lc $method]}"} = $procs{$method} = sub {
$connect->($_[0], $_[1], { method => $method });
};
}
*{"${caller}::submapper"} = sub {
if ($_[2] && ref($_[2]) eq 'CODE') {
my ($path, $controller, $callback) = @_;
my $submap = $router->submapper($path, { controller => $controller });
no warnings 'redefine';
*{"${caller}::connect"} = sub {
if (@_ >= 2 && !ref $_[1]) {
my ($path, $action, $opt) = @_;
$submap->connect($path, { action => $action }, $opt || {});
} else {
$submap->connect(@_);
}
};
for my $method (@methods) {
*{"${caller}::@{[lc $method]}"} = sub {
my ($path, $action) = @_;
$submap->connect($path, { action => $action }, { metod => $method });
};
}
$callback->();
*{"${caller}::connect"} = $connect;
*{"${caller}::@{[ lc $_ ]}"} = $procs{$_} for (@methods);
}
else {
$router->submapper(@_);
}
};
# class methods
*{"${caller}::router"} = sub { $router };
for my $meth (qw/match as_string/) {
*{"$caller\::${meth}"} = sub {
my $self = shift;
$router->$meth(@_)
};
}
*{"$caller\::dispatch"} = \&_dispatch;
}
sub _dispatch {
my ($class, $c) = @_;
my $req = $c->request;
if (my $p = $class->match($req->env)) {
my $action = $p->{action};
$c->{args} = $p;
"@{[ ref Amon2->context ]}::C::$p->{controller}"->$action($c, $p);
} else {
$c->res_404();
}
}
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment