NAME
URI::Dispatch - determine which code to execute based upon path
SYNOPSIS
my $dispatch = URI::Dispatch->new();
$dispatch->add( '/', 'homepage' );
# common matching patterns are available
$dispatch->add( '/user/#id', 'profile' );
# optional parts of the path
$dispatch->add( '/article/#id[/#slug]', 'article' );
# named captures
$dispatch->add( '/tag/#name:slug', 'tag' );
# use a custom regexp
$dispatch->add( '/a-z/#letter:([a-z])', 'az-page' );
# pass in a path and determine what matches
my( $handler, $options)
= $dispatch->handler( '/article/5/awesome-article' );
# handler='article', options=['5','awesome-article']
# construct paths
my $uri = $dispatch->url( 'article', [ '1', 'some-article' ] );
# uri='/article/1/some-article'
METHODS
add( path, handler )
Add path that can be handled by handler. The path string is a literal string, with special markers.
- captures
-
To capture part of the path for later use, mark it with a hash (#) and the capture type. Builtin types are:
- id
-
matches digits
- hex
-
matches digits and the letters a, b, c, d, e, and f case insensitively
- slug
-
matches lowercase letters, digits and hyphens
- year
-
matches four digits
- month
-
matches numbers 01 through 12
- day
-
matches numbers 01 through 31
- *
-
matches anything
- (regexp)
-
matches a custom regular expression
- named captures
-
Rather than relying on the order of the captures, they can be named. The name goes immediately after the hash (#), is formed of "word" characters (alphanumeric plus underscore) and is followed by a colon and then the capture type. Some examples:
#id:id
#title:slug
#letter:([a-z])
- optional segments
-
To mark part of the path as optional, surround it with square brackets. Optional segments cannot be nested.
Limitations
Adding a new path with the same handler will overwrite the previous path.
Different handlers having the same path will result in unpredictable behaviour.
handler( path )
Determine which handler should be used for the given path.
Returns the handler string, and either an array of the captured elements, or a hash if the captures were named. For example, this code:
$dispatch->add( '/article/#key:id/#title:slug', 'article' );
my( $handler, $captures )
= $dispatch->handler( '/article/5/awesome-article' );
will return a data structure equivalent to:
$captures = {
key => '5',
title => 'awesome-article',
};
url( handler, $arguments )
Build a path that handler would accept. If the path contains captures, you can pass them as an arrayref (or hashref if they are named captures).
The $arguments are tested to ensure they would match. If they would not, an Ouch exception is thrown. This can be caught in your code like so:
use Ouch qw( :traditional );
...
$dispatch->add( '/list/#letter:([a-z])', 'az-page' );
try { $url = $dispatch->url( 'az-page', 'too big' ); };
if ( catch 'wrong_input' ) {
# handle errors
}
EXCEPTIONS
- cannot_mix
-
Named and positional captures cannot be mixed. An attempt to do so will throw this exception.
- unmatched_brackets
-
Thrown if the opening and closing square brackets representing optional segments of a path do not match up.
- wrong_input
-
A provided argument when calling url() will not match the relevant capture type.
- args_short
-
Not enough arguments are provided when calling url().
- args_wrong
-
The wrong type of arguments (arrayref versus hashref) were provided when calling url().
- no_param
-
An unknown builtin parameter type was requested.
AUTHOR
Mark Norman Francis, norm@cackhanded.net.
COPYRIGHT AND LICENSE
Copyright 2011 Mark Norman Francis.
This program is free software, you can redistribute it and/or modify it under the terms of the Artistic License version 2.0.