Skip to content

Commit

Permalink
added experimental support for unquoted wildcard placeholders in Mojo…
Browse files Browse the repository at this point in the history
…licious::Routes::Pattern
  • Loading branch information
kraih committed Jun 3, 2011
1 parent 1ea0825 commit a54cb81
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 62 deletions.
2 changes: 2 additions & 0 deletions Changes
@@ -1,6 +1,8 @@
This file documents the revision history for Perl extension Mojolicious.

1.42 2011-06-03 00:00:00
- Added EXPERIMENTAL support for unquoted wildcard placeholders in
Mojolicious::Routes::Pattern.
- Improved layout tests.
- Improved documentation.

Expand Down
34 changes: 17 additions & 17 deletions lib/Mojolicious/Guides/Routing.pod
Expand Up @@ -108,9 +108,21 @@ surrounding text.
/sebastian23hello -> /(:name)hello -> {name => 'sebastian23'}
/sebastian 23hello -> /(:name)hello -> {name => 'sebastian 23'}

=head2 Wildcard Placeholders

Wildcard placeholders are just like generic placeholders, but match
absolutely everything.

/hello -> /*name/hello -> undef
/sebastian/23/hello -> /*name/hello -> {name => 'sebastian/23'}
/sebastian.23/hello -> /*name/hello -> {name => 'sebastian.23'}
/sebastian/hello -> /*name/hello -> {name => 'sebastian'}
/sebastian23/hello -> /*name/hello -> {name => 'sebastian23'}
/sebastian 23/hello -> /*name/hello -> {name => 'sebastian 23'}

=head2 Relaxed Placeholders

Relaxed placeholders are very similar to generic placeholders but always
Relaxed placeholders are similar to the two placeholders above, but always
require brackets and match all characters except C</>.

/hello -> /(.name)/hello -> undef
Expand All @@ -120,18 +132,6 @@ require brackets and match all characters except C</>.
/sebastian23/hello -> /(.name)/hello -> {name => 'sebastian23'}
/sebastian 23/hello -> /(.name)/hello -> {name => 'sebastian 23'}

=head2 Wildcard Placeholders

Wildcard placeholders are just like relaxed placeholders but match absolutely
everything.

/hello -> /(*name)/hello -> undef
/sebastian/23/hello -> /(*name)/hello -> {name => 'sebastian/23'}
/sebastian.23/hello -> /(*name)/hello -> {name => 'sebastian.23'}
/sebastian/hello -> /(*name)/hello -> {name => 'sebastian'}
/sebastian23/hello -> /(*name)/hello -> {name => 'sebastian23'}
/sebastian 23/hello -> /(*name)/hello -> {name => 'sebastian 23'}

=head1 BASICS

Most commonly used features every L<Mojolicious> developer should know about.
Expand Down Expand Up @@ -661,7 +661,7 @@ Because the remaining path always gets stored in the C<path> stash value, you
could also just use it directly instead of C<detour>.

# /foo/*
$r->route('/foo/(*path)')->to('bar#', name => 'Mojo');
$r->route('/foo/*path')->to('bar#', name => 'Mojo');

=head2 Application Plugins

Expand Down Expand Up @@ -746,9 +746,9 @@ The C<routes> command can be used from the command line to list all available
routes together with name and underlying regular expressions.

% script/myapp routes
/foo/:name GET fooname (?-xism:^/foo/([^\/\.]+))
/bar/(.test) * bartest (?-xism:^/bar/([^\/]+))
/baz/(*everything) POST bazeverything (?-xism:^/baz/(.+))
/foo/:name GET fooname (?-xism:^/foo/([^\/\.]+))
/baz/*everything POST bazeverything (?-xism:^/baz/(.+))
/bar/(.test) * bartest (?-xism:^/bar/([^\/]+))

=head1 MORE

Expand Down
19 changes: 1 addition & 18 deletions lib/Mojolicious/Lite.pm
Expand Up @@ -363,23 +363,6 @@ C<param>.
$self->render(text => "Our :bar placeholder matched $bar");
};
=head2 Relaxed Placeholders
Relaxed placeholders allow matching of everything until a C</> occurs.
# /*/hello (everything except "/")
# /test/hello
# /test123/hello
# /test.123/hello
get '/(.you)/hello' => sub {
shift->render('groovy');
};
__DATA__
@@ groovy.html.ep
Your name is <%= $you %>.
=head2 Wildcard Placeholders
Wildcard placeholders allow matching absolutely everything, including
Expand All @@ -389,7 +372,7 @@ C</> and C<.>.
# /hello/test
# /hello/test123
# /hello/test.123/test/123
get '/hello/(*you)' => sub {
get '/hello/*you' => sub {
shift->render('groovy');
};
Expand Down
31 changes: 11 additions & 20 deletions lib/Mojolicious/Routes/Pattern.pm
Expand Up @@ -224,28 +224,19 @@ sub _tokenize {
next;
}

# Relaxed start
if ($quoted && $char eq $relaxed_start) {

# Upgrade relaxed to wildcard
if ($state eq 'symbol') {
$state = 'relaxed';
$tree->[-1]->[0] = 'relaxed';
next;
}

# Relaxed start (needs to be quoted)
if ($quoted && $char eq $relaxed_start && $state eq 'symbol') {
$state = 'relaxed';
$tree->[-1]->[0] = 'relaxed';
next;
}

# Wildcard start
if ($quoted && $char eq $wildcard_start) {

# Upgrade relaxed to wildcard
if ($state eq 'symbol') {
$state = 'wildcard';
$tree->[-1]->[0] = 'wildcard';
next;
}

# Wildcard start (upgrade when quoted)
if ($char eq $wildcard_start) {
push @$tree, ['symbol', ''] unless $quoted;
$state = 'wildcard';
$tree->[-1]->[0] = 'wildcard';
next;
}

# Quote end
Expand Down
2 changes: 1 addition & 1 deletion t/mojolicious/embedded_lite_app.t
Expand Up @@ -107,7 +107,7 @@ get('/yada/yada/yada')
get('/basic')->detour(MyTestApp::Basic->new, test => 'lalala');

# /third/* (dispatch to embedded app)
get '/third/(*path)' =>
get '/third/*path' =>
{app => 'MyTestApp::Test2', name => 'third embedded', path => '/'};

# /hello/* (dispatch to embedded app)
Expand Down
14 changes: 13 additions & 1 deletion t/mojolicious/lite_app.t
Expand Up @@ -12,7 +12,7 @@ BEGIN { $ENV{MOJO_NO_IPV6} = $ENV{MOJO_POLL} = 1 }
my $backup;
BEGIN { $backup = $ENV{MOJO_MODE} || ''; $ENV{MOJO_MODE} = 'development' }

use Test::More tests => 787;
use Test::More tests => 792;

# Pollution
123 =~ m/(\d+)/;
Expand Down Expand Up @@ -268,6 +268,12 @@ get '/foo_wildcard/(*test)' => sub {
$self->render_text($self->stash('test'));
};

# GET /foo_wildcard_too/*
get '/foo_wildcard_too/*test' => sub {
my $self = shift;
$self->render_text($self->stash('test'));
};

# GET /with/header/condition
get '/with/header/condition' => (headers => {'X-Secret-Header' => 'bar'}) =>
'with_header_condition';
Expand Down Expand Up @@ -1043,6 +1049,12 @@ $t->get_ok('/foo_wildcard/123')->status_is(200)->content_is('123');
# GET /foo_wildcard
$t->get_ok('/foo_wildcard/')->status_is(404);

# GET /foo_wildcard_too/123
$t->get_ok('/foo_wildcard_too/123')->status_is(200)->content_is('123');

# GET /foo_wildcard_too
$t->get_ok('/foo_wildcard_too/')->status_is(404);

# GET /with/header/condition
$t->get_ok('/with/header/condition', {'X-Secret-Header' => 'bar'})
->status_is(200)->content_like(qr/^Test ok<base href="http:\/\/localhost/);
Expand Down
14 changes: 10 additions & 4 deletions t/mojolicious/pattern.t
Expand Up @@ -3,7 +3,7 @@
use strict;
use warnings;

use Test::More tests => 50;
use Test::More tests => 53;

use Mojo::ByteStream 'b';

Expand Down Expand Up @@ -91,6 +91,12 @@ is $result->{controller}, 'foo', 'right value';
is $result->{action}, 'bar.baz/yada', 'right value';
is $pattern->render({controller => 'foo', action => 'bar.baz/yada'}),
'/test/foo/bar.baz/yada', 'right result';
$pattern = Mojolicious::Routes::Pattern->new('/tset/:controller/*action');
$result = $pattern->match('/tset/foo/bar.baz/yada');
is $result->{controller}, 'foo', 'right value';
is $result->{action}, 'bar.baz/yada', 'right value';
is $pattern->render({controller => 'foo', action => 'bar.baz/yada'}),
'/tset/foo/bar.baz/yada', 'right result';

# Render false value
$pattern = Mojolicious::Routes::Pattern->new('/:id');
Expand All @@ -103,10 +109,10 @@ is $result->{test}, 'test(test)(\Qtest\E)(', 'right value';
is $pattern->render({test => '23'}), '/23', 'right result';

# Regex in pattern
$pattern = Mojolicious::Routes::Pattern->new('/.+.*(:test)');
$result = $pattern->match('/.+.*test');
$pattern = Mojolicious::Routes::Pattern->new('/.+(:test)');
$result = $pattern->match('/.+test');
is $result->{test}, 'test', 'right value';
is $pattern->render({test => '23'}), '/.+.*23', 'right result';
is $pattern->render({test => '23'}), '/.+23', 'right result';

# Unusual values
$pattern = Mojolicious::Routes::Pattern->new('/:test');
Expand Down
14 changes: 13 additions & 1 deletion t/mojolicious/routes.t
Expand Up @@ -3,7 +3,7 @@
use strict;
use warnings;

use Test::More tests => 232;
use Test::More tests => 237;

# "They're not very heavy, but you don't hear me not complaining."
use_ok 'Mojolicious::Routes';
Expand Down Expand Up @@ -69,6 +69,10 @@ $r->route('/wildcards/2/(*wildcard)')
$r->route('/wildcards/3/(*wildcard)/foo')
->to(controller => 'very', action => 'dangerous');

# /wildcards/4/*/foo
$r->route('/wildcards/4/*wildcard/foo')
->to(controller => 'somewhat', action => 'dangerous');

# /format
# /format.html
$r->route('/format')
Expand Down Expand Up @@ -313,6 +317,14 @@ is $m->stack->[0]->{action}, 'dangerous', 'right value';
is $m->stack->[0]->{wildcard}, 'hello/there', 'right value';
is $m->path_for, '/wildcards/3/hello/there/foo', 'right path';
is @{$m->stack}, 1, 'right number of elements';
$m =
Mojolicious::Routes::Match->new(get => '/wildcards/4/hello/there/foo')
->match($r);
is $m->stack->[0]->{controller}, 'somewhat', 'right value';
is $m->stack->[0]->{action}, 'dangerous', 'right value';
is $m->stack->[0]->{wildcard}, 'hello/there', 'right value';
is $m->path_for, '/wildcards/4/hello/there/foo', 'right path';
is @{$m->stack}, 1, 'right number of elements';

# Escaped
$m =
Expand Down

0 comments on commit a54cb81

Please sign in to comment.