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