X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FManual%2FIntro.pod;h=728c5013700c0bdc18c81440778a9f7a0486fd2e;hb=5a8ed4fea844a2945eb98ae9ba76ba44b5d8ffdc;hp=c78366fe5be180b422f355830f28ce3e30418cb1;hpb=4a6895ce26f166f3b58aee8c691fce662f835865;p=catagits%2FCatalyst-Runtime.git diff --git a/lib/Catalyst/Manual/Intro.pod b/lib/Catalyst/Manual/Intro.pod index c78366f..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!". @@ -71,6 +71,8 @@ Use L or L. The best part is that Catalyst implements all this flexibility in a very simple way. +=over 4 + =item * B Components interoperate very smoothly. For example, Catalyst automatically makes a L object available in every component. Via the context, you can access the request object, share data between components, and control the flow of your application. Building a Catalyst application feels a lot like snapping together toy building blocks, and everything just works. @@ -91,6 +93,8 @@ Catalyst comes with a builtin, lightweight http server and test framework, makin Catalyst provides helper scripts to quickly generate running starter code for components and unit tests. +=back + =head2 Quickstart Here's how to install Catalyst and get a simple application up and running, using the helper scripts described above. @@ -101,13 +105,13 @@ Here's how to install Catalyst and get a simple application up and running, usin =head3 Setup - $ perl /path/to/catalyst My::App + $ catalyst.pl My::App $ cd My-App - $ perl bin/create controller My::Controller + $ script/create.pl controller My::Controller =head3 Run - $ perl bin/server + $ script/server.pl Now visit these locations with your favorite browser or user agent to see Catalyst in action: @@ -142,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; @@ -171,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: @@ -227,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 @@ -252,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/'. @@ -267,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. @@ -307,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. @@ -316,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: @@ -335,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; @@ -433,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. @@ -500,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; @@ -525,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 @@ -552,23 +530,26 @@ Catalyst has a built in http server for testing! (Later, you can easily use a mo Start your application on the command line... - perl -I/home/joeuser/myapp/lib -MCatalyst::Test=MyApp -e1 3000 - -or - - perl bin/server + script/server.pl ...then visit http://localhost:3000/ in a browser to view the output. You can also do it all from the command line: - perl -I/home/joeuser/myapp/lib -MCatalyst::Test=MyApp -e1 http://localhost/ + script/test.pl http://localhost/ -or +Have fun! - perl bin/test http://localhost/ +=head1 SUPPORT -Have fun! +IRC: + + Join #catalyst on irc.perl.org. + +Mailing-Lists: + + http://lists.rawmode.org/mailman/listinfo/catalyst + http://lists.rawmode.org/mailman/listinfo/catalyst-dev =head1 AUTHOR