Mojolicious
view release on metacpan or search on metacpan
lib/Mojolicious/Guides/Routing.pod view on Meta::CPAN
=head2 Catch-all route
Since routes match in the order in which they were defined, you can catch all requests that did not match in your last
route with an optional wildcard placeholder.
# * /*
$r->any('/*whatever' => {whatever => ''} => sub ($c) {
my $whatever = $c->param('whatever');
$c->render(text => "/$whatever did not match.", status => 404);
});
=head2 Conditions
Conditions such as C<headers>, C<agent> and C<host> from L<Mojolicious::Plugin::HeaderCondition> can be applied to any
route with the method L<Mojolicious::Routes::Route/"requires">, and allow even more powerful route constructs.
# / (Origin: http://perl.org)
$r->get('/')->requires(headers => {Origin => qr/perl\.org/})->to('foo#bar');
# / (Firefox)
$r->get('/')->requires(agent => qr/Firefox/)->to('browser-test#firefox');
# / (Internet Explorer)
$r->get('/')->requires(agent => qr/Internet Explorer/)->to('browser-test#ie');
# http://docs.mojolicious.org/Mojolicious
$r->get('/')->requires(host => 'docs.mojolicious.org')->to('perldoc#index');
Just be aware that conditions are too complex for the routing cache, which normally speeds up recurring requests, and
can therefore reduce performance.
=head2 Hooks
Hooks operate outside the routing system and allow you to extend the framework itself by sharing code with all requests
indiscriminately through L<Mojolicious/"hook">, which makes them a very powerful tool especially for plugins.
# Application
package MyApp;
use Mojo::Base 'Mojolicious', -signatures;
sub startup ($self) {
# Check all requests for a "/test" prefix
$self->hook(before_dispatch => sub ($c) {
$c->render(text => 'This request did not reach the router.') if $c->req->url->path->contains('/test');
});
# These will not be reached if the hook above renders a response
my $r = $self->routes;
$r->get('/welcome')->to('foo#welcome');
$r->post('/bye')->to('foo#bye');
}
1;
Post-processing the response to add or remove headers is a very common use.
# Make sure static files are cached
$app->hook(after_static => sub ($c) {
$c->res->headers->cache_control('max-age=3600, must-revalidate');
});
# Remove a default header
$app->hook(after_dispatch => sub ($c) {
$c->res->headers->remove('Server');
});
Same for pre-processing the request.
# Choose template variant based on request headers
$app->hook(before_dispatch => sub ($c) {
return unless my $agent = $c->req->headers->user_agent;
$c->stash(variant => 'ie') if $agent =~ /Internet Explorer/;
});
Or more advanced extensions to add monitoring to your application.
# Forward exceptions to a web service
$app->hook(after_dispatch => sub ($c) {
return unless my $e = $c->stash('exception');
$c->ua->post('https://example.com/bugs' => form => {exception => $e});
});
You can even extend much of the core functionality.
# Make controller object available to actions as $_
$app->hook(around_action => sub ($next, $c, $action, $last) {
local $_ = $c;
return $next->();
});
# Pass route name as argument to actions
$app->hook(around_action => sub ($next, $c, $action, $last) {
return $c->$action($c->current_route);
});
For a full list of available hooks see L<Mojolicious/"HOOKS">.
=head1 ADVANCED
Less commonly used and more powerful features.
=head2 Shortcuts
To make route generation more expressive, you can also add your own shortcuts with
L<Mojolicious::Routes/"add_shortcut">.
# Simple "resource" shortcut
$r->add_shortcut(resource => sub ($r, $name) {
# Prefix for resource
my $resource = $r->any("/$name")->to("$name#");
# Render a list of resources
$resource->get('/')->to('#index')->name($name);
# Render a form to create a new resource (submitted to "store")
$resource->get('/create')->to('#create')->name("create_$name");
# Store newly created resource (submitted by "create")
( run in 2.595 seconds using v1.01-cache-2.11-cpan-5837b0d9d2c )