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 )