=head1 NAME

Catalyst::Manual::Tutorial - Getting started with Catalyst

=head1 DESCRIPTION

This document aims to get you up and running with Catalyst.

NOTE: THIS DOCUMENT IS STILL VERY MUCH IN AN EARLY DRAFT STATE.  SEE 
THE NOTES AT THE BOTTOM OF THE DOCUMENT.

=head2 Installation

The first step is to install Catalyst, and the simplest way to do this 
is to install the Catalyst bundle from CPAN:

    $ perl -MCPAN -e 'install Task::Catalyst'

This will retrieve Catalyst and a number of useful extensions and 
install them for you.


=head2 Setting up your application

Catalyst includes a helper script, C<catalyst.pl>, that will set up a 
skeleton application for you:

    $ catalyst MyApp
    
    created "MyApp"
    created "MyApp/script"
    created "MyApp/lib"
    created "MyApp/root"
    created "MyApp/root/static"
    created "MyApp/root/static/images"
    created "MyApp/t"
    created "MyApp/t/Model"
    created "MyApp/t/View"
    created "MyApp/t/Controller"
    created "MyApp/lib/MyApp"
    created "MyApp/lib/MyApp/Model"
    created "MyApp/lib/MyApp/View"
    created "MyApp/lib/MyApp/Controller"
    created "MyApp/lib/MyApp.pm"
    created "MyApp/Build.PL"
    created "MyApp/Makefile.PL"
    created "MyApp/README"
    created "MyApp/Changes"
    created "MyApp/t/01app.t"
    created "MyApp/t/02pod.t"
    created "MyApp/t/03podcoverage.t"
    created "MyApp/root/static/images/catalyst_logo.png"
    created "MyApp/root/static/images/btn_120x50_built.png"
    created "MyApp/root/static/images/btn_120x50_built_shadow.png"
    created "MyApp/root/static/images/btn_120x50_powered.png"
    created "MyApp/root/static/images/btn_120x50_powered_shadow.png"
    created "MyApp/root/static/images/btn_88x31_built.png"
    created "MyApp/root/static/images/btn_88x31_built_shadow.png"
    created "MyApp/root/static/images/btn_88x31_powered.png"
    created "MyApp/root/static/images/btn_88x31_powered_shadow.png"
    created "MyApp/root/favicon.ico"
    created "MyApp/script/myapp_cgi.pl"
    created "MyApp/script/myapp_fastcgi.pl"
    created "MyApp/script/myapp_server.pl"
    created "MyApp/script/myapp_test.pl"
    created "MyApp/script/myapp_create.pl"

This creates the directory structure shown, populated with skeleton 
files.

=head2 Testing out the sample application

You can test out your new application by running the server script that
Catalyst provides:

    $ cd MyApp
    $ script/myapp_server.pl 

    [...] [catalyst] [debug] Debug messages enabled
    [...] [catalyst] [debug] Loaded plugins:
    .------------------------------------------------------------------------------.
    | Catalyst::Plugin::Static::Simple                                             |
    '------------------------------------------------------------------------------'
    [...] [catalyst] [debug] Loaded dispatcher "Catalyst::Dispatcher"
    [...] [catalyst] [debug] Loaded engine "Catalyst::Engine::HTTP"
    [...] [catalyst] [debug] Found home "/home/users/me/MyApp"
    [...] [catalyst] [debug] Loaded Private actions:
    .--------------------------------------+---------------------------------------.
    | Private                              | Class                                 |
    +--------------------------------------+---------------------------------------+
    | /default                             | MyApp                                 |
    '--------------------------------------+---------------------------------------'
    
    [...] [catalyst] [info] MyApp powered by Catalyst 5.5
    You can connect to your server at http://localhost:3000

(Note that each line logged by Catalyst begins with a timestamp, which has
been replaced here with "C<...>" so that the text fits onto the lines.)

The server is now waiting for you to make requests of it.  Try using 
telnet to manually make a simple GET request of the server (when 
telnet responds with "Escape character is '^]'.", type "GET / HTTP/1.0"
and hit return twice):

    $ telnet localhost 3000
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    GET / HTTP/1.0
    
    HTTP/1.0 200 OK
    Date: Mon, 07 Nov 2005 14:57:39 GMT
    Content-Length: 5525
    Content-Type: text/html; charset=utf-8
    Status: 200
    X-Catalyst: 5.5

    [...]
    Connection closed by foreign host.
    $

You can see the full welcome message by visting
http://localhost:3000/ with your browser.

More trace messages will appear in the original terminal window:

    [...] [catalyst] [debug] **********************************
    [...] [catalyst] [debug] * Request 1 (0.063/s) [2148]
    [...] [catalyst] [debug] **********************************
    [...] [catalyst] [debug] Arguments are ""
    [...] [catalyst] [debug] "GET" request for "" from localhost
    [...] [catalyst] [info] Request took 0.046883s (21.330/s)
    .------------------------------------------------------------------+-----------.
    | Action                                                           | Time      |
    +------------------------------------------------------------------+-----------+
    | /default                                                         | 0.000000s |
    '------------------------------------------------------------------+-----------'

The server will continue running until you interrupt it.

The application can also be tested from the command line using the generated
helper script, C<script/myapp_test.pl>.

=head2 Getting your application invoked

Catalyst applications are usually run from mod_perl, but can also be
run as CGI or FastCGI scripts.  Running under mod_perl gives better 
performance, but for development purposes you may want to run your 
application as a CGI script, especially as changes to your application 
code take effect under CGI without having to restart the web server.

To run from mod_perl you need to add something like this to your Apache
configuration file:

    <Location /MyApp>
        SetHandler  perl-script
        PerlHandler MyApp
    </Location>

