# Remember to update this in Catalyst::Runtime as well!
-our $VERSION = '5.80006';
+our $VERSION = '5.80007';
{
my $dev_version = $VERSION =~ /_\d{2}$/;
}
my $meta = Moose::Meta::Class->initialize($caller);
- #Moose->import({ into => $caller }); #do we want to do this?
-
unless ( $caller->isa('Catalyst') ) {
my @superclasses = ($meta->superclasses, $class, 'Catalyst::Controller');
$meta->superclasses(@superclasses);
}
+ # Avoid possible C3 issues if 'Moose::Object' is already on RHS of MyApp
+ $meta->superclasses(grep { $_ ne 'Moose::Object' } $meta->superclasses);
+
unless( $meta->has_method('meta') ){
$meta->add_method(meta => sub { Moose::Meta::Class->initialize("${caller}") } );
}
$c->forward(qw/MyApp::Model::DBIC::Foo do_stuff/);
$c->forward('MyApp::View::TT');
-Note that forward implies an C<<eval { }>> around the call (actually
-C<execute> does), thus de-fatalizing all 'dies' within the called
-action. If you want C<die> to propagate you need to do something like:
+Note that L<< forward|/"$c->forward( $action [, \@arguments ] )" >> implies
+an C<< eval { } >> around the call (actually
+L<< execute|/"$c->execute( $class, $coderef )" >> does), thus de-fatalizing
+all 'dies' within the called action. If you want C<die> to propagate you
+need to do something like:
$c->forward('foo');
die $c->error if $c->error;
=head2 $c->detach()
-The same as C<forward>, but doesn't return to the previous action when
-processing is finished.
+The same as L<< forward|/"$c->forward( $action [, \@arguments ] )" >>, but
+doesn't return to the previous action when processing is finished.
When called with no arguments it escapes the processing chain entirely.
=head2 $c->visit( $class, $method, [, \@captures, \@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.
+Almost the same as L<< forward|/"$c->forward( $action [, \@arguments ] )" >>,
+but does a full dispatch, instead of just calling the new C<$action> /
+C<< $class->$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
+This means, for example, that C<< $c->action >> methods such as
+L<name|Catalyst::Action/name>, L<class|Catalyst::Action/class> and
+L<reverse|Catalyst::Action/reverse> return information for the visited action
+when they are invoked within the visited action. This is different from the
+behavior of L<< forward|/"$c->forward( $action [, \@arguments ] )" >>, 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.
+C<< $c->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.
+In effect, L<< visit|/"$c->visit( $action [, \@captures, \@arguments ] )" >>
+allows you to "wrap" another action, just as it would have been called by
+dispatching from a URL, while the analogous
+L<< go|/"$c->go( $action [, \@captures, \@arguments ] )" >> allows you to
+transfer control to another action as if it had been reached directly from a URL.
=cut
=head2 $c->go( $class, $method, [, \@captures, \@arguments ] )
-Almost the same as C<detach>, but does a full dispatch like C<visit>,
+Almost the same as L<< detach|/"$c->detach( $action [, \@arguments ] )" >>, but does a full dispatch like L</visit>,
instead of just calling the new C<$action> /
-C<$class-E<gt>$method>. This means that C<begin>, C<auto> and the
+C<< $class->$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.
+C<< $c->stash >> is kept unchanged.
=cut
if( $rest ) {
$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->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' );
$c->log->warn( 'NB: in version 5.81, the "random" behavior will not work at all.' );
if( $rest ) {
$c->log->warn( 'Calling $c->view() will return a random view unless you specify one of:' );
- $c->log->warn( '* $c->config->{default_view} # the name of the default view to use' );
+ $c->log->warn( '* $c->config(default_view => "the name of the default view to use")' );
$c->log->warn( '* $c->stash->{current_view} # the name of the view to use for this request' );
$c->log->warn( '* $c->stash->{current_view_instance} # the instance of the view to use for this request' );
$c->log->warn( 'NB: in version 5.81, the "random" behavior will not work at all.' );
__PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } );
-You can also use a C<YAML>, C<XML> or C<Config::General> config file
-like myapp.conf in your applications home directory. See
+You can also use a C<YAML>, C<XML> or L<Config::General> config file
+like C<myapp.conf> in your applications home directory. See
L<Catalyst::Plugin::ConfigLoader>.
-=head3 Cascading configuration.
+=head3 Cascading configuration
The config method is present on all Catalyst components, and configuration
will be merged when an application is started. Configuration loaded with
Merges C<@path> with C<< $c->config->{home} >> and returns a
L<Path::Class::Dir> object. Note you can usually use this object as
a filename, but sometimes you will have to explicitly stringify it
-yourself by calling the C<<->stringify>> method.
+yourself by calling the C<< ->stringify >> method.
For example:
$class->log->_flush() if $class->log->can('_flush');
# Make sure that the application class becomes immutable at this point,
- # which ensures that it gets an inlined constructor. This means that it
- # works even if the user has added a plugin which contains a new method.
- # Note however that we have to do the work on scope end, so that method
- # modifiers work correctly in MyApp (as you have to call setup _before_
- # applying modifiers).
B::Hooks::EndOfScope::on_scope_end {
return if $@;
my $meta = Class::MOP::get_metaclass_by_name($class);
- if ( $meta->is_immutable && ! { $meta->immutable_options }->{inline_constructor} ) {
+ if (
+ $meta->is_immutable
+ && ! { $meta->immutable_options }->{replace_constructor}
+ && (
+ $class->isa('Class::Accessor::Fast')
+ || $class->isa('Class::Accessor')
+ )
+ ) {
warn "You made your application class ($class) immutable, "
- . "but did not inline the constructor.\n"
- . "This will break catalyst, please pass "
- . "(replace_constructor => 1) when making your class immutable.\n";
+ . "but did not inline the\nconstructor. "
+ . "This will break catalyst, as your app \@ISA "
+ . "Class::Accessor(::Fast)?\nPlease pass "
+ . "(replace_constructor => 1)\nwhen making your class immutable.\n";
}
- $meta->make_immutable(replace_constructor => 1) unless $meta->is_immutable;
+ $meta->make_immutable(replace_constructor => 1)
+ unless $meta->is_immutable;
};
$class->setup_finalize;
$class->setup_finished(1);
}
-=head2 $c->uri_for( $action, \@captures?, @args?, \%query_values? )
-
=head2 $c->uri_for( $path, @args?, \%query_values? )
-=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.
-
-You can maintain the arguments captured by an action (e.g.: Regex, Chained)
-using C<< $c->req->captures >>.
+=head2 $c->uri_for( $action, \@captures?, @args?, \%query_values? )
- # For the current action
- $c->uri_for($c->action, $c->req->captures);
+Constructs an absolute L<URI> object based on the application root, the
+provided path, and the additional arguments and query parameters provided.
+When used as a string, provides a textual URI.
+
+If the first argument is a string, it is taken as a public URI path relative
+to C<< $c->namespace >> (if it doesn't begin with a forward slash) or
+relative to the application root (if it does). It is then merged with
+C<< $c->request->base >>; any C<@args> are appended as additional path
+components; and any C<%query_values> are appended as C<?foo=bar> parameters.
+
+If the first argument is a L<Catalyst::Action> it represents an action which
+will have its path resolved using C<< $c->dispatcher->uri_for_action >>. The
+optional C<\@captures> argument (an arrayref) allows passing the captured
+variables that are needed to fill in the paths of Chained and Regex actions;
+once the path is resolved, C<uri_for> continues as though a path was
+provided, appending any arguments or parameters and creating an absolute
+URI.
+
+The captures for the current request can be found in
+C<< $c->request->captures >>, and actions can be resolved using
+C<< Catalyst::Controller->action_for($name) >>. If you have a private action
+path, use C<< $c->uri_for_action >> instead.
+
+ # Equivalent to $c->req->uri
+ $c->uri_for($c->action, $c->req->captures,
+ @{ $c->req->args }, $c->req->params);
# For the Foo action in the Bar controller
- $c->uri_for($c->controller('Bar')->action_for('Foo'), $c->req->captures);
+ $c->uri_for($c->controller('Bar')->action_for('Foo'));
-=back
+ # Path to a static resource
+ $c->uri_for('/static/images/logo.png');
=cut
$c->stats->profile( end => $info );
}
-=head2 $c->_localize_fields( sub { }, \%keys );
-
-=cut
-
-#Why does this exist? This is no longer safe and WILL NOT WORK.
-# it doesnt seem to be used anywhere. can we remove it?
-sub _localize_fields {
- my ( $c, $localized, $code ) = ( @_ );
-
- my $request = delete $localized->{request} || {};
- my $response = delete $localized->{response} || {};
-
- local @{ $c }{ keys %$localized } = values %$localized;
- local @{ $c->request }{ keys %$request } = values %$request;
- local @{ $c->response }{ keys %$response } = values %$response;
-
- $code->();
-}
-
=head2 $c->finalize
Finalizes the request.
be used in a while loop, reading C<$maxlength> bytes on every call.
C<$maxlength> defaults to the size of the request if not specified.
-You have to set C<< MyApp->config->{parse_on_demand} >> to use this
+You have to set C<< MyApp->config(parse_on_demand => 1) >> to use this
directly.
Warning: If you use read(), Catalyst will not process the body,
application class name prepended to them.
All components found will also have any
-L<Devel::InnerPackage|inner packages> loaded and set up as components.
+L<inner packages|Devel::InnerPackage> loaded and set up as components.
Note, that modules which are B<not> an I<inner package> of the main
file namespace loaded will not be instantiated as components.
my $suffix = Catalyst::Utils::class2classsuffix( $component );
my $config = $class->config->{ $suffix } || {};
+ # Stash _component_name in the config here, so that custom COMPONENT
+ # methods also pass it. local to avoid pointlessly shitting in config
+ # for the debug screen, as $component is already the key name.
+ local $config->{_component_name} = $component;
my $instance = eval { $component->COMPONENT( $class, $config ); };
C<_ACTION>, and C<_END>. These are by default not shown in the private
action table, but you can make them visible with a config parameter.
- MyApp->config->{show_internal_actions} = 1;
+ MyApp->config(show_internal_actions => 1);
=head1 CASE SENSITIVITY
mapped to C</foo/bar>. You can activate case sensitivity with a config
parameter.
- MyApp->config->{case_sensitive} = 1;
+ MyApp->config(case_sensitive => 1);
This causes C<MyApp::C::Foo::Bar> to map to C</Foo/Bar>.
but if you want to handle input yourself, you can enable on-demand
parsing with a config parameter.
- MyApp->config->{parse_on_demand} = 1;
+ MyApp->config(parse_on_demand => 1);
=head1 PROXY SUPPORT
configuration option to tell Catalyst to read the proxied data from the
headers.
- MyApp->config->{using_frontend_proxy} = 1;
+ MyApp->config(using_frontend_proxy => 1);
If you do not wish to use the proxy support at all, you may set:
- MyApp->config->{ignore_frontend_proxy} = 1;
+ MyApp->config(ignore_frontend_proxy => 1);
=head1 THREAD SAFETY
=head2 L<Catalyst::Manual> - The Catalyst Manual
-=head2 L<Catalyst::Component>, L<Catalyst::Base> - Base classes for components
+=head2 L<Catalyst::Component>, L<Catalyst::Controller> - Base classes for components
=head2 L<Catalyst::Engine> - Core engine
Geoff Richards
+hobbs: Andrew Rodland <andrew@cleverdomain.org>
+
ilmari: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
jcamacho: Juan Camacho
+jester: Jesse Sheidlower
+
jhannah: Jay Hannah <jay@jays.net>
Jody Belka
jon: Jon Schutz <jjschutz@cpan.org>
+konobi: Scott McWhirter <konobi@cpan.org>
+
marcus: Marcus Ramberg <mramberg@cpan.org>
miyagawa: Tatsuhiko Miyagawa <miyagawa@bulknews.net>
sky: Arthur Bergman
-the_jester: Jesse Sheidlower
-
t0m: Tomas Doran <bobtfish@bobtfish.net>
Ulf Edvinsson