Skip to content

Commit

Permalink
another format detection example
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Apr 15, 2012
1 parent f18ba44 commit 2b1abd4
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 84 deletions.
5 changes: 1 addition & 4 deletions lib/Mojolicious/Commands.pm
Expand Up @@ -131,10 +131,7 @@ sub start_app {

sub _command {
my $module = shift;
if (my $e = Mojo::Loader->load($module)) {
return unless ref $e;
die $e;
}
if (my $e = Mojo::Loader->load($module)) { return ref $e ? die $e : undef }
return $module->isa('Mojo::Command') ? $module : undef;
}

Expand Down
4 changes: 2 additions & 2 deletions lib/Mojolicious/Guides/Routing.pod
Expand Up @@ -417,8 +417,8 @@ Restrictive placeholders can also be used for format detection.
$r->route('/foo', format => ['rss', 'xml'])
->to(controller => 'foo', action => 'feed');

Or you can just disable format detection, which gets inherited by nested routes
and allows re-enabling detection selectively.
Or you can just disable format detection, which gets inherited by nested
routes and allows re-enabling detection selectively.

# /foo -> {controller => 'foo', action => 'none'}
# /foo.html -> undef
Expand Down
135 changes: 75 additions & 60 deletions lib/Mojolicious/Lite.pm
Expand Up @@ -456,66 +456,6 @@ Just make sure not to use C<^> and C<$> or capturing groups C<(...)>, because
placeholders become part of a larger regular expression internally,
C<(?:...)> is fine though.
=head2 Formats
Formats can be automatically detected by looking at file extensions.
# /detection.html
# /detection.txt
get '/detection' => sub {
my $self = shift;
$self->render('detected');
};
__DATA__
@@ detected.html.ep
<!DOCTYPE html>
<html>
<head><title>Detected</title></head>
<body>HTML was detected.</body>
</html>
@@ detected.txt.ep
TXT was detected.
Restrictive placeholders can also be used for format detection.
# /hello.json
# /hello.txt
get '/hello' => [format => ['json', 'txt']] => sub {
my $self = shift;
return $self->render_json({hello => 'world'})
if $self->stash('format') eq 'json';
$self->render_text('hello world');
};
=head2 Content negotiation
For resources with different representations and that require truly
C<RESTful> content negotiation you can also use
L<Mojolicious::Controller/"respond_to">.
# /hello (Accept: application/json)
# /hello (Accept: text/xml)
# /hello.json
# /hello.xml
# /hello?format=json
# /hello?format=xml
get '/hello' => sub {
my $self = shift;
$self->respond_to(
json => {json => {hello => 'world'}},
xml => {text => '<hello>world</hello>'},
any => {data => '', status => 204}
);
};
MIME type mappings can be extended or changed easily with
L<Mojolicious/"types">.
app->types->type(rdf => 'application/rdf+xml');
=head2 Under
Authentication and code shared between multiple routes can be realized easily
Expand Down Expand Up @@ -603,6 +543,81 @@ C<under> statements.
app->start;
=head2 Formats
Formats can be automatically detected by looking at file extensions.
# /detection.html
# /detection.txt
get '/detection' => sub {
my $self = shift;
$self->render('detected');
};
__DATA__
@@ detected.html.ep
<!DOCTYPE html>
<html>
<head><title>Detected</title></head>
<body>HTML was detected.</body>
</html>
@@ detected.txt.ep
TXT was detected.
Restrictive placeholders can also be used for format detection.
# /hello.json
# /hello.txt
get '/hello' => [format => ['json', 'txt']] => sub {
my $self = shift;
return $self->render_json({hello => 'world'})
if $self->stash('format') eq 'json';
$self->render_text('hello world');
};
Or you can just disable format detection.
# /hello
get '/hello' => [format => 0] => {text => 'No format.'};
# Disable format detection for the following routes
under [format => 0];
# /foo
get '/foo' => {text => 'No format again.'};
# /bar.txt
# /bar.html
get '/bar' => [format => ['txt', 'html']] => {text => 'Two formats.'};
=head2 Content negotiation
For resources with different representations and that require truly
C<RESTful> content negotiation you can also use
L<Mojolicious::Controller/"respond_to">.
# /hello (Accept: application/json)
# /hello (Accept: text/xml)
# /hello.json
# /hello.xml
# /hello?format=json
# /hello?format=xml
get '/hello' => sub {
my $self = shift;
$self->respond_to(
json => {json => {hello => 'world'}},
xml => {text => '<hello>world</hello>'},
any => {data => '', status => 204}
);
};
MIME type mappings can be extended or changed easily with
L<Mojolicious/"types">.
app->types->type(rdf => 'application/rdf+xml');
=head2 Conditions
Conditions such as C<agent> and C<host> from
Expand Down
29 changes: 11 additions & 18 deletions lib/Mojolicious/Routes/Route.pm
Expand Up @@ -55,10 +55,8 @@ sub find {
while (my $child = shift @children) {

# Match
if ($child->name eq $name) {
$candidate = $child;
return $candidate if $child->has_custom_name;
}
$candidate = $child->has_custom_name ? return $child : $child
if $child->name eq $name;

# Search children too
push @children, @{$child->children};
Expand Down Expand Up @@ -87,9 +85,8 @@ sub has_websocket {

sub is_endpoint {
my $self = shift;
return if $self->inline;
return 1 if $self->block;
return !@{$self->children};
return if $self->inline;
return $self->block ? 1 : !@{$self->children};
}

sub is_websocket { shift->{websocket} }
Expand Down Expand Up @@ -124,9 +121,8 @@ sub over {

sub parse {
my $self = shift;
my $name = $self->pattern->parse(@_)->pattern // '';
$name =~ s/\W+//g;
$self->{name} = $name;
$self->{name} = $self->pattern->parse(@_)->pattern // '';
$self->{name} =~ s/\W+//g;
return $self;
}

Expand All @@ -139,16 +135,15 @@ sub render {

# Path prefix
my $prefix = $self->pattern->render($values);
$path = $prefix . $path unless $prefix eq '/';
$path = "$prefix$path" unless $prefix eq '/';

# Make sure there is always a root
my $parent = $self->parent;
$path = '/' if !$path && !$parent;

# Format
if ((my $format = $values->{format}) && !$parent) {
$path .= ".$format" unless $path =~ m#\.[^/]+$#;
}
$path .= ".$values->{format}"
if $values->{format} && !$parent && $path !~ m#\.[^/]+$#;

return $parent ? $parent->render($path, $values) : $path;
}
Expand All @@ -160,10 +155,8 @@ sub root {
}

sub route {
my $self = shift;
my $route = $self->new(@_);
$self->add_child($route);
return $route;
my $self = shift;
return $self->add_child($self->new(@_))->children->[-1];
}

sub to {
Expand Down

0 comments on commit 2b1abd4

Please sign in to comment.