Skip to content

Commit

Permalink
improved Mojolicious::Routes to allow redispatching controllers
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Apr 9, 2012
1 parent 436b3fe commit 78f105f
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 25 deletions.
4 changes: 3 additions & 1 deletion Changes
@@ -1,6 +1,8 @@
This file documents the revision history for Perl extension Mojolicious.

2.78 2012-04-10
2.78 2012-04-09
- Improved Mojolicious::Routes to allow redispatching controllers.
- Improved Mojolicious::Routes logging.
- Improved documentation.

2.77 2012-04-09
Expand Down
43 changes: 20 additions & 23 deletions lib/Mojolicious/Routes.pm
Expand Up @@ -115,42 +115,39 @@ sub _dispatch_callback {
sub _dispatch_controller {
my ($self, $c, $field, $staging) = @_;

# Class and method
# Load and instantiate controller/application
return 1
unless my $app = $field->{app} || $self->_generate_class($field, $c);
my $method = $self->_generate_method($field, $c);
my $target = (ref $app || $app) . ($method ? "->$method" : '');
$c->app->log->debug(qq/Routing to "$target"./);

# Controller or application
return unless $self->_load_class($c, $app);
$app = $app->new($c) unless ref $app;

# Action
# Application
my $continue;
if ($method) {
my $class = ref $app;
if (my $sub = $app->can('handler')) {
$c->app->log->debug(qq/Routing to application "$class"./);

# Try to connect routes
if (my $sub = $app->can('routes')) {
my $r = $app->$sub;
weaken $r->parent($c->match->endpoint)->{parent} unless $r->parent;
}
$app->$sub($c);
}

# Action
elsif (my $method = $self->_generate_method($field, $c)) {
$c->app->log->debug(qq/Routing to action "$class->$method"./);

# Call action
# Try to call action
my $stash = $c->stash;
if (my $sub = $app->can($method)) {
$stash->{'mojo.routed'}++ unless $staging;
$continue = $app->$sub;
}

# Render
else {
$c->app->log->debug(
qq/Action "$target" not found, assuming template without action./);
}
}

# Application
else {
if (my $sub = $app->can('routes')) {
my $r = $app->$sub;
weaken $r->parent($c->match->endpoint)->{parent} unless $r->parent;
}
$app->handler($c);
# Action not found
else { $c->app->log->debug('Assuming template without action.') }
}

return !$staging || $continue ? 1 : undef;
Expand Down
24 changes: 23 additions & 1 deletion t/mojolicious/app.t
Expand Up @@ -7,7 +7,7 @@ BEGIN {
$ENV{MOJO_REACTOR} = 'Mojo::Reactor::Poll';
}

use Test::More tests => 294;
use Test::More tests => 314;

use FindBin;
use lib "$FindBin::Bin/lib";
Expand Down Expand Up @@ -331,6 +331,28 @@ $t->get_ok('/foo/routes')->status_is(200)
->header_is('X-Powered-By' => 'Mojolicious (Perl)')
->content_is('/foo/routes');

# SingleFileTestApp::Redispatch::handler
$t->get_ok('/redispatch')->status_is(200)
->header_is(Server => 'Mojolicious (Perl)')
->header_is('X-Powered-By' => 'Mojolicious (Perl)')
->content_is('Redispatch!');

# SingleFileTestApp::Redispatch::render
$t->get_ok('/redispatch/render')->status_is(200)
->header_is(Server => 'Mojolicious (Perl)')
->header_is('X-Powered-By' => 'Mojolicious (Perl)')->content_is('Render!');

# SingleFileTestApp::Redispatch::handler (targeting an existing method)
$t->get_ok('/redispatch/secret')->status_is(200)
->header_is(Server => 'Mojolicious (Perl)')
->header_is('X-Powered-By' => 'Mojolicious (Perl)')
->content_is('Redispatch!');

# SingleFileTestApp::Redispatch::secret
$t->get_ok('/redispatch/secret?rly=1')->status_is(200)
->header_is(Server => 'Mojolicious (Perl)')
->header_is('X-Powered-By' => 'Mojolicious (Perl)')->content_is('Secret!');

$t = Test::Mojo->new('MojoliciousTest');

# MojoliciousTestController::Foo::plugin_upper_case
Expand Down
23 changes: 23 additions & 0 deletions t/mojolicious/lib/SingleFileTestApp.pm
Expand Up @@ -17,6 +17,9 @@ sub startup {
push @{$self->renderer->classes}, 'SingleFileTestApp::Foo';
push @{$self->static->classes}, 'SingleFileTestApp::Foo';

# Allow redispatching controller
push @{$self->routes->base_classes}, 'Mojo::Base';

# Helper route
$self->routes->route('/helper')->to(
cb => sub {
Expand All @@ -29,6 +32,26 @@ sub startup {
$self->routes->route('/:controller/:action')->to(action => 'index');
}

package SingleFileTestApp::Redispatch;
use Mojo::Base -base;

sub handler {
my ($self, $c) = @_;
return secret($c) if $c->param('rly');
return render($c) if $c->stash('action') eq 'render';
$c->render(text => 'Redispatch!');
}

sub render {
my $c = shift;
$c->render(text => 'Render!');
}

sub secret {
my $c = shift;
$c->render(text => 'Secret!');
}

package SingleFileTestApp::Foo;
use Mojo::Base 'Mojolicious::Controller';

Expand Down

0 comments on commit 78f105f

Please sign in to comment.