improved documentation
Sebastian Riedel [Mon, 28 Mar 2005 19:29:20 +0000 (19:29 +0000)]
lib/Catalyst.pm
lib/Catalyst/Helper.pm
lib/Catalyst/Manual/Intro.pod

index 1dd09c0..e5eb853 100644 (file)
@@ -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<Catalyst::Manual::Intro>
 
index 71efd7d..4ce4b90 100644 (file)
@@ -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");
index 560274d..728c501 100644 (file)
@@ -54,10 +54,10 @@ Catalyst allows you to dispatch any URLs to any application L<Actions>, 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<Literal>
 
-    MyApp->action( 'foo/bar' => sub { } );
+    sub bar : Absolute('foo/bar') { }
 
 Matches only http://localhost:3000/foo/bar.
 
 =item * B<Regex>
 
-    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<Namespace-Prefixed>
 
     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</Components> for a full explanation of the pre-defined meaning of Catalyst component class names.
 
 =item * B<Private>
 
-    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<forward> method:
 
-    $c->forward('!foo');
+    $c->forward('foo');
 
 See L</Flow Control> for a full explanation of C<forward>.
 
@@ -311,8 +307,8 @@ Called at the end of a request, after all matching actions are called.
 
 =head4 B<Namespace-Prefixed Private Actions>
 
-    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<forward> 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-E<gt>forward(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