X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=blobdiff_plain;f=lib%2FCatalyst.pm;h=4cf485d0e99a0685744f7dab227f139c86aef751;hp=b6196354fb4129f372f25f3f46ca9a9c0fabc5b3;hb=cc95842fedcac58b2dc12c6ce547e22d3170351c;hpb=88879e92d58519c320438f8440a68d1648f4c099 diff --git a/lib/Catalyst.pm b/lib/Catalyst.pm index b619635..4cf485d 100644 --- a/lib/Catalyst.pm +++ b/lib/Catalyst.pm @@ -61,7 +61,7 @@ __PACKAGE__->response_class('Catalyst::Response'); # Remember to update this in Catalyst::Runtime as well! -our $VERSION = '5.7001'; +our $VERSION = '5.7006'; sub import { my ( $class, @arguments ) = @_; @@ -92,11 +92,12 @@ Catalyst - The Elegant MVC Web Application Framework catalyst.pl MyApp # add models, views, controllers - script/myapp_create.pl model Database DBIC::SchemaLoader dbi:SQLite:/path/to/db - script/myapp_create.pl view TT TT + script/myapp_create.pl model MyDatabase DBIC::Schema create=dynamic dbi:SQLite:/path/to/db + script/myapp_create.pl view MyTemplate TT script/myapp_create.pl controller Search # built in testserver -- use -r to restart automatically on changes + # --help to see all available options script/myapp_server.pl # command line testing interface @@ -224,6 +225,12 @@ Forces Catalyst to use a specific home directory, e.g.: use Catalyst qw[-Home=/usr/mst]; +This can also be done in the shell environment by setting either the +C environment variable or C; where C +is replaced with the uppercased name of your application, any "::" in +the name will be replaced with underscores, e.g. MyApp::Web should use +MYAPP_WEB_HOME. If both variables are set, the MYAPP_HOME one will be used. + =head2 -Log Specifies log level. @@ -262,8 +269,8 @@ cookies, HTTP headers, etc.). See L. Forwards processing to another action, by its private name. If you give a class name but no method, C is called. You may also optionally pass arguments in an arrayref. The action will receive the arguments in -C<@_> and C<$c-Ereq-Eargs>. Upon returning from the function, -C<$c-Ereq-Eargs> will be restored to the previous values. +C<@_> and C<< $c->req->args >>. Upon returning from the function, +C<< $c->req->args >> will be restored to the previous values. Any data Ced from the action forwarded to, will be returned by the call to forward. @@ -293,9 +300,13 @@ sub forward { my $c = shift; $c->dispatcher->forward( $c, @_ ) } =head2 $c->detach( $class, $method, [, \@arguments ] ) +=head2 $c->detach() + The same as C, but doesn't return to the previous action when processing is finished. +When called with no arguments it escapes the processing chain entirely. + =cut sub detach { my $c = shift; $c->dispatcher->detach( $c, @_ ) } @@ -304,7 +315,7 @@ sub detach { my $c = shift; $c->dispatcher->detach( $c, @_ ) } =head2 $c->res -Returns the current L object, q.v. +Returns the current L object, see there for details. =head2 $c->stash @@ -321,7 +332,7 @@ Catalyst). $c->stash( bar => 1, gorch => 2 ); # equivalent to passing a hashref # stash is automatically passed to the view for use in a template - $c->forward( 'MyApp::V::TT' ); + $c->forward( 'MyApp::View::TT' ); =cut @@ -497,8 +508,11 @@ Gets a L instance by name. $c->model('Foo')->do_stuff; -If the name is omitted, it will look for a config setting 'default_model', -or check if there is only one view, and return it if that's the case. +If the name is omitted, it will look for + - a model object in $c->stash{current_model_instance}, then + - a model name in $c->stash->{current_model}, then + - a config setting 'default_model', or + - check if there is only one model, and return it if that's the case. =cut @@ -507,8 +521,14 @@ sub model { return $c->_filter_component( $c->_comp_prefixes( $name, qw/Model M/ ), @args ) if $name; - return $c->component( $c->config->{default_model} ) - if $c->config->{default_model}; + if (ref $c) { + return $c->stash->{current_model_instance} + if $c->stash->{current_model_instance}; + return $c->model( $c->stash->{current_model} ) + if $c->stash->{current_model}; + return $c->model( $c->config->{default_model} ) + if $c->config->{default_model}; + } return $c->_filter_component( $c->_comp_singular(qw/Model M/), @args ); } @@ -531,9 +551,11 @@ Gets a L instance by name. $c->view('Foo')->do_stuff; -If the name is omitted, it will look for a config setting -'default_view', or check if there is only one view, and forward to it if -that's the case. +If the name is omitted, it will look for + - a view object in $c->stash{current_view_instance}, then + - a view name in $c->stash->{current_view}, then + - a config setting 'default_view', or + - check if there is only one view, and return it if that's the case. =cut @@ -542,8 +564,14 @@ sub view { return $c->_filter_component( $c->_comp_prefixes( $name, qw/View V/ ), @args ) if $name; - return $c->component( $c->config->{default_view} ) - if $c->config->{default_view}; + if (ref $c) { + return $c->stash->{current_view_instance} + if $c->stash->{current_view_instance}; + return $c->view( $c->stash->{current_view} ) + if $c->stash->{current_view}; + return $c->view( $c->config->{default_view} ) + if $c->config->{default_view}; + } return $c->_filter_component( $c->_comp_singular(qw/View V/) ); } @@ -574,9 +602,9 @@ sub views { =head2 $c->component($name) -Gets a component object by name. This method is no longer recommended, +Gets a component object by name. This method is not recommended, unless you want to get a specific component by full -class. C<$c-Econtroller>, C<$c-Emodel>, and C<$c-Eview> +class. C<< $c->controller >>, C<< $c->model >>, and C<< $c->view >> should be used instead. =cut @@ -616,8 +644,9 @@ Returns or takes a hashref containing the application's configuration. __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } ); -You can also use a L config file like myapp.yml in your -applications home directory. +You can also use a C, C or C config file +like myapp.yml in your applications home directory. See +L. --- db: dsn:SQLite:foo.db @@ -678,8 +707,8 @@ L. =head2 $c->path_to(@path) -Merges C<@path> with C<$c-Econfig-E{home}> and returns a -L object. +Merges C<@path> with C<< $c->config->{home} >> and returns a +L object. For example: @@ -796,6 +825,7 @@ You are running an old script! or (this will not overwrite existing files): catalyst.pl -scripts $class + EOF } @@ -805,7 +835,7 @@ EOF if (@plugins) { my $t = Text::SimpleTable->new(74); $t->row($_) for @plugins; - $class->log->debug( "Loaded plugins:\n" . $t->draw ); + $class->log->debug( "Loaded plugins:\n" . $t->draw . "\n" ); } my $dispatcher = $class->dispatcher; @@ -840,7 +870,7 @@ EOF my $type = ref $class->components->{$comp} ? 'instance' : 'class'; $t->row( $comp, $type ); } - $class->log->debug( "Loaded components:\n" . $t->draw ) + $class->log->debug( "Loaded components:\n" . $t->draw . "\n" ) if ( keys %{ $class->components } ); } @@ -889,6 +919,7 @@ sub uri_for { : [] ); $path = $c->dispatcher->uri_for_action($path, $captures); return undef unless defined($path); + $path = '/' if $path eq ''; } # massage namespace, empty if absolute path @@ -897,11 +928,13 @@ sub uri_for { $path ||= ''; $namespace = '' if $path =~ /^\//; $path =~ s/^\///; + $path =~ s/\?/%3F/g; 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( $_ ); @@ -909,7 +942,7 @@ sub uri_for { }; # join args with '/', or a blank string - my $args = ( scalar @args ? '/' . join( '/', @args ) : '' ); + my $args = ( scalar @args ? '/' . join( '/', map {s/\?/%3F/g; $_} @args ) : '' ); $args =~ s/^\/// unless $path; my $res = URI->new_abs( URI->new_abs( "$path$args", "$basepath$namespace" ), $base ) @@ -1013,7 +1046,7 @@ sub welcome_message {

