sub uri_for { my ( $c, $path, @args ) = @_; my $base = $c->request->base->clone; my $basepath = $base->path; $basepath =~ s/\/$//; $basepath .= '/'; my $namespace = $c->namespace || ''; if ( Scalar::Util::blessed($path) ) { # action object my $captures = ( scalar @args && ref $args[0] eq 'ARRAY' ? shift(@args) : [] ); $path = $c->dispatcher->uri_for_action($path, $captures); return undef unless defined($path); $path = '/' if $path eq ''; } # massage namespace, empty if absolute path $namespace =~ s/^\/// if $namespace; $namespace .= '/' if $namespace; $path ||= ''; $namespace = '' if $path =~ /^\//; $path =~ s/^\///; my $params = ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} ); for my $value ( values %$params ) { next unless defined $value; for ( ref $value eq 'ARRAY' ? @$value : $value ) { $_ = "$_"; utf8::encode( $_ ); } }; # join args with '/', or a blank string my $args = ( scalar @args ? '/' . join( '/', @args ) : '' ); $args =~ s/^\/// unless $path; my $res = URI->new_abs( URI->new_abs( "$path$args", "$basepath$namespace" ), $base ) ->canonical; $res->query_form(%$params); $res; }