1 | package Mojolicious::Routes::Route;
|
---|
2 | use Mojo::Base -base;
|
---|
3 |
|
---|
4 | use Carp ();
|
---|
5 | use Mojo::Util;
|
---|
6 | use Mojolicious::Routes::Pattern;
|
---|
7 | use Scalar::Util ();
|
---|
8 |
|
---|
9 | has [qw(inline parent partial)];
|
---|
10 | has 'children' => sub { [] };
|
---|
11 | has pattern => sub { Mojolicious::Routes::Pattern->new };
|
---|
12 |
|
---|
13 | sub AUTOLOAD {
|
---|
14 | my $self = shift;
|
---|
15 |
|
---|
16 | my ($package, $method) = our $AUTOLOAD =~ /^(.+)::(.+)$/;
|
---|
17 | Carp::croak "Undefined subroutine &${package}::$method called"
|
---|
18 | unless Scalar::Util::blessed $self && $self->isa(__PACKAGE__);
|
---|
19 |
|
---|
20 | # Call shortcut with current route
|
---|
21 | Carp::croak qq{Can't locate object method "$method" via package "$package"}
|
---|
22 | unless my $shortcut = $self->root->shortcuts->{$method};
|
---|
23 | return $self->$shortcut(@_);
|
---|
24 | }
|
---|
25 |
|
---|
26 | sub add_child {
|
---|
27 | my ($self, $route) = @_;
|
---|
28 | Scalar::Util::weaken $route->remove->parent($self)->{parent};
|
---|
29 | push @{$self->children}, $route;
|
---|
30 | $route->pattern->types($self->root->types);
|
---|
31 | return $self;
|
---|
32 | }
|
---|
33 |
|
---|
34 | sub any { shift->_generate_route(ref $_[0] eq 'ARRAY' ? shift : [], @_) }
|
---|
35 |
|
---|
36 | sub delete { shift->_generate_route(DELETE => @_) }
|
---|
37 |
|
---|
38 | sub detour { shift->partial(1)->to(@_) }
|
---|
39 |
|
---|
40 | sub find { shift->_index->{shift()} }
|
---|
41 |
|
---|
42 | sub get { shift->_generate_route(GET => @_) }
|
---|
43 |
|
---|
44 | sub has_custom_name { !!shift->{custom} }
|
---|
45 |
|
---|
46 | sub has_websocket {
|
---|
47 | my $self = shift;
|
---|
48 | return $self->{has_websocket} if exists $self->{has_websocket};
|
---|
49 | return $self->{has_websocket} = grep { $_->is_websocket } @{$self->_chain};
|
---|
50 | }
|
---|
51 |
|
---|
52 | sub is_endpoint { $_[0]->inline ? undef : !@{$_[0]->children} }
|
---|
53 |
|
---|
54 | sub is_websocket { !!shift->{websocket} }
|
---|
55 |
|
---|
56 | sub name {
|
---|
57 | my $self = shift;
|
---|
58 | return $self->{name} unless @_;
|
---|
59 | @$self{qw(name custom)} = (shift, 1);
|
---|
60 | return $self;
|
---|
61 | }
|
---|
62 |
|
---|
63 | sub options { shift->_generate_route(OPTIONS => @_) }
|
---|
64 |
|
---|
65 | sub over {
|
---|
66 | my $self = shift;
|
---|
67 |
|
---|
68 | # Routes with conditions can't be cached
|
---|
69 | return $self->{over} unless @_;
|
---|
70 | my $conditions = ref $_[0] eq 'ARRAY' ? $_[0] : [@_];
|
---|
71 | return $self unless @$conditions;
|
---|
72 | $self->{over} = $conditions;
|
---|
73 | $self->root->cache->max_keys(0);
|
---|
74 |
|
---|
75 | return $self;
|
---|
76 | }
|
---|
77 |
|
---|
78 | sub parse {
|
---|
79 | my $self = shift;
|
---|
80 | $self->{name} = $self->pattern->parse(@_)->unparsed // '';
|
---|
81 | $self->{name} =~ s/\W+//g;
|
---|
82 | return $self;
|
---|
83 | }
|
---|
84 |
|
---|
85 | sub patch { shift->_generate_route(PATCH => @_) }
|
---|
86 | sub post { shift->_generate_route(POST => @_) }
|
---|
87 | sub put { shift->_generate_route(PUT => @_) }
|
---|
88 |
|
---|
89 | sub remove {
|
---|
90 | my $self = shift;
|
---|
91 | return $self unless my $parent = $self->parent;
|
---|
92 | @{$parent->children} = grep { $_ ne $self } @{$parent->children};
|
---|
93 | return $self->parent(undef);
|
---|
94 | }
|
---|
95 |
|
---|
96 | sub render {
|
---|
97 | my ($self, $values) = @_;
|
---|
98 | my $path = join '',
|
---|
99 | map { $_->pattern->render($values, !@{$_->children} && !$_->partial) }
|
---|
100 | @{$self->_chain};
|
---|
101 | return $path || '/';
|
---|
102 | }
|
---|
103 |
|
---|
104 | sub root { shift->_chain->[0] }
|
---|
105 |
|
---|
106 | sub route {
|
---|
107 | my $self = shift;
|
---|
108 | my $route = $self->add_child(__PACKAGE__->new->parse(@_))->children->[-1];
|
---|
109 | my $format = $self->pattern->constraints->{format};
|
---|
110 | $route->pattern->constraints->{format} //= 0 if defined $format && !$format;
|
---|
111 | return $route;
|
---|
112 | }
|
---|
113 |
|
---|
114 | sub suggested_method {
|
---|
115 | my $self = shift;
|
---|
116 |
|
---|
117 | my %via;
|
---|
118 | for my $route (@{$self->_chain}) {
|
---|
119 | next unless my @via = @{$route->via || []};
|
---|
120 | %via = map { $_ => 1 } keys %via ? grep { $via{$_} } @via : @via;
|
---|
121 | }
|
---|
122 |
|
---|
123 | return 'POST' if $via{POST} && !$via{GET};
|
---|
124 | return $via{GET} ? 'GET' : (sort keys %via)[0] || 'GET';
|
---|
125 | }
|
---|
126 |
|
---|
127 | sub to {
|
---|
128 | my $self = shift;
|
---|
129 |
|
---|
130 | my $pattern = $self->pattern;
|
---|
131 | return $pattern->defaults unless @_;
|
---|
132 | my ($shortcut, %defaults) = Mojo::Util::_options(@_);
|
---|
133 |
|
---|
134 | if ($shortcut) {
|
---|
135 |
|
---|
136 | # Application
|
---|
137 | if (ref $shortcut || $shortcut =~ /^[\w:]+$/) {
|
---|
138 | $defaults{app} = $shortcut;
|
---|
139 | }
|
---|
140 |
|
---|
141 | # Controller and action
|
---|
142 | elsif ($shortcut =~ /^([\w\-:]+)?\#(\w+)?$/) {
|
---|
143 | $defaults{controller} = $1 if defined $1;
|
---|
144 | $defaults{action} = $2 if defined $2;
|
---|
145 | }
|
---|
146 | }
|
---|
147 |
|
---|
148 | @{$pattern->defaults}{keys %defaults} = values %defaults;
|
---|
149 |
|
---|
150 | return $self;
|
---|
151 | }
|
---|
152 |
|
---|
153 | sub to_string {
|
---|
154 | join '', map { $_->pattern->unparsed // '' } @{shift->_chain};
|
---|
155 | }
|
---|
156 |
|
---|
157 | sub under { shift->_generate_route(under => @_) }
|
---|
158 |
|
---|
159 | sub via {
|
---|
160 | my $self = shift;
|
---|
161 | return $self->{via} unless @_;
|
---|
162 | my $methods = [map uc($_), @{ref $_[0] ? $_[0] : [@_]}];
|
---|
163 | $self->{via} = $methods if @$methods;
|
---|
164 | return $self;
|
---|
165 | }
|
---|
166 |
|
---|
167 | sub websocket {
|
---|
168 | my $route = shift->get(@_);
|
---|
169 | $route->{websocket} = 1;
|
---|
170 | return $route;
|
---|
171 | }
|
---|
172 |
|
---|
173 | sub _chain {
|
---|
174 | my @chain = (my $parent = shift);
|
---|
175 | unshift @chain, $parent while $parent = $parent->parent;
|
---|
176 | return \@chain;
|
---|
177 | }
|
---|
178 |
|
---|
179 | sub _generate_route {
|
---|
180 | my ($self, $methods, @args) = @_;
|
---|
181 |
|
---|
182 | my (@conditions, @constraints, %defaults, $name, $pattern);
|
---|
183 | while (defined(my $arg = shift @args)) {
|
---|
184 |
|
---|
185 | # First scalar is the pattern
|
---|
186 | if (!ref $arg && !$pattern) { $pattern = $arg }
|
---|
187 |
|
---|
188 | # Scalar
|
---|
189 | elsif (!ref $arg && @args) { push @conditions, $arg, shift @args }
|
---|
190 |
|
---|
191 | # Last scalar is the route name
|
---|
192 | elsif (!ref $arg) { $name = $arg }
|
---|
193 |
|
---|
194 | # Callback
|
---|
195 | elsif (ref $arg eq 'CODE') { $defaults{cb} = $arg }
|
---|
196 |
|
---|
197 | # Constraints
|
---|
198 | elsif (ref $arg eq 'ARRAY') { push @constraints, @$arg }
|
---|
199 |
|
---|
200 | # Defaults
|
---|
201 | elsif (ref $arg eq 'HASH') { %defaults = (%defaults, %$arg) }
|
---|
202 | }
|
---|
203 |
|
---|
204 | my $route
|
---|
205 | = $self->route($pattern, @constraints)->over(\@conditions)->to(\%defaults);
|
---|
206 | $methods eq 'under' ? $route->inline(1) : $route->via($methods);
|
---|
207 |
|
---|
208 | return defined $name ? $route->name($name) : $route;
|
---|
209 | }
|
---|
210 |
|
---|
211 | sub _index {
|
---|
212 | my $self = shift;
|
---|
213 |
|
---|
214 | my (%auto, %custom);
|
---|
215 | my @children = (@{$self->children});
|
---|
216 | while (my $child = shift @children) {
|
---|
217 | if ($child->has_custom_name) { $custom{$child->name} ||= $child }
|
---|
218 | else { $auto{$child->name} ||= $child }
|
---|
219 | push @children, @{$child->children};
|
---|
220 | }
|
---|
221 |
|
---|
222 | return {%auto, %custom};
|
---|
223 | }
|
---|
224 |
|
---|
225 | 1;
|
---|
226 |
|
---|
227 | =encoding utf8
|
---|
228 |
|
---|
229 | =head1 NAME
|
---|
230 |
|
---|
231 | Mojolicious::Routes::Route - Route
|
---|
232 |
|
---|
233 | =head1 SYNOPSIS
|
---|
234 |
|
---|
235 | use Mojolicious::Routes::Route;
|
---|
236 |
|
---|
237 | my $r = Mojolicious::Routes::Route->new;
|
---|
238 |
|
---|
239 | =head1 DESCRIPTION
|
---|
240 |
|
---|
241 | L<Mojolicious::Routes::Route> is the route container used by
|
---|
242 | L<Mojolicious::Routes>.
|
---|
243 |
|
---|
244 | =head1 ATTRIBUTES
|
---|
245 |
|
---|
246 | L<Mojolicious::Routes::Route> implements the following attributes.
|
---|
247 |
|
---|
248 | =head2 children
|
---|
249 |
|
---|
250 | my $children = $r->children;
|
---|
251 | $r = $r->children([Mojolicious::Routes::Route->new]);
|
---|
252 |
|
---|
253 | The children of this route, used for nesting routes.
|
---|
254 |
|
---|
255 | =head2 inline
|
---|
256 |
|
---|
257 | my $bool = $r->inline;
|
---|
258 | $r = $r->inline($bool);
|
---|
259 |
|
---|
260 | Allow L</"under"> semantics for this route.
|
---|
261 |
|
---|
262 | =head2 parent
|
---|
263 |
|
---|
264 | my $parent = $r->parent;
|
---|
265 | $r = $r->parent(Mojolicious::Routes::Route->new);
|
---|
266 |
|
---|
267 | The parent of this route, usually a L<Mojolicious::Routes::Route> object.
|
---|
268 |
|
---|
269 | =head2 partial
|
---|
270 |
|
---|
271 | my $bool = $r->partial;
|
---|
272 | $r = $r->partial($bool);
|
---|
273 |
|
---|
274 | Route has no specific end, remaining characters will be captured in C<path>.
|
---|
275 |
|
---|
276 | =head2 pattern
|
---|
277 |
|
---|
278 | my $pattern = $r->pattern;
|
---|
279 | $r = $r->pattern(Mojolicious::Routes::Pattern->new);
|
---|
280 |
|
---|
281 | Pattern for this route, defaults to a L<Mojolicious::Routes::Pattern> object.
|
---|
282 |
|
---|
283 | =head1 METHODS
|
---|
284 |
|
---|
285 | L<Mojolicious::Routes::Route> inherits all methods from L<Mojo::Base> and
|
---|
286 | implements the following new ones.
|
---|
287 |
|
---|
288 | =head2 add_child
|
---|
289 |
|
---|
290 | $r = $r->add_child(Mojolicious::Routes::Route->new);
|
---|
291 |
|
---|
292 | Add a child to this route, it will be automatically removed from its current
|
---|
293 | parent if necessary.
|
---|
294 |
|
---|
295 | # Reattach route
|
---|
296 | $r->add_child($r->find('foo'));
|
---|
297 |
|
---|
298 | =head2 any
|
---|
299 |
|
---|
300 | my $route = $r->any;
|
---|
301 | my $route = $r->any('/:foo');
|
---|
302 | my $route = $r->any('/:foo' => sub {...});
|
---|
303 | my $route = $r->any('/:foo' => sub {...} => 'name');
|
---|
304 | my $route = $r->any('/:foo' => {foo => 'bar'} => sub {...});
|
---|
305 | my $route = $r->any('/:foo' => [foo => qr/\w+/] => sub {...});
|
---|
306 | my $route = $r->any('/:foo' => (agent => qr/Firefox/) => sub {...});
|
---|
307 | my $route = $r->any(['GET', 'POST'] => '/:foo' => sub {...});
|
---|
308 | my $route = $r->any(['GET', 'POST'] => '/:foo' => [foo => qr/\w+/]);
|
---|
309 |
|
---|
310 | Generate L<Mojolicious::Routes::Route> object matching any of the listed HTTP
|
---|
311 | request methods or all.
|
---|
312 |
|
---|
313 | # Route with pattern and destination
|
---|
314 | $r->any('/user')->to('user#whatever');
|
---|
315 |
|
---|
316 | All arguments are optional, but some have to appear in a certain order, like the
|
---|
317 | two supported array reference values, which contain the HTTP methods to match
|
---|
318 | and restrictive placeholders.
|
---|
319 |
|
---|
320 | # Route with HTTP methods, pattern, restrictive placeholders and destination
|
---|
321 | $r->any(['DELETE', 'PUT'] => '/:foo' => [foo => qr/\w+/])->to('foo#bar');
|
---|
322 |
|
---|
323 | There are also two supported string values, containing the route pattern and the
|
---|
324 | route name, defaulting to the pattern C</> and a name based on the pattern.
|
---|
325 |
|
---|
326 | # Route with pattern, name and destination
|
---|
327 | $r->any('/:foo' => 'foo_route')->to('foo#bar');
|
---|
328 |
|
---|
329 | An arbitrary number of key/value pairs in between the route pattern and name can
|
---|
330 | be used to specify route conditions.
|
---|
331 |
|
---|
332 | # Route with pattern, condition and destination
|
---|
333 | $r->any('/' => (agent => qr/Firefox/))->to('foo#bar');
|
---|
334 |
|
---|
335 | A hash reference is used to specify optional placeholders and default values for
|
---|
336 | the stash.
|
---|
337 |
|
---|
338 | # Route with pattern, optional placeholder and destination
|
---|
339 | $r->any('/:foo' => {foo => 'bar'})->to('foo#bar');
|
---|
340 |
|
---|
341 | And a code reference can be used to specify a C<cb> value to be merged into the
|
---|
342 | default values for the stash.
|
---|
343 |
|
---|
344 | # Route with pattern and a closure as destination
|
---|
345 | $r->any('/:foo' => sub {
|
---|
346 | my $c = shift;
|
---|
347 | $c->render(text => 'Hello World!');
|
---|
348 | });
|
---|
349 |
|
---|
350 | See L<Mojolicious::Guides::Tutorial> and L<Mojolicious::Guides::Routing> for
|
---|
351 | more information.
|
---|
352 |
|
---|
353 | =head2 delete
|
---|
354 |
|
---|
355 | my $route = $r->delete;
|
---|
356 | my $route = $r->delete('/:foo');
|
---|
357 | my $route = $r->delete('/:foo' => sub {...});
|
---|
358 | my $route = $r->delete('/:foo' => sub {...} => 'name');
|
---|
359 | my $route = $r->delete('/:foo' => {foo => 'bar'} => sub {...});
|
---|
360 | my $route = $r->delete('/:foo' => [foo => qr/\w+/] => sub {...});
|
---|
361 | my $route = $r->delete('/:foo' => (agent => qr/Firefox/) => sub {...});
|
---|
362 |
|
---|
363 | Generate L<Mojolicious::Routes::Route> object matching only C<DELETE> requests,
|
---|
364 | takes the same arguments as L</"any"> (except for the HTTP methods to match,
|
---|
365 | which are implied). See L<Mojolicious::Guides::Tutorial> and
|
---|
366 | L<Mojolicious::Guides::Routing> for more information.
|
---|
367 |
|
---|
368 | # Route with destination
|
---|
369 | $r->delete('/user')->to('user#remove');
|
---|
370 |
|
---|
371 | =head2 detour
|
---|
372 |
|
---|
373 | $r = $r->detour(action => 'foo');
|
---|
374 | $r = $r->detour('controller#action');
|
---|
375 | $r = $r->detour(Mojolicious->new, foo => 'bar');
|
---|
376 | $r = $r->detour('MyApp', {foo => 'bar'});
|
---|
377 |
|
---|
378 | Set default parameters for this route and allow partial matching to simplify
|
---|
379 | application embedding, takes the same arguments as L</"to">.
|
---|
380 |
|
---|
381 | =head2 find
|
---|
382 |
|
---|
383 | my $route = $r->find('foo');
|
---|
384 |
|
---|
385 | Find child route by name, custom names have precedence over automatically
|
---|
386 | generated ones.
|
---|
387 |
|
---|
388 | # Change default parameters of a named route
|
---|
389 | $r->find('show_user')->to(foo => 'bar');
|
---|
390 |
|
---|
391 | =head2 get
|
---|
392 |
|
---|
393 | my $route = $r->get;
|
---|
394 | my $route = $r->get('/:foo');
|
---|
395 | my $route = $r->get('/:foo' => sub {...});
|
---|
396 | my $route = $r->get('/:foo' => sub {...} => 'name');
|
---|
397 | my $route = $r->get('/:foo' => {foo => 'bar'} => sub {...});
|
---|
398 | my $route = $r->get('/:foo' => [foo => qr/\w+/] => sub {...});
|
---|
399 | my $route = $r->get('/:foo' => (agent => qr/Firefox/) => sub {...});
|
---|
400 |
|
---|
401 | Generate L<Mojolicious::Routes::Route> object matching only C<GET> requests,
|
---|
402 | takes the same arguments as L</"any"> (except for the HTTP methods to match,
|
---|
403 | which are implied). See L<Mojolicious::Guides::Tutorial> and
|
---|
404 | L<Mojolicious::Guides::Routing> for more information.
|
---|
405 |
|
---|
406 | # Route with destination
|
---|
407 | $r->get('/user')->to('user#show');
|
---|
408 |
|
---|
409 | =head2 has_custom_name
|
---|
410 |
|
---|
411 | my $bool = $r->has_custom_name;
|
---|
412 |
|
---|
413 | Check if this route has a custom name.
|
---|
414 |
|
---|
415 | =head2 has_websocket
|
---|
416 |
|
---|
417 | my $bool = $r->has_websocket;
|
---|
418 |
|
---|
419 | Check if this route has a WebSocket ancestor and cache the result for future
|
---|
420 | checks.
|
---|
421 |
|
---|
422 | =head2 is_endpoint
|
---|
423 |
|
---|
424 | my $bool = $r->is_endpoint;
|
---|
425 |
|
---|
426 | Check if this route qualifies as an endpoint.
|
---|
427 |
|
---|
428 | =head2 is_websocket
|
---|
429 |
|
---|
430 | my $bool = $r->is_websocket;
|
---|
431 |
|
---|
432 | Check if this route is a WebSocket.
|
---|
433 |
|
---|
434 | =head2 name
|
---|
435 |
|
---|
436 | my $name = $r->name;
|
---|
437 | $r = $r->name('foo');
|
---|
438 |
|
---|
439 | The name of this route, defaults to an automatically generated name based on
|
---|
440 | the route pattern. Note that the name C<current> is reserved for referring to
|
---|
441 | the current route.
|
---|
442 |
|
---|
443 | # Route with destination and custom name
|
---|
444 | $r->get('/user')->to('user#show')->name('show_user');
|
---|
445 |
|
---|
446 | =head2 options
|
---|
447 |
|
---|
448 | my $route = $r->options;
|
---|
449 | my $route = $r->options('/:foo');
|
---|
450 | my $route = $r->options('/:foo' => sub {...});
|
---|
451 | my $route = $r->options('/:foo' => sub {...} => 'name');
|
---|
452 | my $route = $r->options('/:foo' => {foo => 'bar'} => sub {...});
|
---|
453 | my $route = $r->options('/:foo' => [foo => qr/\w+/] => sub {...});
|
---|
454 | my $route = $r->options('/:foo' => (agent => qr/Firefox/) => sub {...});
|
---|
455 |
|
---|
456 | Generate L<Mojolicious::Routes::Route> object matching only C<OPTIONS>
|
---|
457 | requests, takes the same arguments as L</"any"> (except for the HTTP methods to
|
---|
458 | match, which are implied). See L<Mojolicious::Guides::Tutorial> and
|
---|
459 | L<Mojolicious::Guides::Routing> for more information.
|
---|
460 |
|
---|
461 | # Route with destination
|
---|
462 | $r->options('/user')->to('user#overview');
|
---|
463 |
|
---|
464 | =head2 over
|
---|
465 |
|
---|
466 | my $over = $r->over;
|
---|
467 | $r = $r->over(foo => 1);
|
---|
468 | $r = $r->over(foo => 1, bar => {baz => 'yada'});
|
---|
469 | $r = $r->over([foo => 1, bar => {baz => 'yada'}]);
|
---|
470 |
|
---|
471 | Activate conditions for this route. Note that this automatically disables the
|
---|
472 | routing cache, since conditions are too complex for caching.
|
---|
473 |
|
---|
474 | # Route with condition and destination
|
---|
475 | $r->get('/foo')->over(host => qr/mojolicious\.org/)->to('foo#bar');
|
---|
476 |
|
---|
477 | =head2 parse
|
---|
478 |
|
---|
479 | $r = $r->parse('/:action');
|
---|
480 | $r = $r->parse('/:action', action => qr/\w+/);
|
---|
481 | $r = $r->parse(format => 0);
|
---|
482 |
|
---|
483 | Parse pattern.
|
---|
484 |
|
---|
485 | =head2 patch
|
---|
486 |
|
---|
487 | my $route = $r->patch;
|
---|
488 | my $route = $r->patch('/:foo');
|
---|
489 | my $route = $r->patch('/:foo' => sub {...});
|
---|
490 | my $route = $r->patch('/:foo' => sub {...} => 'name');
|
---|
491 | my $route = $r->patch('/:foo' => {foo => 'bar'} => sub {...});
|
---|
492 | my $route = $r->patch('/:foo' => [foo => qr/\w+/] => sub {...});
|
---|
493 | my $route = $r->patch('/:foo' => (agent => qr/Firefox/) => sub {...});
|
---|
494 |
|
---|
495 | Generate L<Mojolicious::Routes::Route> object matching only C<PATCH> requests,
|
---|
496 | takes the same arguments as L</"any"> (except for the HTTP methods to match,
|
---|
497 | which are implied). See L<Mojolicious::Guides::Tutorial> and
|
---|
498 | L<Mojolicious::Guides::Routing> for more information.
|
---|
499 |
|
---|
500 | # Route with destination
|
---|
501 | $r->patch('/user')->to('user#update');
|
---|
502 |
|
---|
503 | =head2 post
|
---|
504 |
|
---|
505 | my $route = $r->post;
|
---|
506 | my $route = $r->post('/:foo');
|
---|
507 | my $route = $r->post('/:foo' => sub {...});
|
---|
508 | my $route = $r->post('/:foo' => sub {...} => 'name');
|
---|
509 | my $route = $r->post('/:foo' => {foo => 'bar'} => sub {...});
|
---|
510 | my $route = $r->post('/:foo' => [foo => qr/\w+/] => sub {...});
|
---|
511 | my $route = $r->post('/:foo' => (agent => qr/Firefox/) => sub {...});
|
---|
512 |
|
---|
513 | Generate L<Mojolicious::Routes::Route> object matching only C<POST> requests,
|
---|
514 | takes the same arguments as L</"any"> (except for the HTTP methods to match,
|
---|
515 | which are implied). See L<Mojolicious::Guides::Tutorial> and
|
---|
516 | L<Mojolicious::Guides::Routing> for more information.
|
---|
517 |
|
---|
518 | # Route with destination
|
---|
519 | $r->post('/user')->to('user#create');
|
---|
520 |
|
---|
521 | =head2 put
|
---|
522 |
|
---|
523 | my $route = $r->put;
|
---|
524 | my $route = $r->put('/:foo');
|
---|
525 | my $route = $r->put('/:foo' => sub {...});
|
---|
526 | my $route = $r->put('/:foo' => sub {...} => 'name');
|
---|
527 | my $route = $r->put('/:foo' => {foo => 'bar'} => sub {...});
|
---|
528 | my $route = $r->put('/:foo' => [foo => qr/\w+/] => sub {...});
|
---|
529 | my $route = $r->put('/:foo' => (agent => qr/Firefox/) => sub {...});
|
---|
530 |
|
---|
531 | Generate L<Mojolicious::Routes::Route> object matching only C<PUT> requests,
|
---|
532 | takes the same arguments as L</"any"> (except for the HTTP methods to match,
|
---|
533 | which are implied). See L<Mojolicious::Guides::Tutorial> and
|
---|
534 | L<Mojolicious::Guides::Routing> for more information.
|
---|
535 |
|
---|
536 | # Route with destination
|
---|
537 | $r->put('/user')->to('user#replace');
|
---|
538 |
|
---|
539 | =head2 remove
|
---|
540 |
|
---|
541 | $r = $r->remove;
|
---|
542 |
|
---|
543 | Remove route from parent.
|
---|
544 |
|
---|
545 | # Remove route completely
|
---|
546 | $r->find('foo')->remove;
|
---|
547 |
|
---|
548 | # Reattach route to new parent
|
---|
549 | $r->route('/foo')->add_child($r->find('bar')->remove);
|
---|
550 |
|
---|
551 | =head2 render
|
---|
552 |
|
---|
553 | my $path = $r->render({foo => 'bar'});
|
---|
554 |
|
---|
555 | Render route with parameters into a path.
|
---|
556 |
|
---|
557 | =head2 root
|
---|
558 |
|
---|
559 | my $root = $r->root;
|
---|
560 |
|
---|
561 | The L<Mojolicious::Routes> object this route is a descendant of.
|
---|
562 |
|
---|
563 | =head2 route
|
---|
564 |
|
---|
565 | my $route = $r->route;
|
---|
566 | my $route = $r->route('/:action');
|
---|
567 | my $route = $r->route('/:action', action => qr/\w+/);
|
---|
568 | my $route = $r->route(format => 0);
|
---|
569 |
|
---|
570 | Low-level generator for routes matching all HTTP request methods, returns a
|
---|
571 | L<Mojolicious::Routes::Route> object.
|
---|
572 |
|
---|
573 | =head2 suggested_method
|
---|
574 |
|
---|
575 | my $method = $r->suggested_method;
|
---|
576 |
|
---|
577 | Suggested HTTP method for reaching this route, C<GET> and C<POST> are
|
---|
578 | preferred.
|
---|
579 |
|
---|
580 | =head2 to
|
---|
581 |
|
---|
582 | my $defaults = $r->to;
|
---|
583 | $r = $r->to(action => 'foo');
|
---|
584 | $r = $r->to({action => 'foo'});
|
---|
585 | $r = $r->to('controller#action');
|
---|
586 | $r = $r->to('controller#action', foo => 'bar');
|
---|
587 | $r = $r->to('controller#action', {foo => 'bar'});
|
---|
588 | $r = $r->to(Mojolicious->new);
|
---|
589 | $r = $r->to(Mojolicious->new, foo => 'bar');
|
---|
590 | $r = $r->to(Mojolicious->new, {foo => 'bar'});
|
---|
591 | $r = $r->to('MyApp');
|
---|
592 | $r = $r->to('MyApp', foo => 'bar');
|
---|
593 | $r = $r->to('MyApp', {foo => 'bar'});
|
---|
594 |
|
---|
595 | Set default parameters for this route.
|
---|
596 |
|
---|
597 | =head2 to_string
|
---|
598 |
|
---|
599 | my $str = $r->to_string;
|
---|
600 |
|
---|
601 | Stringify the whole route.
|
---|
602 |
|
---|
603 | =head2 under
|
---|
604 |
|
---|
605 | my $route = $r->under(sub {...});
|
---|
606 | my $route = $r->under('/:foo' => sub {...});
|
---|
607 | my $route = $r->under('/:foo' => {foo => 'bar'});
|
---|
608 | my $route = $r->under('/:foo' => [foo => qr/\w+/]);
|
---|
609 | my $route = $r->under('/:foo' => (agent => qr/Firefox/));
|
---|
610 | my $route = $r->under([format => 0]);
|
---|
611 |
|
---|
612 | Generate L<Mojolicious::Routes::Route> object for a nested route with its own
|
---|
613 | intermediate destination, takes the same arguments as L</"any"> (except for the
|
---|
614 | HTTP methods to match, which are not available). See
|
---|
615 | L<Mojolicious::Guides::Tutorial> and L<Mojolicious::Guides::Routing> for more
|
---|
616 | information.
|
---|
617 |
|
---|
618 | # Intermediate destination and prefix shared between two routes
|
---|
619 | my $auth = $r->under('/user')->to('user#auth');
|
---|
620 | $auth->get('/show')->to('#show');
|
---|
621 | $auth->post('/create')->to('#create');
|
---|
622 |
|
---|
623 | =head2 via
|
---|
624 |
|
---|
625 | my $methods = $r->via;
|
---|
626 | $r = $r->via('GET');
|
---|
627 | $r = $r->via('GET', 'POST');
|
---|
628 | $r = $r->via(['GET', 'POST']);
|
---|
629 |
|
---|
630 | Restrict HTTP methods this route is allowed to handle, defaults to no
|
---|
631 | restrictions.
|
---|
632 |
|
---|
633 | # Route with two methods and destination
|
---|
634 | $r->route('/foo')->via('GET', 'POST')->to('foo#bar');
|
---|
635 |
|
---|
636 | =head2 websocket
|
---|
637 |
|
---|
638 | my $route = $r->websocket;
|
---|
639 | my $route = $r->websocket('/:foo');
|
---|
640 | my $route = $r->websocket('/:foo' => sub {...});
|
---|
641 | my $route = $r->websocket('/:foo' => sub {...} => 'name');
|
---|
642 | my $route = $r->websocket('/:foo' => {foo => 'bar'} => sub {...});
|
---|
643 | my $route = $r->websocket('/:foo' => [foo => qr/\w+/] => sub {...});
|
---|
644 | my $route = $r->websocket('/:foo' => (agent => qr/Firefox/) => sub {...});
|
---|
645 |
|
---|
646 | Generate L<Mojolicious::Routes::Route> object matching only WebSocket
|
---|
647 | handshakes, takes the same arguments as L</"any"> (except for the HTTP methods
|
---|
648 | to match, which are implied). See L<Mojolicious::Guides::Tutorial> and
|
---|
649 | L<Mojolicious::Guides::Routing> for more information.
|
---|
650 |
|
---|
651 | # Route with destination
|
---|
652 | $r->websocket('/echo')->to('example#echo');
|
---|
653 |
|
---|
654 | =head1 AUTOLOAD
|
---|
655 |
|
---|
656 | In addition to the L</"ATTRIBUTES"> and L</"METHODS"> above you can also call
|
---|
657 | shortcuts provided by L</"root"> on L<Mojolicious::Routes::Route> objects.
|
---|
658 |
|
---|
659 | # Add a "firefox" shortcut
|
---|
660 | $r->root->add_shortcut(firefox => sub {
|
---|
661 | my ($r, $path) = @_;
|
---|
662 | $r->get($path, agent => qr/Firefox/);
|
---|
663 | });
|
---|
664 |
|
---|
665 | # Use "firefox" shortcut to generate routes
|
---|
666 | $r->firefox('/welcome')->to('firefox#welcome');
|
---|
667 | $r->firefox('/bye')->to('firefox#bye');
|
---|
668 |
|
---|
669 | =head1 SEE ALSO
|
---|
670 |
|
---|
671 | L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>.
|
---|
672 |
|
---|
673 | =cut
|
---|