use Tree::Simple::Visitor::FindByUID;
use attributes;
use utf8;
-use Carp qw/croak carp/;
+use Carp qw/croak carp shortmess/;
BEGIN { require 5.008001; }
# Remember to update this in Catalyst::Runtime as well!
-our $VERSION = '5.7099_02';
+our $VERSION = '5.71000';
sub import {
my ( $class, @arguments ) = @_;
catalyst.pl MyApp
# add models, views, controllers
- script/myapp_create.pl model MyDatabase DBIC::Schema create=dynamic dbi:SQLite:/path/to/db
+ script/myapp_create.pl model MyDatabase DBIC::Schema create=static dbi:SQLite:/path/to/db
script/myapp_create.pl view MyTemplate TT
script/myapp_create.pl controller Search
sub detach { my $c = shift; $c->dispatcher->detach( $c, @_ ) }
+=head2 $c->visit( $action [, \@arguments ] )
+
+=head2 $c->visit( $class, $method, [, \@arguments ] )
+
+Almost the same as C<forward>, but does a full dispatch, instead of just
+calling the new C<$action> / C<$class-E<gt>$method>. This means that C<begin>,
+C<auto> and the method you go to are called, just like a new request.
+
+In addition both C<< $c->action >> and C<< $c->namespace >> are localized.
+This means, for example, that $c->action methods such as C<name>, C<class> and
+C<reverse> return information for the visited action when they are invoked
+within the visited action. This is different from the behavior of C<forward>
+which continues to use the $c->action object from the caller action even when
+invoked from the callee.
+
+C<$c-E<gt>stash> is kept unchanged.
+
+In effect, C<visit> allows you to "wrap" another action, just as it
+would have been called by dispatching from a URL, while the analogous
+C<go> allows you to transfer control to another action as if it had
+been reached directly from a URL.
+
+=cut
+
+sub visit { my $c = shift; $c->dispatcher->visit( $c, @_ ) }
+
=head2 $c->go( $action [, \@arguments ] )
=head2 $c->go( $class, $method, [, \@arguments ] )
-Almost the same as C<detach>, but does a full dispatch, instead of just
-calling the new C<$action> / C<$class-E<gt>$method>. This means that C<begin>,
-C<auto> and the method you go to is called, just like a new request.
+Almost the same as C<detach>, but does a full dispatch like C<visit>,
+instead of just calling the new C<$action> /
+C<$class-E<gt>$method>. This means that C<begin>, C<auto> and the
+method you visit are called, just like a new request.
C<$c-E<gt>stash> is kept unchanged.
# don't warn if we didn't find any results, it just might not exist
if( @result ) {
- $c->log->warn( qq(Found results for "${name}" using regexp fallback.) );
- $c->log->warn( 'Relying on the regexp fallback behavior for component resolution is unreliable and unsafe.' );
- $c->log->warn( 'If you really want to search, pass in a regexp as the argument.' );
+ my $msg = "Used regexp fallback for \$c->model('${name}'), which found '" .
+ (join '", "', @result) . "'. Relying on regexp fallback behavior for " .
+ "component resolution is unreliable and unsafe.";
+ my $short = $result[0];
+ $short =~ s/.*?Model:://;
+ my $shortmess = Carp::shortmess('');
+ if ($shortmess =~ m#Catalyst/Plugin#) {
+ $msg .= " You probably need to set '$short' instead of '${name}' in this " .
+ "plugin's config";
+ } elsif ($shortmess =~ m#Catalyst/lib/(View|Controller)#) {
+ $msg .= " You probably need to set '$short' instead of '${name}' in this " .
+ "component's config";
+ } else {
+ $msg .= " You probably meant \$c->model('$short') instead of \$c->model{'${name}'}, " .
+ "but if you really wanted to search, pass in a regexp as the argument " .
+ "like so: \$c->model(qr/${name}/)";
+ }
+ $c->log->warn( "${msg}$shortmess" );
}
return @result;
my( $comp, $rest ) = $c->_comp_search_prefixes( undef, qw/Model M/);
if( $rest ) {
- $c->log->warn( 'Calling $c->model() will return a random model unless you specify one of:' );
+ $c->log->warn( Carp::shortmess('Calling $c->model() will return a random model unless you specify one of:') );
$c->log->warn( '* $c->config->{default_model} # the name of the default model to use' );
$c->log->warn( '* $c->stash->{current_model} # the name of the model to use for this request' );
$c->log->warn( '* $c->stash->{current_model_instance} # the instance of the model to use for this request' );
if( !ref $name ) {
# is it the exact name?
- return $comps->{ $name } if exists $comps->{ $name };
+ return $c->_filter_component( $comps->{ $name }, @args )
+ if exists $comps->{ $name };
# perhaps we just omitted "MyApp"?
my $composed = ( ref $c || $c ) . "::${name}";
- return $comps->{ $composed } if exists $comps->{ $composed };
+ return $c->_filter_component( $comps->{ $composed }, @args )
+ if exists $comps->{ $composed };
# search all of the models, views and controllers
my( $comp ) = $c->_comp_search_prefixes( $name, qw/Model M Controller C View V/ );
my $query = ref $name ? $name : qr{$name}i;
my @result = grep { m{$query} } keys %{ $c->components };
- return @result if ref $name;
+ return map { $c->_filter_component( $_, @args ) } @result if ref $name;
if( $result[ 0 ] ) {
+ $c->log->warn( Carp::shortmess(qq(Found results for "${name}" using regexp fallback)) );
$c->log->warn( 'Relying on the regexp fallback behavior for component resolution' );
$c->log->warn( 'is unreliable and unsafe. You have been warned' );
- return $result[ 0 ];
+ return $c->_filter_component( $result[ 0 ], @args );
}
# I would expect to return an empty list here, but that breaks back-compat
$class->setup_finished(1);
}
+=head2 $c->uri_for( $action, \@captures?, @args?, \%query_values? )
+
=head2 $c->uri_for( $path, @args?, \%query_values? )
-Merges path with C<< $c->request->base >> for absolute URIs and with
-C<< $c->namespace >> for relative URIs, then returns a normalized L<URI>
-object. If any args are passed, they are added at the end of the path.
-If the last argument to C<uri_for> is a hash reference, it is assumed to
-contain GET parameter key/value pairs, which will be appended to the URI
-in standard fashion.
+=over
+
+=item $action
+
+A Catalyst::Action object representing the Catalyst action you want to
+create a URI for. To get one for an action in the current controller,
+use C<< $c->action('someactionname') >>. To get one from different
+controller, fetch the controller using C<< $c->controller() >>, then
+call C<action_for> on it.
-Note that uri_for is destructive to the passed hashref. Subsequent calls
-with the same hashref may have unintended results.
+This method must be used to create URIs for
+L<Catalyst::DispatchType::Chained> actions.
-Instead of C<$path>, you can also optionally pass a C<$action> object
-which will be resolved to a path using
-C<< $c->dispatcher->uri_for_action >>; if the first element of
-C<@args> is an arrayref it is treated as a list of captures to be passed
-to C<uri_for_action>.
+=item $path
+
+The actual path you wish to create a URI for, this is a public path,
+not a private action path.
+
+=item \@captures
+
+If provided, this argument is used to insert values into a I<Chained>
+action in the parts where the definitions contain I<CaptureArgs>. If
+not needed, leave out this argument.
+
+=item @args
+
+If provided, this is used as a list of further path sections to append
+to the URI. In a I<Chained> action these are the equivalent to the
+endpoint L<Args>.
+
+=item \%query_values
+
+If provided, the query_values hashref is used to add query parameters
+to the URI, with the keys as the names, and the values as the values.
+
+=back
+
+Returns a L<URI> object.
+
+ ## Ex 1: a path with args and a query parameter
+ $c->uri_for('user/list', 'short', { page => 2});
+ ## -> ($c->req->base is 'http://localhost:3000/'
+ URI->new('http://localhost:3000/user/list/short?page=2)
+
+ ## Ex 2: a chained view action that captures the user id
+ ## In controller:
+ sub user : Chained('/'): PathPart('myuser'): CaptureArgs(1) {}
+ sub viewuser : Chained('user'): PathPart('view') {}
+
+ ## In uri creating code:
+ my $uaction = $c->controller('Users')->action_for('viewuser');
+ $c->uri_for($uaction, [ 42 ]);
+ ## outputs:
+ URI->new('http://localhost:3000/myuser/42/view')
+
+Creates a URI object using C<< $c->request->base >> and a path. If an
+Action object is given instead of a path, the path is constructed
+using C<< $c->dispatcher->uri_for_action >> and passing it the
+@captures array, if supplied.
+
+If any query parameters are passed they are added to the end of the
+URI in the usual way.
+
+Note that uri_for is destructive to the passed query values hashref.
+Subsequent calls with the same hashref may have unintended results.
=cut
jcamacho: Juan Camacho
+jhannah: Jay Hannah <jay@jays.net>
+
Jody Belka
Johan Lindstrom
willert: Sebastian Willert <willert@cpan.org>
+batman: Jan Henning Thorsen <pm@flodhest.net>
+
=head1 LICENSE
This library is free software, you can redistribute it and/or modify it under