Skip to content
This repository
Browse code

added named url_for

  • Loading branch information...
commit 4049362492bfcfb7dcda10dbb5cfa876ef61aee2 1 parent 76948dc
Sebastian Riedel authored
1  Changes
@@ -17,6 +17,7 @@ This file documents the revision history for Perl extension Mojo.
17 17 - Fixed Content-Length header for empty messages.
18 18 - Removed warning from Mojo.pm.
19 19 - Added waypoint() to MojoX::Routes.
  20 + - Added named url_for to MojoX::Routes and Mojolicious.
20 21 - Added Mojolicious documentation. (vti)
21 22 - Fixed documentation links.
22 23 - Fixed some typos.
3  lib/MojoX/Routes.pm
@@ -6,7 +6,6 @@ use strict;
6 6 use warnings;
7 7
8 8 use base 'Mojo::Base';
9   -use overload '""' => sub { shift->to_string }, fallback => 1;
10 9
11 10 use Mojo::URL;
12 11 use MojoX::Routes::Match;
@@ -16,7 +15,7 @@ use constant DEBUG => $ENV{MOJOX_ROUTES_DEBUG} || 0;
16 15
17 16 __PACKAGE__->attr([qw/block inline name/], chained => 1);
18 17 __PACKAGE__->attr('children', chained => 1, default => sub { [] });
19   -__PACKAGE__->attr('parent', chained => 1, weaken => 1);
  18 +__PACKAGE__->attr('parent', chained => 1, weak => 1);
20 19 __PACKAGE__->attr('pattern',
21 20 chained => 1,
22 21 default => sub { MojoX::Routes::Pattern->new }
70 lib/MojoX/Routes/Match.pm
@@ -32,8 +32,67 @@ sub new {
32 32 }
33 33
34 34 sub url_for {
35   - my $self = shift;
36   - my $values = ref $_[0] eq 'HASH' ? $_[0] : {@_};
  35 + my $self = shift;
  36 + my $endpoint = $self->endpoint;
  37 + my $values = {};
  38 + my $name = undef;
  39 +
  40 + # Single argument
  41 + if (@_ == 1) {
  42 +
  43 + # Hash
  44 + $values = shift if ref $_[0] eq 'HASH';
  45 +
  46 + # Name
  47 + $name = $_[0] if $_[0];
  48 + }
  49 +
  50 + # Multiple arguments
  51 + elsif (@_ > 1) {
  52 +
  53 + # Odd
  54 + if (@_ % 2) {
  55 + $name = shift;
  56 + $values = {@_};
  57 + }
  58 +
  59 + # Even
  60 + else {
  61 +
  62 + # Name and hashref
  63 + if (ref $_[1] eq 'HASH') {
  64 + $name = shift;
  65 + $values = shift;
  66 + }
  67 +
  68 + # Just values
  69 + $values = {@_};
  70 +
  71 + }
  72 + }
  73 +
  74 + # Named
  75 + if ($name) {
  76 +
  77 + # Find root
  78 + my $stop = $endpoint;
  79 + while ($stop->parent) {
  80 + $stop = $stop->parent;
  81 + }
  82 +
  83 + # Find endpoint
  84 + my @children = ($stop);
  85 + while (my $child = shift @children) {
  86 +
  87 + if (($child->name || '') eq $name) {
  88 + $endpoint = $child;
  89 + last;
  90 + }
  91 +
  92 + # Append
  93 + push @children, @{$child->children};
  94 + }
  95 + }
37 96
38 97 # Merge values
39 98 $values = {%{$self->captures}, %$values};
@@ -41,10 +100,10 @@ sub url_for {
41 100 my $url = Mojo::URL->new;
42 101
43 102 # No endpoint
44   - return $url unless $self->endpoint;
  103 + return $url unless $endpoint;
45 104
46 105 # Render
47   - $self->endpoint->url_for($url, $values);
  106 + $endpoint->url_for($url, $values);
48 107
49 108 return $url;
50 109 }
@@ -112,5 +171,8 @@ implements the follwing the ones.
112 171 my $url = $match->url_for;
113 172 my $url = $match->url_for(foo => 'bar');
114 173 my $url = $match->url_for({foo => 'bar'});
  174 + my $url = $match->url_for('named');
  175 + my $url = $match->url_for('named', foo => 'bar');
  176 + my $url = $match->url_for('named', {foo => 'bar'});
115 177
116 178 =cut
3  lib/Mojolicious/Context.pm
@@ -7,7 +7,7 @@ use warnings;
7 7
8 8 use base 'MojoX::Dispatcher::Routes::Context';
9 9
10   -__PACKAGE__->attr('mojolicious', chained => 1, weaken => 1);
  10 +__PACKAGE__->attr('mojolicious', chained => 1, weak => 1);
11 11 __PACKAGE__->attr('stash', chained => 1, default => sub { {} });
12 12
13 13 *mojo = \&mojolicious;
@@ -82,5 +82,6 @@ L<MojoX::Dispatcher::Routes::Context> and implements the following new ones.
82 82
83 83 my $url = $c->url_for;
84 84 my $url = $c->url_for(controller => 'bar', action => 'baz');
  85 + my $url = $c->url_for('named', controller => 'bar', action => 'baz');
85 86
86 87 =cut
9 t/mojox/routes/routes.t
@@ -5,7 +5,7 @@
5 5 use strict;
6 6 use warnings;
7 7
8   -use Test::More tests => 39;
  8 +use Test::More tests => 41;
9 9
10 10 use Mojo::Transaction;
11 11
@@ -19,7 +19,7 @@ my $r = MojoX::Routes->new;
19 19 my $test = $r->route('/:controller/test')->to(action => 'test');
20 20
21 21 # /*/test/edit
22   -$test->route('/edit')->to(action => 'edit');
  22 +$test->route('/edit')->to(action => 'edit')->name('test_edit');
23 23
24 24 # /*/test/delete/*
25 25 $test->route('/delete/:id', id => qr/\d+/)->to(action => 'delete', id => 23);
@@ -98,6 +98,11 @@ is($match->stack->[0]->{controller}, 's');
98 98 is($match->stack->[0]->{action}, 'edit');
99 99 is($match->url_for, '/test3/edit');
100 100
  101 +# Named url_for
  102 +$match = $r->match(_tx('/test3'));
  103 +is($match->url_for, '/test3');
  104 +is($match->url_for('test_edit', controller => 'foo'), '/foo/test/edit');
  105 +
101 106 # Helper
102 107 sub _tx {
103 108 my $tx = Mojo::Transaction->new_post;

0 comments on commit 4049362

Please sign in to comment.
Something went wrong with that request. Please try again.