Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

added named url_for

  • Loading branch information...
commit 4049362492bfcfb7dcda10dbb5cfa876ef61aee2 1 parent 76948dc
Sebastian Riedel authored
1  Changes
View
@@ -17,6 +17,7 @@ This file documents the revision history for Perl extension Mojo.
- Fixed Content-Length header for empty messages.
- Removed warning from Mojo.pm.
- Added waypoint() to MojoX::Routes.
+ - Added named url_for to MojoX::Routes and Mojolicious.
- Added Mojolicious documentation. (vti)
- Fixed documentation links.
- Fixed some typos.
3  lib/MojoX/Routes.pm
View
@@ -6,7 +6,6 @@ use strict;
use warnings;
use base 'Mojo::Base';
-use overload '""' => sub { shift->to_string }, fallback => 1;
use Mojo::URL;
use MojoX::Routes::Match;
@@ -16,7 +15,7 @@ use constant DEBUG => $ENV{MOJOX_ROUTES_DEBUG} || 0;
__PACKAGE__->attr([qw/block inline name/], chained => 1);
__PACKAGE__->attr('children', chained => 1, default => sub { [] });
-__PACKAGE__->attr('parent', chained => 1, weaken => 1);
+__PACKAGE__->attr('parent', chained => 1, weak => 1);
__PACKAGE__->attr('pattern',
chained => 1,
default => sub { MojoX::Routes::Pattern->new }
70 lib/MojoX/Routes/Match.pm
View
@@ -32,8 +32,67 @@ sub new {
}
sub url_for {
- my $self = shift;
- my $values = ref $_[0] eq 'HASH' ? $_[0] : {@_};
+ my $self = shift;
+ my $endpoint = $self->endpoint;
+ my $values = {};
+ my $name = undef;
+
+ # Single argument
+ if (@_ == 1) {
+
+ # Hash
+ $values = shift if ref $_[0] eq 'HASH';
+
+ # Name
+ $name = $_[0] if $_[0];
+ }
+
+ # Multiple arguments
+ elsif (@_ > 1) {
+
+ # Odd
+ if (@_ % 2) {
+ $name = shift;
+ $values = {@_};
+ }
+
+ # Even
+ else {
+
+ # Name and hashref
+ if (ref $_[1] eq 'HASH') {
+ $name = shift;
+ $values = shift;
+ }
+
+ # Just values
+ $values = {@_};
+
+ }
+ }
+
+ # Named
+ if ($name) {
+
+ # Find root
+ my $stop = $endpoint;
+ while ($stop->parent) {
+ $stop = $stop->parent;
+ }
+
+ # Find endpoint
+ my @children = ($stop);
+ while (my $child = shift @children) {
+
+ if (($child->name || '') eq $name) {
+ $endpoint = $child;
+ last;
+ }
+
+ # Append
+ push @children, @{$child->children};
+ }
+ }
# Merge values
$values = {%{$self->captures}, %$values};
@@ -41,10 +100,10 @@ sub url_for {
my $url = Mojo::URL->new;
# No endpoint
- return $url unless $self->endpoint;
+ return $url unless $endpoint;
# Render
- $self->endpoint->url_for($url, $values);
+ $endpoint->url_for($url, $values);
return $url;
}
@@ -112,5 +171,8 @@ implements the follwing the ones.
my $url = $match->url_for;
my $url = $match->url_for(foo => 'bar');
my $url = $match->url_for({foo => 'bar'});
+ my $url = $match->url_for('named');
+ my $url = $match->url_for('named', foo => 'bar');
+ my $url = $match->url_for('named', {foo => 'bar'});
=cut
3  lib/Mojolicious/Context.pm
View
@@ -7,7 +7,7 @@ use warnings;
use base 'MojoX::Dispatcher::Routes::Context';
-__PACKAGE__->attr('mojolicious', chained => 1, weaken => 1);
+__PACKAGE__->attr('mojolicious', chained => 1, weak => 1);
__PACKAGE__->attr('stash', chained => 1, default => sub { {} });
*mojo = \&mojolicious;
@@ -82,5 +82,6 @@ L<MojoX::Dispatcher::Routes::Context> and implements the following new ones.
my $url = $c->url_for;
my $url = $c->url_for(controller => 'bar', action => 'baz');
+ my $url = $c->url_for('named', controller => 'bar', action => 'baz');
=cut
9 t/mojox/routes/routes.t
View
@@ -5,7 +5,7 @@
use strict;
use warnings;
-use Test::More tests => 39;
+use Test::More tests => 41;
use Mojo::Transaction;
@@ -19,7 +19,7 @@ my $r = MojoX::Routes->new;
my $test = $r->route('/:controller/test')->to(action => 'test');
# /*/test/edit
-$test->route('/edit')->to(action => 'edit');
+$test->route('/edit')->to(action => 'edit')->name('test_edit');
# /*/test/delete/*
$test->route('/delete/:id', id => qr/\d+/)->to(action => 'delete', id => 23);
@@ -98,6 +98,11 @@ is($match->stack->[0]->{controller}, 's');
is($match->stack->[0]->{action}, 'edit');
is($match->url_for, '/test3/edit');
+# Named url_for
+$match = $r->match(_tx('/test3'));
+is($match->url_for, '/test3');
+is($match->url_for('test_edit', controller => 'foo'), '/foo/test/edit');
+
# Helper
sub _tx {
my $tx = Mojo::Transaction->new_post;
Please sign in to comment.
Something went wrong with that request. Please try again.