Catalyst-Plugin-CachedUriForAction

 view release on metacpan or  search on metacpan

lib/Catalyst/Plugin/CachedUriForAction.pm  view on Meta::CPAN


sub uri_for_action {
	my $c = shift;

	my $dispatcher = $c->dispatcher;
	my $cache = $dispatcher && $dispatcher->{(CACHE_KEY)}
		or return $c->next::method( @_ ); # fall back if called too early

	my $action   = shift;
	my $captures = @_ && 'ARRAY'  eq ref $_[0]  ? shift : [];
	my $fragment = @_ && 'SCALAR' eq ref $_[-1] ? pop   : undef;
	my $params   = @_ && 'HASH'   eq ref $_[-1] ? pop   : undef;

	$action = '/' . $dispatcher->get_action_by_path( $action )->reverse
		if ref $action
		and do { local $@; eval { $action->isa( 'Catalyst::Action' ) } };

	my $info = $cache->{ $action }
		or Carp::croak "Can't find action for path '$action' in uri_for_action";

	my ( $uri, $base ) = '';

lib/Catalyst/Plugin/CachedUriForAction.pm  view on Meta::CPAN

					( $query .= '=' ) .= uri_encode_utf8 $_ if defined;
				}
			}
		}
		if ( '' ne $query ) {
			$query =~ s/%20/+/g;
			( $uri .= '?' ) .= substr $query, length $delim;
		}
	}

	if ( defined $fragment ) {
		( $uri .= '#' ) .= uri_encode_utf8 $$fragment;
	}

	bless \$uri, ref $base;
}

BEGIN { delete $Catalyst::Plugin::CachedUriForAction::{'uri_encode_utf8'} }

1;

__END__

lib/Catalyst/Plugin/CachedUriForAction.pm  view on Meta::CPAN

B<If you need this then you will not be able to use this plugin.>

=item * Incorrect C<uri_for_action> inputs

The stock method returns undef when given an unknown action path or the wrong number of captures or args.
This has never been useful to me but has been a cause of some annoying debugging sessions.
This plugin puts an end to that by throwing an exception instead.

If you run into this, you can use C<eval> or fall back to C<uri_for> for those calls.

=item * Setting the URL fragment as part of the args

This plugin does not handle args in the sloppy/DWIM fashion C<uri_for> tries to offer.
Setting a URL fragment is supported, but only by passing it as a trailing scalar ref.
Plain parameters are always treated as args and therefore encoded.

If you run into this, you can fall back to C<uri_for> for those calls.

=item * Arg constraints (such as C<:CaptureArgs(Int,Str)>)

Note that this plugin does not affect request dispatch so constraints will still apply there.
They will merely not be validated when generating URLs.

This may be possible to support but demand would have to justify an attempt at it.

t/unit_core_uri_for.t  view on Meta::CPAN

    'Plus is not encoded'
);

is(
    $context->uri_for_action( '/bar', 'with space', { 'also with' => 'space here' })->as_string,
    'http://127.0.0.1/foo/bar/with%20space?also+with=space+here',
    'Spaces encoded correctly'
);

is(
    $context->uri_for_action( '/bar', { param1 => 'value1' }, \'fragment' )->as_string,
    'http://127.0.0.1/foo/bar?param1=value1#fragment',
    'URI for path with fragment and query params 1'
);

is(
    TestApp->uri_for_action( '/quux', { param1 => 'value1' } )->as_string,
    '/quux?param1=value1',
    'URI for quux action with query params, called with only class name'
);

is (TestApp->uri_for_action( '/bar', 'wibble?' )->as_string,
   '/bar/wibble%3F', 'Question Mark gets encoded, called with only class name'

t/unit_core_uri_for.t  view on Meta::CPAN

    use overload '""' => sub { $_[0]->{string} }, fallback => 1;
}

is(
    $context->uri_for_action( bless( { string => '/test' }, 'MyStringThing' ) ),
    'http://127.0.0.1/test',
    'overloaded object handled correctly'
);

is(
    $context->uri_for_action( bless( { string => '/test' }, 'MyStringThing' ), \'fragment' ),
    'http://127.0.0.1/test#fragment',
    'overloaded object handled correctly'
);

done_testing;



( run in 1.886 second using v1.01-cache-2.11-cpan-364913b4093 )