To run as a CGI script you need a wrapper script like:

    #!/usr/bin/perl -w
    
    use strict;
    use lib '/path/to/MyApp/lib';
    use MyApp;
    
    MyApp->run;

=head2 Examining the generated code

The generated application code is quite simple and looks something 
like this (comments removed):

    package MyApp;
    
    use strict;
    use warnings;
    
    use Catalyst qw/-Debug Static::Simple/;
    
    our $VERSION = '0.01';
    
    __PACKAGE__->config( name => 'MyApp' );
    __PACKAGE__->setup;
    
    sub default : Private {
        my ( $self, $c ) = @_;
    
        $c->response->body( $c->welcome_message );
    }
    
    1;

When the C<Catalyst> module is imported by the application code, 
Catalyst performs the first stage of its initialization.  This includes
loading the appropriate Engine module for the environment in which the 
application is running, loading any plugins and ensuring that the 
calling module (the application module) inherits from C<Catalyst> 
(which makes the Catalyst methods C<config> and C<setup> available to 
the application module).

The call to C<config> sets up configuration data for the application.  
The C<name> parameter is the only required configuration parameter.
You may also specificy a C<root> parameter, which is the path to the
directory where documents, images, and templates can be found.

Catalyst associates I<actions> with URLs and on receiving a request 
dispatches to the action that matches to request URL.  The call to 
C<setup> in the code above registers a default action.  With just 
this action registered the application will respond to all requests 
with the same welcome page.

As you see, the default action is defined as a Private action. 
Most private actions are not directly available from a web url. This
also includes the built-in actions, 'default', 'begin', 'end', and
'auto', although they will be called as part of some chains.  
The rest can only be reached by using C<forward>.

The call to the C<setup> method also triggers the second stage of 
Catalyst's initialization process.  In this phase Catalyst searches 
for any component modules, locating and registering any actions it 
finds in those modules.

Component modules have names prefixed with the application module name,
followed by C<Model>, C<View> or C<Controller> (or the optional short
forms: C<M>, C<V> or C<C>) followed by the component
name, for example:

    MyApp::Controller::ShoppingCart  # long (default) version
    MyApp::C::ShoppingCart           # short version 

    MyApp::Model::User               # long (default) version
    MyApp::M::User                   # short version

=head2 Extending the generated code

You can start extending the application by adding new actions:

    sub test1 : Global {
        my ( $self, $c ) = @_;
        $c->res->body('In a new test action #1');
    }
    sub default : Private {
        my ( $self, $c ) = @_;
        $c->res->body('Congratulations, MyApp is on Catalyst!');
    }

    # called like '/article/2005/06'
    sub archive_month : Regex('^article/(\d{4})/(\d{2})$') {
        my ( $self, $c ) = @_;

        my $datetime = DateTime->new(
            year  => $c->request->snippets->[0],
            month => $c->request->snippets->[1]
        );
    }

TODO: explain briefly about plugins, actions, and components

If the action is a Regex type, you can use capturing parentheses to
extract values within the matching URL (2005, 06 in the above
example). Those values are available in the $c->req->snippets
anonymous array. See L<Catalyst::Manual::Intro#Actions> for details.

=head2 Hooking in to Template Toolkit

One of the first things you will probably want to add to your 
application is a templating system for generating your output.  
Catalyst works well with Template Toolkit.  If you are unfamiliar with 
Template Toolkit then I suggest you look at L<http://tt2.org>, install 
C<Template>, read the documentation and play around with it, and have 
a look at the I<Badger Book> (I<Template Toolkit> by Darren 
Chamberlain, Dave Cross, and Andy Wardley, O'Reilly & Associates, 2004).

You can create a stub Template Toolkit view component by installing
L<Catalyst::View::TT> and using the create script that Catalyst set
up as part of the skeleton application:

    $ script/myapp_create.pl view TT TT
    
     exists "MyApp/lib/MyApp/View"
     exists "MyApp/t/View"
    created "MyApp/lib/MyApp/View/TT.pm"
    created "MyApp/t/View/TT.t"

this generates a view component named C<MyApp::View::TT>, which you 
might use by forwarding from your C<end> action:

    # In MyApp or MyApp::Controller::SomeController

    sub end : Private {
        my($self, $c) = @_;
        $c->forward('MyApp::V::TT');
    }

The generated TT view component simply subclasses the 
C<Catalyst::View::TT> class.  It looks like this (with the POD 
stripped out): 

    package My::App::V::TT;

    use strict;
    use base 'Catalyst::View::TT';

    1;

C<Catalyst::View::TT> initializes a Template Toolkit object with an 
options hash initialized with built-in default settings followed by 
the contents of the hash C<<%{__PACKAGE__->config()}>>.  You can
configure TT more to your needs by adding a C<new> method to the 
generated TT component:

    sub new {
        my $self = shift;
        $self->config->{PRE_PROCESS} = 'config/main';
        $self->config->{WRAPPER}     = 'site/wrapper';
        return $self->SUPER::new(@_);
    }

=head1 AUTHOR

Andrew Ford, C<A.Ford@ford-mason.co.uk>
Marcus Ramberg, C<mramberg@cpan.org>

As noted above, this document is at an alpha stage.  My plan for this 
document is as follows:

=over 4

=item 1

Expand this document fairly rapidly to cover topics relevant to
a newcomer to Catalyst, in an order that can be read sequentially

=item 2

Incorporate feedback 

=item 3

Revise the text 

=back

Placeholders are indicated by the words: TODO or CHECK 

Please send comments, corrections and suggestions for improvements to
A.Ford@ford-mason.co.uk

=head1 COPYRIGHT

This program is free software, you can redistribute it and/or modify 
it under the same terms as Perl itself.
