From: Sebastian Riedel Date: Mon, 28 Mar 2005 19:29:20 +0000 (+0000) Subject: improved documentation X-Git-Tag: 5.7099_04~1670 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=5a8ed4fea844a2945eb98ae9ba76ba44b5d8ffdc;p=catagits%2FCatalyst-Runtime.git improved documentation --- diff --git a/lib/Catalyst.pm b/lib/Catalyst.pm index 1dd09c0..e5eb853 100644 --- a/lib/Catalyst.pm +++ b/lib/Catalyst.pm @@ -40,23 +40,19 @@ Catalyst - The Elegant MVC Web Application Framework use Catalyst qw/-Debug -Engine=CGI/; - __PACKAGE__->action( '!default' => sub { $_[1]->res->output('Hello') } ); + sub default : Private { $_[1]->res->output('Hello') } ); - __PACKAGE__->action( - 'index.html' => sub { - my ( $self, $c ) = @_; - $c->res->output('Hello'); - $c->forward('_foo'); - } - ); + sub index : Absolute('index.html') { + my ( $self, $c ) = @_; + $c->res->output('Hello'); + $c->forward('_foo'); + } - __PACKAGE__->action( - '/^product[_]*(\d*).html$/' => sub { - my ( $self, $c ) = @_; - $c->stash->{template} = 'product.tt'; - $c->stash->{product} = $c->req->snippets->[0]; - } - ); + sub product : Regex('/^product[_]*(\d*).html$/') { + my ( $self, $c ) = @_; + $c->stash->{template} = 'product.tt'; + $c->stash->{product} = $c->req->snippets->[0]; + } See also L diff --git a/lib/Catalyst/Helper.pm b/lib/Catalyst/Helper.pm index 71efd7d..4ce4b90 100644 --- a/lib/Catalyst/Helper.pm +++ b/lib/Catalyst/Helper.pm @@ -224,14 +224,10 @@ $name->config( root => '$base/root', ); -$name->action( - - '!default' => sub { - my ( \$self, \$c ) = \@_; - \$c->res->output('Congratulations, $name is on Catalyst!'); - }, - -); +sub default : Private { + my ( \$self, \$c ) = \@_; + \$c->res->output('Congratulations, $name is on Catalyst!'); +} =head1 NAME @@ -676,14 +672,11 @@ sub _mk_compclass { my $action = ''; $action = <<"EOF" if $type eq 'C'; -$app->action( - - '!?default' => sub { - my ( \$self, \$c ) = \@_; - \$c->res->output('Congratulations, $class is on Catalyst!'); - }, +sub default : Private { + my ( \$self, \$c ) = \@_; + \$c->res->output('Congratulations, $class is on Catalyst!'); +} -); EOF my $file = $self->{file}; return $self->mk_file( "$file", <<"EOF"); diff --git a/lib/Catalyst/Manual/Intro.pod b/lib/Catalyst/Manual/Intro.pod index 560274d..728c501 100644 --- a/lib/Catalyst/Manual/Intro.pod +++ b/lib/Catalyst/Manual/Intro.pod @@ -54,10 +54,10 @@ Catalyst allows you to dispatch any URLs to any application L, even via With Catalyst you register your actions and address them directly. For example: - MyApp->action( 'hello' => sub { + sub hello : Absolute { my ( $self, $context ) = @_; $context->response->output('Hello World!'); - }); + } Now http://localhost:3000/hello prints "Hello World!". @@ -146,10 +146,10 @@ In addition to the Model, View and Controller components, there's a single class # my_param_name => $my_param_value, ); - MyApp->action( '!default' => sub { + sub default : Private { my ( $self, $context ) = @_; $context->response->output('Catalyst rockz!'); - }); + } 1; @@ -175,10 +175,10 @@ Catalyst automatically blesses a Context object into your application class and As illustrated earlier in our URL-to-Action dispatching example, the Context is always the second method parameter, behind the Component object reference or class name itself. Previously we called it C<$context> for clarity, but most Catalyst developers just call it C<$c>: - MyApp->action( 'hello' => sub { + sub hello : Absolute { my ( $self, $c ) = @_; $c->res->output('Hello World!'); - }); + } The Context contains several important objects: @@ -231,20 +231,16 @@ The response is like the request, but contains just response-specific informatio The last of these, the stash, is a universal hash for sharing data among application components. For an example, we return to our 'hello' action: - MyApp->action( - - 'hello' => sub { - my ( $self, $c ) = @_; - $c->stash->{message} = 'Hello World!'; - $c->forward('!show-message'); - }, - - '!show-message' => sub { - my ( $self, $c ) = @_; - $c->res->output( $c->stash->{message} ); - }, + sub hello : Absolute { + my ( $self, $c ) = @_; + $c->stash->{message} = 'Hello World!'; + $c->forward('show-message'); + } - ); + show-message : Private { + my ( $self, $c ) = @_; + $c->res->output( $c->stash->{message} ); + } =head3 Actions @@ -256,13 +252,13 @@ Catalyst supports several ways to define Actions: =item * B - MyApp->action( 'foo/bar' => sub { } ); + sub bar : Absolute('foo/bar') { } Matches only http://localhost:3000/foo/bar. =item * B - MyApp->action( '/^foo(\d+)/bar(\d+)$/' => sub { } ); + sub bar : Regex('/^foo(\d+)/bar(\d+)$/') { } Matches any URL that matches the pattern in the action key, e.g. http://localhost:3000/foo23/bar42. The pattern must be enclosed with forward slashes, i.e. '/$pattern/'. @@ -271,19 +267,19 @@ If you use capturing parantheses to extract values within the matching URL (23, =item * B package MyApp::Controller::My::Controller; - MyApp->action( '?foo' => sub { } ); + sub foo : Relative { } -Matches http://localhost:3000/my_controller/foo. The action key must be prefixed with '?'. +Matches http://localhost:3000/my/controller/foo. The action key must be prefixed with '?'. Prefixing the action key with '?' indicates that the matching URL must be prefixed with a modified form of the component's class (package) name. This modified class name excludes the parts that have a pre-defined meaning in Catalyst ("MyApp::Controller" in the above example), replaces "::" with "_" and converts the name to lower case. See L for a full explanation of the pre-defined meaning of Catalyst component class names. =item * B - MyApp->action( '!foo' => sub { } ); + sub foo : Private { } Matches no URL, and cannot be executed by requesting a URL that corresponds to the action key. Private actions can be executed only inside a Catalyst application, by calling the C method: - $c->forward('!foo'); + $c->forward('foo'); See L for a full explanation of C. @@ -311,8 +307,8 @@ Called at the end of a request, after all matching actions are called. =head4 B - MyApp->action( '!?foo' => sub { } ); - MyApp->action( '!?default' => sub { } ); + sub foo : Private { } + sub default : Private { } The leading '!?' indicates that these are namespace-prefixed private actions. These override any application-wide private actions with the same names, and can be called only from within the namespace in which they are defined. Any private action can be namespace-prefixed, including the builtins. One use for this might be to give a Controller its own !?default, !?begin and !?end. @@ -320,12 +316,12 @@ The leading '!?' indicates that these are namespace-prefixed private actions. Th If you want to pass variable arguments at the end of a URL, you must use regex actions keys with '^' and '$' anchors, and the arguments must be separated with forward slashes (/) in the URL. For example, suppose you want to handle /foo/$bar/$baz, where $bar and $baz may vary: - MyApp->action( '/^foo$/' => sub { my ($self, $context, $bar, $baz) = @_; } ); + sub foo : Regex('/^foo$/') { my ($self, $context, $bar, $baz) = @_; } But what if you also defined actions for /foo/boo and /foo/boo/hoo ? - MyApp->action( '/foo/boo' => sub { .. } ); - MyApp->action( '/foo/boo/hoo' => sub { .. } ); + sub boo : Absolute('foo/boo') { .. } + sub hoo : Absolute('foo/boo/hoo') { .. } Catalyst matches actions in most specific to least specific order: @@ -339,42 +335,34 @@ So Catalyst would never mistakenly dispatch the first two URLs to the '/^foo$/' Control the application flow with the C method, which accepts the key of an action to execute. - MyApp->action( - - 'hello' => sub { - my ( $self, $c ) = @_; - $c->stash->{message} = 'Hello World!'; - $c->forward('!check-message'); - }, - - '!check-message' => sub { - my ( $self, $c ) = @_; - return unless $c->stash->{message}; - $c->forward('!show-message'); - }, + sub hello : Absolute { + my ( $self, $c ) = @_; + $c->stash->{message} = 'Hello World!'; + $c->forward('check-message'); + } - '!show-message' => sub { - my ( $self, $c ) = @_; - $c->res->output( $c->stash->{message} ); - }, + sub check-message : Private { + my ( $self, $c ) = @_; + return unless $c->stash->{message}; + $c->forward('show-message'); + } - ); + sub show-message : Private { + my ( $self, $c ) = @_; + $c->res->output( $c->stash->{message} ); + } You can also forward to classes and methods. - MyApp->action( - - 'hello' => sub { - my ( $self, $c ) = @_; - $c->forward(qw/MyApp::M::Hello say_hello/); - }, - - 'bye' => sub { - my ( $self, $c ) = @_; - $c->forward('MyApp::M::Hello'); - }, + sub hello : Absolute { + my ( $self, $c ) = @_; + $c->forward(qw/MyApp::M::Hello say_hello/); + } - ); + sub bye : Absolute { + my ( $self, $c ) = @_; + $c->forward('MyApp::M::Hello'); + } package MyApp::M::Hello; @@ -437,19 +425,15 @@ To show how to define views, we'll use an already-existing base class for the L< This gives us a process() method and we can now just do $c->forward('MyApp::V::TT') to render our templates. The base class makes process() implicit, so we don't have to say C<$c-Eforward(qw/MyApp::V::TT process/)>. - MyApp->action( - - 'hello' => sub { - my ( $self, $c ) = @_; - $c->stash->{template} = 'hello.tt'; - }, - - '!end' => sub { - my ( $self, $c ) = @_; - $c->forward('MyApp::View::TT'); - }, + sub hello : Absolute { + my ( $self, $c ) = @_; + $c->stash->{template} = 'hello.tt'; + } - ); + sub end : Private { + my ( $self, $c ) = @_; + $c->forward('MyApp::View::TT'); + } You normally render templates at the end of a request, so it's a perfect use for the !end action. @@ -504,20 +488,16 @@ Catalyst automatically loads table layouts and relationships. Use the stash to p root => '/home/joeuser/myapp/root' ); - __PACKAGE__->action( - - '!end' => sub { - my ( $self, $c ) = @_; - $c->stash->{template} ||= 'index.tt'; - $c->forward('MyApp::V::TT'); - }, - - 'view' => sub { - my ( $self, $c, $id ) = @_; - $c->stash->{item} = MyApp::M::CDBI::Foo->retrieve($id); - } + sub end : Private { + my ( $self, $c ) = @_; + $c->stash->{template} ||= 'index.tt'; + $c->forward('MyApp::V::TT'); + } - ); + sub view : Absolute { + my ( $self, $c, $id ) = @_; + $c->stash->{item} = MyApp::M::CDBI::Foo->retrieve($id); + } 1; @@ -529,26 +509,20 @@ Multiple Controllers are a good way to separate logical domains of your applicat package MyApp::C::Login; - MyApp->action( - '?sign-in' => sub { }, - '?new-password' => sub { }, - '?sign-out' => sub { }, - ); + sign-in : Relative { } + new-password :Relative { } + sign-out : Relative { } package MyApp::C::Catalog; - MyApp->action( - '?view' => sub { }, - '?list' => sub { }, - ); + sub view : Relative { } + sub list : Relative { } package MyApp::C::Cart; - MyApp->action( - '?add' => sub { }, - '?update' => sub { }, - '?order' => sub { }, - ); + sub add : Relative { } + sub update : Relative { } + sub order : Relative { } =head3 Testing