Oh, the humiliation of forgetting to add a test plugin :(
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Manual / Tutorial.pod
CommitLineData
83cea649 1=head1 NAME
2
3Catalyst::Manual::Tutorial - Getting started with Catalyst
4
5=head1 DESCRIPTION
6
7This document aims to get you up and running with Catalyst.
8
83cea649 9=head2 Installation
10
61b1e958 11The first step is to install Catalyst, and the simplest way to do this
12is to install the Catalyst bundle from CPAN:
83cea649 13
d538823f 14 $ perl -MCPAN -e 'install Task::Catalyst'
83cea649 15
61b1e958 16This will retrieve Catalyst and a number of useful extensions and
587d5860 17install them for you. This process might not be totally painless
18though, and you might want to look at CatInABox
19L<http://use.perl.org/~jk2addict/journal/28071>, especially if you are
20on a system that lacks a compiler.
83cea649 21
22
587d5860 23=head2 The very basics - Setting up the skeleton application.
83cea649 24
61b1e958 25Catalyst includes a helper script, C<catalyst.pl>, that will set up a
26skeleton application for you:
83cea649 27
387e4c50 28 $ catalyst MyApp
b248fa4a 29
387e4c50 30 created "MyApp"
31 created "MyApp/script"
587d5860 32 ... output snipped
387e4c50 33 created "MyApp/script/myapp_create.pl"
83cea649 34
587d5860 35This creates the directory structure, populated with skeleton
61b1e958 36files.
83cea649 37
587d5860 38=head2 Testing out the skeleton application
83cea649 39
40You can test out your new application by running the server script that
07e73f82 41Catalyst provides:
83cea649 42
387e4c50 43 $ cd MyApp
44 $ script/myapp_server.pl
b33ed88c 45
b460ad78 46 [...] [catalyst] [debug] Debug messages enabled
387e4c50 47 [...] [catalyst] [debug] Loaded plugins:
48 .------------------------------------------------------------------------------.
49 | Catalyst::Plugin::Static::Simple |
50 '------------------------------------------------------------------------------'
b33ed88c 51 [...] [catalyst] [debug] Loaded dispatcher "Catalyst::Dispatcher"
61b1e958 52 [...] [catalyst] [debug] Loaded engine "Catalyst::Engine::HTTP"
387e4c50 53 [...] [catalyst] [debug] Found home "/home/users/me/MyApp"
54 [...] [catalyst] [debug] Loaded Private actions:
55 .--------------------------------------+---------------------------------------.
56 | Private | Class |
57 +--------------------------------------+---------------------------------------+
58 | /default | MyApp |
59 '--------------------------------------+---------------------------------------'
b248fa4a 60
387e4c50 61 [...] [catalyst] [info] MyApp powered by Catalyst 5.5
62 You can connect to your server at http://localhost:3000
b33ed88c 63
64(Note that each line logged by Catalyst begins with a timestamp, which has
61b1e958 65been replaced here with "C<...>" so that the text fits onto the lines.)
b460ad78 66
61b1e958 67The server is now waiting for you to make requests of it. Try using
68telnet to manually make a simple GET request of the server (when
69telnet responds with "Escape character is '^]'.", type "GET / HTTP/1.0"
70and hit return twice):
83cea649 71
72 $ telnet localhost 3000
73 Trying 127.0.0.1...
74 Connected to localhost.
75 Escape character is '^]'.
76 GET / HTTP/1.0
b248fa4a 77
387e4c50 78 HTTP/1.0 200 OK
79 Date: Mon, 07 Nov 2005 14:57:39 GMT
80 Content-Length: 5525
81 Content-Type: text/html; charset=utf-8
83cea649 82 Status: 200
387e4c50 83 X-Catalyst: 5.5
83cea649 84
387e4c50 85 [...]
83cea649 86 Connection closed by foreign host.
87 $
88
387e4c50 89You can see the full welcome message by visting
90http://localhost:3000/ with your browser.
91
83cea649 92More trace messages will appear in the original terminal window:
93
387e4c50 94 [...] [catalyst] [debug] **********************************
95 [...] [catalyst] [debug] * Request 1 (0.063/s) [2148]
96 [...] [catalyst] [debug] **********************************
97 [...] [catalyst] [debug] Arguments are ""
61b1e958 98 [...] [catalyst] [debug] "GET" request for "" from localhost
387e4c50 99 [...] [catalyst] [info] Request took 0.046883s (21.330/s)
100 .------------------------------------------------------------------+-----------.
101 | Action | Time |
102 +------------------------------------------------------------------+-----------+
103 | /default | 0.000000s |
104 '------------------------------------------------------------------+-----------'
83cea649 105
106The server will continue running until you interrupt it.
107
108The application can also be tested from the command line using the generated
387e4c50 109helper script, C<script/myapp_test.pl>.
83cea649 110
8d47005f 111=head2 Getting started
83cea649 112
8d47005f 113So you picked Catalyst. Good choice. I assume you've installed it as
114well. For this tutorial you will also need the following modules:
83cea649 115
8d47005f 116L<Catalyst::Plugin::Session>
83cea649 117
8d47005f 118L<Catalyst::Plugin::Session::Store::File>
83cea649 119
8d47005f 120L<Catalyst::Plugin::Session::State::Cookie>
83cea649 121
8d47005f 122L<Catalyst::Plugin::Authentication>
83cea649 123
587d5860 124L<Catalyst::Plugin::Authentication::Store::Minimal>
125
126L<Catalyst::Plugin::Authentication::::Minimal>
127
128L<Catalyst::Plugin::Authentication::Credential::Password>
129
8d47005f 130L<Catalyst::Plugin::Authorization::Roles>
83cea649 131
8d47005f 132L<DBD::SQLite>
83cea649 133
8d47005f 134...
135
136To get started all you need to do is type:
137
138B<catalyst.pl tutorial>
139
140This should create a directory called F<tutorial> and fill it with the
141default (standard) Catalyst installation. Change to this directory
142because we will be running all further commands from inside the
143F<tutorial> directory.
144
145If you now run the built-in mini-server with
146B<script/tutorial_server.pl>, it will show some standard debug messages
147in the console screen (more about those in a minute), and then inform
148you that you can now connect to the test server on port 3000. Point your
149browser at localhost:3000 to see the built-in catalyst welcome screen.
150
151The other important thing catalyst.pl did was create your root
152controller. This file is a standard perl module like all the other
153controllers that you might add to your application. It lives in the
154F<lib/> directory, and will have the same name as you supplied to the
155command above, in our case it is F<tutorial.pm>. Alongside this file is
156a directory of the same name, which is the top level namespace for the
157entire application. Thus every other module we create will be
158"tutorial::something";
159
160The root controller is used to load plugins, to configure the
161application and its plugins, and for generic private actions. We will
162explain more about those later.
163
164=head2 Debugging
165
166The simplest way to debug your Catalyst application is to run it using
b248fa4a 167the built-in mini-server as described in L<Getting started>.
8d47005f 168
169If you want to output any debugging information to the console, then
170call C<< $context->log->debug() >>, passing it a string to output. For
171data structures, use Data::Dumper and call C<<
172$context->log->debug(Dumper($structure)) >>
173
174=head2 Model/View/Controller
175
176The recommended method for code organization in a Catalyst application
177is known as the "Model View Controller" design pattern (also referred to
178"MVC"). The point of the MVC pattern is to divorce the dependencies of
179parts of the application from each other, and give them standard
180interfaces. Following this theory of organization should give your code
181all the benefits of modularity. The main benefits are interchangability
182of parts and reusable code.
183
184Thus you could replace your file data storage with a database or your
185oracle database with a mysql database and not have to change any of your
186controlling or view logic. Or you could later decide to output
187information from your application as RSS instead of HTML just by adding
188a new view module.
189
190=head3 Model
191
192Models deal with the storage of data. For a complex website, you may
193need multiple varied data sources, each will have it's own model class
194that provides an abstracted interface to it. In this tutorial we are
195going to be using a simple database.
196
197=head3 View
198
199Views are used to display information to the user. In a web framework,
200it is generally used to output HTML to the browser. As mentioned
201previously, views can also be used to output RSS or any other kind of
202data format. One easy way to do this with Catalyst is to use a
203templating system such as Template Toolkit. If outputting HTML is all
204you are going to do, then you will probably only need one view.
205
206=head3 Controller
207
208A controller deals with reacting to user choices, and thus controls what
209the application does. Since this is a web framework, Catalyst
210controllers are frequently used to react directly to URLs requested by
211the user. This tutorial will describe the simplest way of using
212controllers, where each path or part of a path is assigned its own
213action (or subroutine). More complex controlling mechanisms will be
214mentioned briefly, and can be read about in detail in the manual.
215
216
217=head2 Controlling
218
219Now lets write our first bit of application code. First, we would like
220our application to greet our users. We'll assume for now that our users
221will be sent to the I<users/greet> URL. To create a controller that
222serves the I<users> namespace, we run the following command in our
223F<tutorial> directory:
224
225B<script/tutorial_create.pl controller Users>
226
227This will create a Users.pm in F<lib/tutorial/Controller>. Open this
228file in an editor and take a look. You will notice there is some
229commented out code which we will ignore for now. To make something
230happen when our URL is visited, we will write a "greet" action which
231looks like this:
232
587d5860 233 sub greet : Local {
234 my ($self, $c) = @_;
8d47005f 235
587d5860 236 my $name = $context->req->param('name');
237 $c->log->debug("Got name: $name\n");
8d47005f 238
587d5860 239 if ($c->req->method eq 'POST') {
240 if(!$name) {
241 $c->stash->{message} = 'Please fill in a name!';
242 }
243 else {
244 $c->stash->{message} = "Hello $name!";
245 }
61b1e958 246 }
587d5860 247 $c->stash->{template} = 'greet.tt';
248 }
8d47005f 249
250Whew! So, what does all this do? Lets take it one step at a time.
251The subroutine declaration gives the action a name. To the right of the
252name there is an attribute type that looks like this: " : Local". That
253defines which URIs will translate to this action. "Local", matches
254exactly one URI: /users/greet. The URI matched by "Local" is composed
255from the namespace minus the tutorial::controller portion, that is
256common to all controllers, and the action name itself. Because it is a
257URI, we use forward slashes instead of double colons. So, in summary,
258when a user requests http://localhost:3000/users/greet" the "greet"
587d5860 259action defined above in the Users controller will be executed.
8d47005f 260
261The second line retrieves the parameters Catalyst gives us when it calls
262our method. The first is the instance of our Users class, and the second
587d5860 263is commonly called the context, and named $c. The context is the magical
264object containing any information you need from catalyst, or want to send to
8d47005f 265it. You will see it used frequently in Catalyst applications, and a list
266of all its methods is available in the L<Catalyst> POD.
267
587d5860 268On the third line we use the ->param method of the $context request
8d47005f 269object to retrieve one of the query parameters, just like in L<CGI>.
270
587d5860 271On the fourth, we make a debug output of this object on the server console,
272or the error log if running under CGI or mod_perl.
8d47005f 273
587d5860 274Next, if we have a post request, we check if the name field contains anything
275(or is "true"), if it isnt, we assign an error message to a "message" field in
276the stash. The stash is yet another method of the context object, it allows us
277to pass data on to other methods we call later, most usefully the View modules.
8d47005f 278
279If the username did contain a value, then we just set our message to
280greet the user by name.
281
282Finally, we set the special "template" variable in the stash to the name
283of the template we want our view to use to display this page.
8d47005f 284
285=head2 Viewing
286
287Ok, so reacting and checking the users data is all fine, but how do we
288actually display the page/form in the first place, and our results? As
289previously mentioned, we'll use Template Toolkit for our viewing. To
290create out TT based view, just run the following command:
291
292B<script/tutorial_create.pl view TToolkit TT>
293
294Notice that this time we not only gave it the type of module we wanted
295to create (a view), and a name, but also a third argument, "TT". This is
296a Catalyst helper module, which will make a standard template toolkit
297module for you. And that's all you need to do there.
298
299To use the view, the easiest way is to set up a standard "end" action.
300This a private action which will not be matched to a path like our
301"greet" action, but instead will be called after all other processing is
302done. Only one end action will be called, if there is one in a
303controller, it will be prefered over one in the application module, and
304so on.
b248fa4a 305
8d47005f 306Since we're writing a simple application, just add an end action like
307this to F<tutorial.pm>:
308
309 sub end : Private
310 {
311 my ($self, $context) = @_;
587d5860 312 $context->forward('tutorial::View::TToolkit') unless $c->res->body();
8d47005f 313 }
314
315The first line declares the end sub, and marks it as a Private action.
316(The second and last attribute type we'll be using). The second line
317collects our standard parameters as shown in the controller's greet action.
318
319The third line directs Catalyst to pass processing on to our TToolkit
320view. The forward method, when just passed a class name, calls process
321on that classs. The standard TT view's process method renders the
322template named in the templare variable in the stash, using all the
323other variables in the stash as values to fill it in.
324
325NB: This is such a common way to end you processing that there is a
326plugin which does it for you: L<Catalyst::Plugin::DefaultEnd>.
327
328Template Toolkit also has access to the entire context object via "c",
329for example, using [% c.config.name %] in our template will output
330"tutorial", our project name.
331
332All that remains is to create a simple template called "greet.tt",
587d5860 333containing a form with a text field called "name" like below.
334
335 <p>[%message%]</p>
336 <form action="[%c.req.uri%]" method="post">
337 <input type="text" name="name"/>
338 </form>
8d47005f 339
587d5860 340In the example above, we use [%c.req.uri%], since we're posting to ourself.
341if we post to another action, we commonly use the uri_for method, like this:
342
343 [% c.uri_for('/users/greet')%]
344
345Place this file in the F<root> directory, . By default, templates are
346searched for here, but we can change that, which brings us to..
8d47005f 347
348=head2 Configuring
349
350As previously mentioned, the configuration of modules, plugins and so on
351is done in the main application file. This is especially true for bits
352which need to be done before an instance of them is created, for example
353Template Toolkit.
354
355The TT View looks for its templates in the F<root> directory by default.
356Since this is also the directory that static files go in, we'd rather
357have a separate F<templates> directory. To do this, change the config
358call in F<tutorial.pm> like this:
359
360 __PACKAGE__->config( name => 'tutorial',
361 'View::TToolkit' => {
362 'INCLUDE_PATH' => __PACKAGE__->path_to('templates')
363 }
364 );
365
366And move the F<greet.tt> file from F<root> to the F<templates> directory
367(after creating it).
368
369Now we can run our application again by killing (ctrl-c) and restarting
370B<script/tutorial_server.pl>. Try connecting to
371I<localhost:3000/users/greet> with a browser and see what happens. What
372happens if you try to visit I<localhost:3000/users> ?
373
374=head2 Users and Authenticating
375
376One of the many reasons to write dynamic websites instead of just using static
377HTML, is to allow us to produce different content for different users, as well
378 as just restricting access to pages (which we could do with just Apaches
379htpasswd system).
380
381In this tutorial, we will just be using basic authentication, when writing
382a real application, you'll want to use a database or other secure store to
383contain your user data.
384
385To add authentication, all we need to do is add the
386L<Catalyst::Plugin::Authentication> module to our main application file. Then
387we need to pick a storage method (one of the
388L<Catalyst::Plugin::Authentication::Store> modules), and a method of verifying
389the users credentials (one of the
390L<Catalyst::Plugin::Authentication::Credential> modules), so just edit
391F<tutorial.pm> to look like this:
392
393 use Catalyst qw/-Debug Static::Simple Authentication
394 Authentication::Store::Minimal
395 Authentication::Credential::Password/;
396
397To configure, add some users to the config call, for example:
398
399 authentication => { 'users' =>
400 { 'fred' =>
401 { 'password' => 'fred1234',
402 }
403 }
404 }
405
406Generally, setting up configuration data for plugins is done based on the
407type of plugin. Check the documentation of the plugin for exact details. The
408details of this one are in L<Catalyst::Plugin::Authentication::Store::Minimal>.
409
410Since our user data is in the config, we can update it at runtime, and thus
411add users dynamically. (Of course, to keep them permanently we'll need to
412export our data to disk and read it back into the config on startup)
413
414To allow creation of new users we'll add a create action to our Users
415controller.
416
417 sub create : Local
418 {
587d5860 419 my ($self, $c) = @_;
8d47005f 420 my ($username, $passwd1, $passwd2) = map { $context->req->param($_)}
421 ('username', 'password', 'passwordverify');
422
423 if($username && $passwd1 && $passwd2)
424 {
587d5860 425 if($c->config->{authentication}{users}{$username})
8d47005f 426 {
587d5860 427 $c->stash->{message} = 'Sorry that user already exists';
428 $c->stash->{username} = $username;
8d47005f 429 }
430 elsif($passwd1 eq $passwd2)
431 {
587d5860 432 $c->config->({%{$context->config},
8d47005f 433 ($username => { password => $passwd1}});
587d5860 434 $c->stash->{message} = 'User created!';
8d47005f 435 }
436 else
437 {
587d5860 438 $c->stash->{username} = $username;
439 $c->stash->{message} = 'Passwords don't match!';
8d47005f 440 }
441 }
587d5860 442 $c->stash->{template} = 'usercreate.tt';
8d47005f 443 }
444
445All this is doing is checking that all the appropriate fields are filled,
446the password fields contain the same data, and then adding the user to the
447config hash. All the checks produce a message which can be displayed to
448the user via the View.
449
450So our that users can login, we need a login page:
451
452 sub login : Local
453 {
454 my ($self, $context) = @_;
587d5860 455 $c->stash->{template} = 'userlogin.tt';
456 if(!$c->login()) {
457 $c->stash->{message} = 'Login failed.';
61b1e958 458 }
8d47005f 459 }
460
461Verrrry simple. Since Credential::Password's "login" call extracts the
462username/password data from the query itself (assuming we use a standard
463name for our form fields), we don't have to do anything but call it.
464
465To keep the user logged in, all we need to do is add the Session modules to
466our collection, and the Auth modules will automatically use them;
467
468 use Catalyst qw/-Debug Static::Simple Authentication
469 Authentication::Store::Minimal
470 Authentication::Credential::Password
471 Session Session::Store::File Session::State::Cookie/;
472
473Magic!
474
475=head2 Authorising
476
477Authentication is about verifying users, Authorisation is about allowing
478them to do things. Catalyst currently has two Authorisation modules,
479Roles and ACL. The Roles module allows you to define groups which you
480can assign your users to, and then allow access to areas of your website
481to the groups. The ACL module lets you do more fine grained
482access/restriction by allowing of denying access however you like. (It
483also supports Roles as done by the roles module.)
484
485Adding Roles via the Minimal store we are already using is quite simple,
486we just add a roles key to each user, defining the names of the roles
487they belong to.
488
489 authentication => { 'users' =>
490 { 'fred' =>
491 { 'password' => 'fred1234',
492 'roles' => ['admin']
493 }
494 }
495 }
496
497We need an interface for our admins to administer the roles, i.e. assign
498the users to groups. To restrict access to certain actions, we just need
499to call C<< $context->check_user_roles() >> in each action. So we can
500make a restricted I<localhost:3000/users/groups> page like this:
501
502 sub groups : Local
503 {
504 my ($self, $context) = @_;
587d5860 505 if($c->check_user_roles('admin')) {
8d47005f 506 # Now we can do things only an admin will see
587d5860 507 if(my $params = $c->req->params) {
508 my $users = $c->config->{authentication}{users};
509 foreach my $u (keys %$params) {
8d47005f 510 $users->{$u}{roles} = $params->{$u} if($users->{$u});
511 }
512 $context->stash->{message} = 'Updated user roles!';
513 }
587d5860 514 else {
8d47005f 515 $context->stash->{users} = $context->config->{authentication};
516 }
517 $context->stash->{template} = 'usersgroups.tt';
61b1e958 518 }
587d5860 519 else {
8d47005f 520 $context->stash->{message} = 'Admins Only!';
521 $context->stash->{template} = 'error.tt';
522 }
523 }
524
525What we are doing here is checking whether the logged in user (used by
526default in the check_user_roles method), is a member of the admin group.
527If it is, then we display the usergroups template, and update the users
528hash as required. Otherwise, we just show the user an error page.
529
530And that's all there is to it.
531
532=head2 Data Storage (Modelling)
533
534Whether we want our users to be able to contribute to our website, or just
535create it from changeable data, we need to store the data somewhere. Generally
536this is done using a database, models can also be other data sources, for
537example another website, or RSS feeds.
538
539If you have or want a database, there are still choices to be made, there are
540several modules about for accessing databases via OO. The best known are
541probably L<Class::DBI> and L<DBIx::Class>. Catalyst supports making models
542using either of these.
543
544For a simple example, we will allow our users to store their favourite
545greeting in our database. Create a table called "greetings" in a database,
546that contains a "user" field and a "greeting" field. The simplest way to
547create a model of your database is to use these helper modules, for example
548with L<DBIx::Class>:
549
550B<script/tutorial_create.pl model UserData DBIC dbi:SQLite:/path/to/mydb.db>
551
552This will cause the DBIx::Class Loader to inspect your database, and create a
553module in the Model::UserData namespace for each table in your database.
554
555Now we need a form for our users to enter/edit their personal greetings in,
556we'll make a I<localhost:3000/users/editgreeting> page:
557
587d5860 558 sub editgreeting : Local {
559 my ($self, $c) = @_;
560 if($c->req->params->{greeting}) {
561 if(!$c->user_exists) {
562 $c->stash->{message} = "You're not logged in!";
8d47005f 563 }
587d5860 564 else {
8d47005f 565 my $grtable = $context->model('UserData::Greetings');
566 my $record = $grtable->find_or_create(user => $context->user->id);
567 $record->greeting($context->req->params->{greeting};
568 $record->update;
587d5860 569 $c->stash->{message} = 'Greeting updated';
8d47005f 570 }
571 }
587d5860 572 $c->stash->{template} = 'usersgreeting.tt';
8d47005f 573 }
83cea649 574
8d47005f 575Using C<< $context->user_exists >> from the Authentication plugin, this checks
576whether the user is logged in already. If they are, if they are, and they have
577entered a new greeting, we use DBIx::Class' C<find_or_create> to fetch or
578create a new record in the greetings table for the user. Once we have the
579record, we change the value of the greeting field, and call C<update> to store
580the new value in the database.
eff5f524 581
8d47005f 582=head2 Engines (Apache and FastCGI)
83cea649 583
8d47005f 584Now that we have the basics together, we can try running our application on a
585"real" server instead of just using the test server that catalyst comes
586with. L<Catalyst::Engine> is the module used to implement various types of
587servers to run it on. The currect popular ones are Apache and FastCGI. To
588force the use of a particular engine we can use the -Engine flag to Catalyst:
b460ad78 589
8d47005f 590 use Catalyst qw/-Engine=Apache/;
b460ad78 591
8d47005f 592or
b460ad78 593
8d47005f 594 use Catalyst qw/-Engine=FastCGI/;
b460ad78 595
8d47005f 596=head3 Apache
b460ad78 597
8d47005f 598Apache also needs configuring, we need to tell it to load your
599application. You can either use Catalyst for your entire website, or
600subsections. Use the Location directive to choose a path to run your
601application under:
b460ad78 602
8d47005f 603 <Location />
604 SetHandler perl-script
605 PerlResponseHandler MyApp
606 </Location>
b460ad78 607
8d47005f 608You will need to install the perl modules of your application into one of
609perls library directories, as listed by B<perl -V>, so that Apache can find
610them. Alternatively you can use the C<PerlSwitches> directive to tell Apache
611where to look:
b460ad78 612
8d47005f 613 PerlSwitches -I/path/to/MyApp/
b460ad78 614
8d47005f 615These instructions are for using Apache2 and mod_perl 2.0. If you are using
616mod_perl 1.3 or 1.99, please refer to either L<Catalyst::Engine::Apache::MP13>
617or L<Catalyst::Engine::Apache2::MP19> for slightly different ways to do it.
b460ad78 618
8d47005f 619If you wish to ensure that Apache pre-loads your application, use the
620PerlModule directive. This means that there will be less of a delay when your
621application is accessed.
b460ad78 622
8d47005f 623 PerlModule MyApp
b460ad78 624
8d47005f 625=head3 FastCGI
b460ad78 626
8d47005f 627These instructions apply to the use of C<mod_fastcgi> under Apache (either 1 or 2 series).
b460ad78 628
8d47005f 629There are 3 ways to attach a program to a URL with C<mod_fastcgi>; we'll examine all of them, and explain how to avoid having the C<myapp_fastcgi.pl> substring in the user-visible URLs.
b460ad78 630
8d47005f 631In all of these examples, we assume that the C<DocumentRoot> is C</var>, that our app is called C<MyApp> and is kept in C</usr>, that you want the users to access the app either from the root of the server-uri-space, or from C</theapp>. We also assume that the general FastCGI settings (C<FastCgiIpcDir>, loading the module) are already correct (they don't depend on Catalyst or your application layout).
83cea649 632
8d47005f 633=head4 static application
634
635In this setup, you tell C<mod_fastcgi> that a particular I<file> is to be run as a FastCGI handler. Put this somewhere in Apache's configuration:
636
637 FastCgiServer /usr/apps/MyApp/script/myapp_fastcgi.pl
638 Alias / /usr/apps/MyApp/script/myapp_fastcgi.pl/
639
640If you want your app under C</theapp>, change the C<Alias> line to:
641
642 Alias /theapp /usr/apps/MyApp/script/myapp_fastcgi.pl
643
644Note the detail of the trailing C</ >: this is a general rule af the C<Alias> directive, both sides must end with C</ >, or both must not; you can't have one with C</ > and the other without, or strange things happen.
645
646=head4 dynamic application
647
648In this setup, you tell C<mod_fastcgi> that certain files are to be treated as FastCGI handlers, in the same way you have to tell C<mod_cgi>. Put this in the configuration:
649
650 FastCgiConfig -autoUpdate
651
652 <Directory /usr/apps/MyApp/script>
653 Options +ExecCGI
654 <Files *_fastcgi.pl>
655 SetHandles fastcgi-script
656 </Files>
657 </Directory>
83cea649 658
8d47005f 659 Alias / /usr/apps/MyApp/script/myapp_fastcgi.pl/
b460ad78 660
8d47005f 661Again, if you want your app under C</theapp>, change the C<Alias> line to:
b460ad78 662
8d47005f 663 Alias /theapp /usr/apps/MyApp/script/myapp_fastcgi.pl
b460ad78 664
8d47005f 665=head4 external server
b460ad78 666
8d47005f 667In this setup, the application is started separately from Apache, and communicates via a socket with C<mod_fastcgi>. This can be useful if you need to have a particular environment for your application (maybe different between applications), or you want to run them on different machines, or under different users for security reasons.
b460ad78 668
8d47005f 669If you want to use a UNIX socket (on the filesystem), put this in Apache's configuration:
b460ad78 670
8d47005f 671 FastCgiExternalServer /tmp/somewhere -socket /tmp/myapp-socket
672 Alias / /tmp/somewhere/
b460ad78 673
8d47005f 674Note that C</tmp> should I<not> exist: it's just a name to connect the two parts.
b460ad78 675
8d47005f 676Again, if you want your app under C</theapp>, change the C<Alias> line to:
b460ad78 677
8d47005f 678 Alias /theapp /tmp/somewhere
679
680Then start your Catalyst application:
681
682 $ cd /usr/apps/MyApp
683 $ ./script/myapp_fastcgi -l /tmp/myapp-socket
684
685If you want to use a TCP socket, simply change the C</tmp> to a C<host:port> pair, both in Apache's configuration and on the command line of your application.
686
687=head2 Upgrading
688
689Upgrading your application to newer Catalyst versions is quite simple. After
690installing the new Catalyst package, just run:
691
692B<catalyst.pl -scripts>
693
694One level above your application directory. This will update the scripts
695directory only, and leave the rest of your app alone, If you wish to make use
696of other parts of Catalyst that have been updated, leave off the B<-scripts>
697argument, this will cause .new files to appear, for each module that has
698either been updated, or is different to the original because you have changed
699it. To find out what these changes are, type:
700
701B<diff MyApp/lib/MyApp/View/TT.pm MyApp/lib/MyApp/View/TT.pm.new>
702
703for each of the changed files. (This is a Unix command, Windows users will
704need to find some equivalent). Copy any changes you need into your original
705file, then remove the .new files. (This makes life less complicated when the
706next upgrade comes around.)
707
708=head1 AUTHOR
709
710Jess Robinson, C<jrobinson@cpan.org>
711Andrew Ford, C<A.Ford@ford-mason.co.uk>
712Marcus Ramberg, C<mramberg@cpan.org>
b460ad78 713
714Please send comments, corrections and suggestions for improvements to
8d47005f 715jrobinson@cpan.org
716
717=head1 TODO
718
719Add template examples.
720
721Many other things..
b460ad78 722
83cea649 723=head1 COPYRIGHT
724
61b1e958 725This program is free software, you can redistribute it and/or modify
726it under the same terms as Perl itself.