Catalyst Logo

-

Welcome to the wonderful world of Catalyst. +

Welcome to the world of Catalyst. This MVC framework will make web development something you had never expected it to be: Fun, rewarding, and quick.

@@ -1021,10 +1054,14 @@ sub welcome_message {

That really depends on what you want to do. We do, however, provide you with a few starting points.

If you want to jump right into web development with Catalyst - you might want to check out the documentation.

-
perldoc Catalyst::Manual::Intro
-perldoc Catalyst::Manual::Tutorial
-perldoc Catalyst::Manual
+ you might want want to start with a tutorial.

+
perldoc Catalyst::Manual::Tutorial
+
+

Afterwards you can go on to check out a more complete look at our features.

+
+perldoc Catalyst::Manual::Intro
+
+

What to do next?

Next it's time to write an actual application. Use the helper scripts to generate controllers, @@ -1289,6 +1326,24 @@ sub finalize { $c->finalize_body; } + + if ($c->debug) { + my $elapsed = sprintf '%f', tv_interval($c->stats->getNodeValue); + my $av = sprintf '%.3f', ( $elapsed == 0 ? '??' : ( 1 / $elapsed ) ); + + my $t = Text::SimpleTable->new( [ 62, 'Action' ], [ 9, 'Time' ] ); + $c->stats->traverse( + sub { + my $action = shift; + my $stat = $action->getNodeValue; + $t->row( ( q{ } x $action->getDepth ) . $stat->{action} . $stat->{comment}, + $stat->{elapsed} || '??' ); + } + ); + + $c->log->info( + "Request took ${elapsed}s ($av/s)\n" . $t->draw . "\n" ); + } return $c->response->status; } @@ -1417,35 +1472,15 @@ sub handle_request { my $status = -1; eval { if ($class->debug) { - my $start = [gettimeofday]; - my $c = $class->prepare(@arguments); - $c->stats(Tree::Simple->new); - $c->dispatch; - $status = $c->finalize; - - my $elapsed = tv_interval $start; - $elapsed = sprintf '%f', $elapsed; - my $av = sprintf '%.3f', - ( $elapsed == 0 ? '??' : ( 1 / $elapsed ) ); - my $t = Text::SimpleTable->new( [ 62, 'Action' ], [ 9, 'Time' ] ); - - $c->stats->traverse( - sub { - my $action = shift; - my $stat = $action->getNodeValue; - $t->row( ( q{ } x $action->getDepth ) . $stat->{action} . $stat->{comment}, - $stat->{elapsed} || '??' ); - } - ); - - $class->log->info( - "Request took ${elapsed}s ($av/s)\n" . $t->draw ); - } - else { - my $c = $class->prepare(@arguments); - $c->dispatch; - $status = $c->finalize; + my $secs = time - $START || 1; + my $av = sprintf '%.3f', $COUNT / $secs; + my $time = localtime time; + $class->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***"); } + + my $c = $class->prepare(@arguments); + $c->dispatch; + $status = $c->finalize; }; if ( my $error = $@ ) { @@ -1499,20 +1534,17 @@ sub prepare { } ); + if ( $c->debug ) { + $c->stats(Tree::Simple->new([gettimeofday])); + $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION ); + } + # For on-demand data $c->request->{_context} = $c; $c->response->{_context} = $c; weaken( $c->request->{_context} ); weaken( $c->response->{_context} ); - if ( $c->debug ) { - my $secs = time - $START || 1; - my $av = sprintf '%.3f', $COUNT / $secs; - my $time = localtime time; - $c->log->info("*** Request $COUNT ($av/s) [$$] [$time] ***"); - $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION ); - } - # Allow engine to direct the prepare flow (for POE) if ( $c->engine->can('prepare') ) { $c->engine->prepare( $c, @arguments ); @@ -1738,7 +1770,7 @@ Reads a chunk of data from the request body. This method is designed to 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 Cconfig-E{parse_on_demand}> to use this +You have to set C<< MyApp->config->{parse_on_demand} >> to use this directly. =cut @@ -2013,6 +2045,7 @@ sub setup_home { } if ( $ENV{ uc($class) . '_HOME' } ) { + $class =~ s/::/_/g; $home = $ENV{ uc($class) . '_HOME' }; }