.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Router::Simple 3pm" .TH Router::Simple 3pm "2011-05-15" "perl v5.14.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Router::Simple \- simple HTTP router .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use Router::Simple; \& \& my $router = Router::Simple\->new(); \& $router\->connect(\*(Aq/\*(Aq, {controller => \*(AqRoot\*(Aq, action => \*(Aqshow\*(Aq}); \& $router\->connect(\*(Aq/blog/{year}/{month}\*(Aq, {controller => \*(AqBlog\*(Aq, action => \*(Aqmonthly\*(Aq}); \& \& my $app = sub { \& my $env = shift; \& if (my $p = $router\->match($env)) { \& # $p = { controller => \*(AqBlog\*(Aq, action => \*(Aqmonthly\*(Aq, ... } \& } else { \& [404, [], [\*(Aqnot found\*(Aq]]; \& } \& }; .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Router::Simple is a simple router class. .PP Its main purpose is to serve as a dispatcher for web applications. .PP Router::Simple can match against \s-1PSGI\s0 \f(CW$env\fR directly, which means it's easy to use with \s-1PSGI\s0 supporting web frameworks. .SH "HOW TO WRITE A ROUTING RULE" .IX Header "HOW TO WRITE A ROUTING RULE" .SS "plain string" .IX Subsection "plain string" .Vb 1 \& $router\->connect( \*(Aq/foo\*(Aq, { controller => \*(AqRoot\*(Aq, action => \*(Aqfoo\*(Aq } ); .Ve .SS ":name notation" .IX Subsection ":name notation" .Vb 4 \& $router\->connect( \*(Aq/wiki/:page\*(Aq, { controller => \*(AqWikiPage\*(Aq, action => \*(Aqshow\*(Aq } ); \& ... \& $router\->match(\*(Aq/wiki/john\*(Aq); \& # => {controller => \*(AqWikiPage\*(Aq, action => \*(Aqshow\*(Aq, page => \*(Aqjohn\*(Aq } .Ve .PP \&':name' notation matches qr{([^/]+)}. .SS "'*' notation" .IX Subsection "'*' notation" .Vb 4 \& $router\->connect( \*(Aq/download/*.*\*(Aq, { controller => \*(AqDownload\*(Aq, action => \*(Aqfile\*(Aq } ); \& ... \& $router\->match(\*(Aq/download/path/to/file.xml\*(Aq); \& # => {controller => \*(AqDownload\*(Aq, action => \*(Aqfile\*(Aq, splat => [\*(Aqpath/to/file\*(Aq, \*(Aqxml\*(Aq] } .Ve .PP \&'*' notation matches qr{(.+)}. You will get the captured argument as an array ref for the special key \f(CW\*(C`splat\*(C'\fR. .SS "'{year}' notation" .IX Subsection "'{year}' notation" .Vb 4 \& $router\->connect( \*(Aq/blog/{year}\*(Aq, { controller => \*(AqBlog\*(Aq, action => \*(Aqyearly\*(Aq } ); \& ... \& $router\->match(\*(Aq/blog/2010\*(Aq); \& # => {controller => \*(AqBlog\*(Aq, action => \*(Aqyearly\*(Aq, year => 2010 } .Ve .PP \&'{year}' notation matches qr{([^/]+)}, and it will be captured. .SS "'{year:[0\-9]+}' notation" .IX Subsection "'{year:[0-9]+}' notation" .Vb 4 \& $router\->connect( \*(Aq/blog/{year:[0\-9]+}/{month:[0\-9]{2}}\*(Aq, { controller => \*(AqBlog\*(Aq, action => \*(Aqmonthly\*(Aq } ); \& ... \& $router\->match(\*(Aq/blog/2010/04\*(Aq); \& # => {controller => \*(AqBlog\*(Aq, action => \*(Aqmonthly\*(Aq, year => 2010, month => \*(Aq04\*(Aq } .Ve .PP You can specify regular expressions in named captures. .SS "regexp" .IX Subsection "regexp" .Vb 4 \& $router\->connect( qr{/blog/(\ed+)/([0\-9]{2})\*(Aq, { controller => \*(AqBlog\*(Aq, action => \*(Aqmonthly\*(Aq } ); \& ... \& $router\->match(\*(Aq/blog/2010/04\*(Aq); \& # => {controller => \*(AqBlog\*(Aq, action => \*(Aqmonthly\*(Aq, splat => [2010, \*(Aq04\*(Aq] } .Ve .PP You can use Perl5's powerful regexp directly, and the captured values are stored in the special key \f(CW\*(C`splat\*(C'\fR. .SH "METHODS" .IX Header "METHODS" .ie n .IP "my $router = Router::Simple\->\fInew()\fR;" 4 .el .IP "my \f(CW$router\fR = Router::Simple\->\fInew()\fR;" 4 .IX Item "my $router = Router::Simple->new();" Creates a new instance of Router::Simple. .ie n .IP "$router\->connect([$name, ] $pattern, \e%destination[, \e%options])" 4 .el .IP "\f(CW$router\fR\->connect([$name, ] \f(CW$pattern\fR, \e%destination[, \e%options])" 4 .IX Item "$router->connect([$name, ] $pattern, %destination[, %options])" Adds a new rule to \f(CW$router\fR. .Sp .Vb 5 \& $router\->connect( \*(Aq/\*(Aq, { controller => \*(AqRoot\*(Aq, action => \*(Aqindex\*(Aq } ); \& $router\->connect( \*(Aqshow_entry\*(Aq, \*(Aq/blog/:id\*(Aq, \& { controller => \*(AqBlog\*(Aq, action => \*(Aqshow\*(Aq } ); \& $router\->connect( \*(Aq/blog/:id\*(Aq, { controller => \*(AqBlog\*(Aq, action => \*(Aqshow\*(Aq } ); \& $router\->connect( \*(Aq/comment\*(Aq, { controller => \*(AqComment\*(Aq, action => \*(Aqnew_comment\*(Aq }, {method => \*(AqPOST\*(Aq} ); .Ve .Sp \&\f(CW\*(C`\e%destination\*(C'\fR will be used by \fImatch\fR method. .Sp You can specify some optional things to \f(CW\*(C`\e%options\*(C'\fR. The current version supports 'method', 'host', and 'on_match'. .RS 4 .IP "method" 4 .IX Item "method" \&'method' is an ArrayRef[String] or String that matches \fB\s-1REQUEST_METHOD\s0\fR in \f(CW$req\fR. .IP "host" 4 .IX Item "host" \&'host' is a String or Regexp that matches \fB\s-1HTTP_HOST\s0\fR in \f(CW$req\fR. .IP "on_match" 4 .IX Item "on_match" .Vb 11 \& $r\->connect( \& \*(Aq/{controller}/{action}/{id}\*(Aq, \& {}, \& { \& on_match => sub { \& my($env, $match) = @_; \& $match\->{referer} = $env\->{HTTP_REFERER}; \& return 1; \& } \& } \& ); .Ve .Sp A function that evaluates the request. Its signature must be \f(CW\*(C`($environ, $match) => bool\*(C'\fR. It should return true if the match is successful or false otherwise. The first arg is \f(CW$env\fR which is either a \s-1PSGI\s0 environment or a request path, depending on what you pass to \f(CW\*(C`match\*(C'\fR method; the second is the routing variables that would be returned if the match succeeds. .Sp The function can modify \f(CW$env\fR (in case it's a reference) and \&\f(CW$match\fR in place to affect which variables are returned. This allows a wide range of transformations. .RE .RS 4 .RE .ie n .IP "$router\->submapper($path, [\e%dest, [\e%opt]])" 4 .el .IP "\f(CW$router\fR\->submapper($path, [\e%dest, [\e%opt]])" 4 .IX Item "$router->submapper($path, [%dest, [%opt]])" .Vb 1 \& $router\->submapper(\*(Aq/entry/\*(Aq, {controller => \*(AqEntry\*(Aq}) .Ve .Sp This method is shorthand for creating new instance of Router::Simple::Submapper. .Sp The arguments will be passed to \f(CW\*(C`Router::Simple::SubMapper\->new(%args)\*(C'\fR. .ie n .IP "$match = $router\->match($env|$path)" 4 .el .IP "\f(CW$match\fR = \f(CW$router\fR\->match($env|$path)" 4 .IX Item "$match = $router->match($env|$path)" Matches a \s-1URL\s0 against one of the contained routes. .Sp The parameter is either a \s-1PSGI\s0 \f(CW$env\fR or a plain string that represents a path. .Sp This method returns a plain hashref that would look like: .Sp .Vb 5 \& { \& controller => \*(AqBlog\*(Aq, \& action => \*(Aqdaily\*(Aq, \& year => 2010, month => \*(Aq03\*(Aq, day => \*(Aq04\*(Aq, \& } .Ve .Sp It returns undef if no valid match is found. .ie n .IP "my ($match, $route) = $router\->routematch($env|$path);" 4 .el .IP "my ($match, \f(CW$route\fR) = \f(CW$router\fR\->routematch($env|$path);" 4 .IX Item "my ($match, $route) = $router->routematch($env|$path);" Match a \s-1URL\s0 against against one of the routes contained. .Sp Will return undef if no valid match is found, otherwise a result hashref and a Router::Simple::Route object is returned. .ie n .IP "$router\->\fIas_string()\fR" 4 .el .IP "\f(CW$router\fR\->\fIas_string()\fR" 4 .IX Item "$router->as_string()" Dumps \f(CW$router\fR as string. .Sp Example output: .Sp .Vb 5 \& home GET / \& blog_monthly GET /blog/{year}/{month} \& GET /blog/{year:\ed{1,4}}/{month:\ed{2}}/{day:\ed\ed} \& POST /comment \& GET / .Ve .SH "AUTHOR" .IX Header "AUTHOR" Tokuhiro Matsuno .SH "THANKS TO" .IX Header "THANKS TO" Tatsuhiko Miyagawa .PP Shawn M Moore .PP routes.py . .SH "SEE ALSO" .IX Header "SEE ALSO" Router::Simple is inspired by routes.py . .PP Path::Dispatcher is similar, but so complex. .PP Path::Router is heavy. It depends on Moose. .PP HTTP::Router has many deps. It is not well documented. .PP HTTPx::Dispatcher is my old one. It does not provide an OOish interface. .SH "THANKS TO" .IX Header "THANKS TO" DeNA .SH "LICENSE" .IX Header "LICENSE" Copyright (C) Tokuhiro Matsuno .PP This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.