3 Catalyst::Manual::Tutorial - Getting started with Catalyst
7 This document aims to get you up and running with Catalyst.
11 The first step is to install Catalyst, and the simplest way to do this
12 is to install the Catalyst bundle from CPAN:
14 $ perl -MCPAN -e 'install Task::Catalyst'
16 This will retrieve Catalyst and a number of useful extensions and
17 install them for you. This process might not be totally painless
18 though, and you might want to look at CatInABox at
19 L<http://use.perl.org/~jk2addict/journal/28071>, especially if you are
20 on a system that lacks a compiler.
23 =head2 The very basics - Setting up the skeleton application.
25 Catalyst includes a helper script, C<catalyst.pl>, that will set up a
26 skeleton application for you:
28 $ catalyst.pl tutorial
31 created "tutorial/script"
33 created "tutorial/script/tutorial_create.pl"
35 This creates the directory structure, populated with skeleton
38 =head2 Testing out the skeleton application
40 You can test out your new application by running the server script that
44 $ script/tutorial_server.pl
46 [...] [catalyst] [debug] Debug messages enabled
47 [...] [catalyst] [debug] Loaded plugins:
48 .------------------------------------------------------------------------------.
49 | Catalyst::Plugin::Static::Simple |
50 '------------------------------------------------------------------------------'
51 [...] [catalyst] [debug] Loaded dispatcher "Catalyst::Dispatcher"
52 [...] [catalyst] [debug] Loaded engine "Catalyst::Engine::HTTP"
53 [...] [catalyst] [debug] Found home "/home/users/me/tutorial"
54 [...] [catalyst] [debug] Loaded Private actions:
55 .--------------------------------------+---------------------------------------.
57 +--------------------------------------+---------------------------------------+
58 | /default | tutorial |
59 '--------------------------------------+---------------------------------------'
61 [...] [catalyst] [info] tutorial powered by Catalyst 5.67
62 You can connect to your server at http://localhost:3000
64 (Note that each line logged by Catalyst begins with a timestamp, which has
65 been replaced here with "C<...>" so that the text fits onto the lines.)
67 The server is now waiting for you to make requests of it. Try using
68 telnet to manually make a simple GET request of the server (when
69 telnet responds with "Escape character is '^]'.", type "GET / HTTP/1.0"
70 and hit return twice):
72 $ telnet localhost 3000
74 Connected to localhost.
75 Escape character is '^]'.
79 Date: Mon, 07 Nov 2005 14:57:39 GMT
81 Content-Type: text/html; charset=utf-8
86 Connection closed by foreign host.
89 You can see the full welcome message by visiting
90 http://localhost:3000/ with your browser.
92 More trace messages will appear in the original terminal window:
94 [...] [catalyst] [debug] **********************************
95 [...] [catalyst] [debug] * Request 1 (0.063/s) [2148]
96 [...] [catalyst] [debug] **********************************
97 [...] [catalyst] [debug] Arguments are ""
98 [...] [catalyst] [debug] "GET" request for "" from localhost
99 [...] [catalyst] [info] Request took 0.046883s (21.330/s)
100 .------------------------------------------------------------------+-----------.
102 +------------------------------------------------------------------+-----------+
103 | /default | 0.000000s |
104 '------------------------------------------------------------------+-----------'
106 The server will continue running until you interrupt it.
108 The application can also be tested from the command line using the generated
109 helper script, C<script/tutorial_test.pl>.
111 =head2 Getting started
113 So you picked Catalyst. Good choice. We assume you have installed it as
114 well. For this tutorial you will also need the following modules:
116 L<Catalyst::Plugin::Session>
118 L<Catalyst::Plugin::Session::Store::File>
120 L<Catalyst::Plugin::Session::State::Cookie>
122 L<Catalyst::Plugin::Authentication>
124 L<Catalyst::Plugin::Authentication::Store::Minimal>
126 L<Catalyst::Plugin::Authentication::::Minimal>
128 L<Catalyst::Plugin::Authentication::Credential::Password>
130 L<Catalyst::Plugin::Authorization::Roles>
136 If you have not already done this following the example above, then to get
137 started all you need to do is type:
142 Poor choice of application name - searching for "tutorial" in the docs
143 also results in discussion of the tutorial process, which is probably
144 not what the reader wants.
148 This should create a directory called F<tutorial> and fill it with the
149 default (standard) Catalyst installation. Change to this directory
150 because we will be running all further commands from inside the
151 F<tutorial> directory.
153 If you now run the built-in mini-server with:
155 script/tutorial_server.pl
157 it will show some standard debug messages in the console screen
158 (more about those in a minute), and then inform you that you can now
159 connect to the test server on port 3000. Point your browser at
160 http://localhost:3000/ to see the built-in Catalyst welcome screen.
162 The other important thing B<catalyst.pl> did was create your root
163 controller. This file is a standard Perl module like all the other
164 controllers that you might add to your application. It lives in the
165 F<lib/> directory, and will have the same name as you supplied to the
166 command above. In our case it is F<tutorial.pm>. Alongside this file is
167 a directory of the same name, which is the top level namespace for the
168 entire application. Thus every other module we create will be
169 "tutorial::something".
171 The root controller is used to load plugins, to configure the
172 application and its plugins, and for generic private actions. We will
173 explain more about those later.
177 The simplest way to debug your Catalyst application is to run it using
178 the built-in mini-server as described in L<Getting started>.
180 If you want to output any debugging information to the console, then
181 call C<< $c->log->debug() >>, passing it a string to output. For data
182 structures, C<use> L<Data::Dumper> and call C<<
183 $c->log->debug(Dumper($structure)) >>
185 =head2 Model/View/Controller
187 The recommended method for code organization in a Catalyst application
188 is known as the "Model View Controller" design pattern (also referred to
189 "MVC". See L<http://en.wikipedia.org/wiki/Model-view-controller>).
191 The point of the MVC pattern is to separate the dependencies of parts of
192 the application from each other, and give them standard
193 interfaces. Following this theory of organization should give your code
194 all the benefits of modularity. The main benefits are interchangeability
195 of parts and reusability of code.
197 Thus you could replace your flat-file data storage with a relational
198 database, or your MySQL database with an Oracle database, and not have
199 to change any of your Controller or View logic. Or you could later
200 decide to output information from your application as RSS instead of
201 HTML just by adding a new View module.
205 Models deal with the storage of data. For a complex website, you may
206 need multiple data sources, each having its own model class that
207 provides an abstracted interface to it. In this tutorial we are going to
208 be using a simple database.
212 Views are used to display information to the user. In a web framework,
213 the View is generally used to output HTML to the browser. As mentioned
214 previously, Views can also be used to output RSS or any other kind of
215 data. One easy way to do this with Catalyst is to use a templating
216 system such as L<Template Toolkit|Template>. If outputting HTML is all
217 you are going to do, then you will probably only need one View.
221 A controller is responsible for responding to user choices, and thus
222 controls what the application does. Since this is a web framework,
223 Catalyst controllers are frequently used to react directly to URLs
224 requested by the user. This tutorial will describe the simplest way of
225 using controllers, where each path or part of a path is assigned its own
226 action (or subroutine). More complex controlling mechanisms will be
227 mentioned briefly, and can be read about in detail elsewhere in the
233 Now let's write our first bit of application code. First, we would like
234 our application to greet our users. We'll assume for now that our users
235 will be sent to the I<users/greet> URL. To create a controller that
236 serves the I<users> namespace, we run the following command in our
237 F<tutorial> directory:
239 script/tutorial_create.pl controller Users
241 This will create a Users.pm in F<lib/tutorial/Controller>. Open this
242 file in an editor and take a look. You will notice there is some
243 commented-out code which we will ignore for now. To make something
244 happen when our URL is visited, we will write a "greet" action which
250 my $name = $c->req->param('name');
251 $c->log->debug("Got name: $name\n");
253 if ($c->req->method eq 'POST') {
255 $c->stash->{message} = 'Please fill in a name!';
258 $c->stash->{message} = "Hello $name!";
261 $c->stash->{template} = 'greet.tt';
264 Whew! So, what does all this do? Let's take it one step at a time. The
265 subroutine declaration gives the action a name. To the right of the name
266 there is an attribute type that looks like this:
270 That defines which URIs will translate to this action. "Local" matches
275 The URI matched by "Local" is composed from the namespace minus the
276 tutorial::controller portion, that is common to all controllers,
277 and the action name itself. Because it is a URI, we use forward slashes
278 instead of double colons. So, in summary, when a user requests:
280 http://localhost:3000/users/greet
282 the "greet" action defined above in the Users controller will be executed.
284 The second line retrieves the parameters Catalyst gives us when it calls
285 our method. The first is the instance of our Users class, and the second
286 is commonly called the "context", held in C<$context>, or abbreviated to
287 C<$c>. From now on, whenever we are talking about the context object,
288 it will be represented as C<$c> in the code.
290 The context is the magical object containing any information you need from
291 catalyst, or want to send to it, and is passed from action to action.
292 You will see it used frequently in Catalyst applications, and a list of all
293 its methods is available in the L<Catalyst> POD.
295 On the third line we use the ->param method of the context's request object
296 to retrieve one of the query parameters, just like in L<CGI>.
298 On the fourth, we make a debug output of this object on the server console,
299 or the error log if running under CGI or mod_perl.
301 Next, if we have a post request, we check if the name field contains
302 anything (or is "true"). If it isn't, we assign an error message to a
303 "message" field in the stash. The stash is a special hash of the context
304 object, which allows us to pass data on to other methods we call later,
305 typically in the View.
307 If the username did contain a value, then we just set our message to
308 greet the user by name.
310 Finally, we set the special "template" variable in the stash to the name
311 of the template we want our View to use to display this page.
315 OK, so reacting and checking the users data is all fine, but how do we
316 actually display the page/form in the first place, and our results? In
317 this tutorial, we'll use Template Toolkit for our viewing. To create our
318 TT-based view, just run the following command:
320 script/tutorial_create.pl view TToolkit TT
322 Notice that this time we not only gave it the type of module we wanted
323 to create (a view), and a name, but also a third argument, "TT". This is
324 a Catalyst helper module, which will make a standard Template Toolkit
325 module for you. And that's all you need to do there.
327 To use the view, the easiest way is to set up a standard "end" action.
328 This is a special private action which will not be matched to a path
329 like our "greet" action, but instead will be called after all other
330 processing is done. Only one end action will be called in any request
331 cycle. If there is one in a controller, it will be preferred over one in
332 the application module, and so on.
334 Since we're writing a simple application, just add an end action like
335 this to F<tutorial.pm>:
339 $c->forward('tutorial::View::TToolkit') unless $c->res->body();
342 The first line declares the end sub, and marks it as a Private action.
343 (This is the second and last attribute type we'll be using in this
344 tutorial.) The second line collects our standard parameters as shown in
345 the controller's greet action.
347 The third line directs Catalyst to pass processing on to our TToolkit
348 view. The forward method, when just passed a class name, calls
349 C<process> on that class. The standard TT view's C<process> method
350 renders the template named in the template variable in the stash, using
351 all the other variables in the stash as values to fill it in.
353 NB: This is such a common way to end your processing that there is a
354 plugin which does it for you: L<Catalyst::Plugin::DefaultEnd>.
356 Template Toolkit also has access to the entire context object via the
357 special variable "c". For example, using C<[% c.config.name %]> in our
358 template will output "tutorial", our project name.
360 All that remains is to create a simple template called "greet.tt",
361 containing a form with a text field called "name" like below.
363 <html><head><title> [% c.name %]</head><body>
365 <form action="[% c.req.uri %]" method="post">
366 <input type="text" name="name"/>
367 <input type="submit" value="Submit" name="submit"/>
371 In the example above, we use C<[% c.req.uri %]>, since we're posting to
372 ourself. If we post to another action, we commonly use the uri_for
375 [% c.uri_for('/users/greet')%]
377 Place this file in the F<root> directory. By default, templates are
378 searched for here, but we can change that, which brings us to...
382 As previously mentioned, the configuration of modules, plugins, and so
383 on is done in the main application file. This is especially true for
384 bits which need to be done before an instance of them is created, for
385 example Template Toolkit.
387 The TT View looks for its templates in the F<root> directory by default.
388 Since this is also the directory that static files go in, we'd rather
389 have a separate F<templates> directory. To do this, change the config
390 call in F<tutorial.pm> like this:
392 __PACKAGE__->config( name => 'tutorial',
393 'View::TToolkit' => {
394 'INCLUDE_PATH' => __PACKAGE__->path_to('templates')
398 And move the F<greet.tt> file from F<root> to the F<templates> directory
401 Now we can run our application again by killing (B<ctrl-c>) and restarting
402 B<script/tutorial_server.pl>. Try connecting to
403 I<localhost:3000/users/greet> with a browser and see what happens. What
404 happens if you try to visit I<localhost:3000/users> ?
406 =head2 Users and Authenticating
408 One of the many reasons to write dynamic websites instead of just using
409 static HTML is to allow us to produce different content for different
410 users, as well as restricting access to pages (which we could do with
411 just Apache's htpasswd system).
413 In this tutorial, we will just be using basic authentication. When
414 writing a real application, you'll want to use a database or other
415 secure store to contain your user data.
417 To add authentication, all we need to do is add the
418 L<Catalyst::Plugin::Authentication> module to our main application
419 file. Then we need to pick a storage method (one of the
420 L<Catalyst::Plugin::Authentication::Store> modules), and a method of
421 verifying the user's credentials (one of the
422 L<Catalyst::Plugin::Authentication::Credential> modules). Edit
423 F<tutorial.pm> to look like this:
425 use Catalyst qw/-Debug Static::Simple Authentication
426 Authentication::Store::Minimal
427 Authentication::Credential::Password/;
429 To configure, add some users to the config call. For example:
431 authentication => { 'users' =>
433 { 'password' => 'fred1234',
438 Generally, setting up configuration data for plugins is done based on
439 the type of plugin. Check the documentation of the plugin for exact
440 details; in this example we should look in
441 L<Catalyst::Plugin::Authentication::Store::Minimal>.
443 Since our user data is in the config, we can update it at runtime, and
444 thus add users dynamically. (Of course, to keep them permanently we'd
445 need to save our data to disk and read it back into the config on
448 To allow creation of new users we'll add a C<create> action to our Users
453 my ($username, $passwd1, $passwd2) = map { $c->req->param($_)}
454 ('username', 'password', 'passwordverify');
456 if($username && $passwd1 && $passwd2) {
457 if($c->config->{authentication}{users}{$username}) {
458 $c->stash->{message} = 'Sorry, that user already exists';
459 $c->stash->{username} = $username;
461 elsif($passwd1 eq $passwd2) {
462 $c->config->{authentication}->{users}->{$username} =
463 {password => $passwd1};
464 $c->stash->{message} = 'User created!';
467 $c->stash->{username} = $username;
468 $c->stash->{message} = 'Passwords do not match!';
471 $c->stash->{template} = 'usercreate.tt';
474 All this is doing is checking that all the appropriate fields are
475 filled, and that the password fields contain the same data, and then
476 adding the user to the config hash. All the checks produce a message
477 which can be displayed to the user via the View.
479 The usercreate.tt template looks like this:
481 <html><head><title>[% c.config.name %]</title></head><body>
482 <h1>Create a new user</h1>
483 <h2>Current users are:</h2>
485 [% FOREACH key = c.config.authentication.users.keys %]
489 <p> [% message %] </p>
490 <form action="/users/create" method="post">
491 <p>User Name: <input type="text" name="username"/></p>
492 <p>Password: <input type="password" name="password"/></p>
493 <p>Confirm Password: <input type="password" name="passwordverify"/></p>
494 <p><input type="submit" name="submit" value="submit"></p>
498 In order for our users to be able to login, we need a C<login> action
499 which we put in the Users controller:
503 $c->stash->{template} = 'userlogin.tt';
505 $c->stash->{message} = 'Please login.';
508 $c->stash->{message} = "Welcome " . $c->user->id;
513 And the userlogin.tt template:
515 <html><head><title>[% c.config.name %]</title></head><body>
516 <p> [% message %] </p>
517 <form name='login' action='/users/login' method='post'>
518 <p>Username: <input type='text' name='user' /></p>
519 <p>Password: <input type='password' name='password' /></p>
520 <p><input type="submit" /></form>
524 Very simple. Since Credential::Password's "login" call extracts the
525 username/password data from the query itself (assuming we use a standard
526 name for our form fields), we don't have to do anything but call it.
528 To keep the user logged in, all we need to do is add the Session modules
529 to our collection, and the Auth modules will automatically use them:
531 use Catalyst qw/-Debug Static::Simple Authentication
532 Authentication::Store::Minimal
533 Authentication::Credential::Password
534 Session Session::Store::File Session::State::Cookie/;
540 As an exercise for the reader, do the following:
542 Change C<users/greet> and C<greet.tt> so that the welcome message greets
545 Enforce user logging in by adding an C<auto> action in tutorial.pm (see
546 the L<Catalyst> documentation to find out about the C<auto> action).
550 Authentication is about verifying users, and authorization is about
551 allowing them to do things. Catalyst currently has two Authorization
552 modules, Roles and ACL. The Roles module allows you to define groups
553 which you can assign your users to, and then allow access to areas of
554 your website to the groups. The ACL module lets you do more fine grained
555 access/restriction by allowing of denying access however you like. (It
556 also supports Roles as done by the roles module.) This example uses
557 L<Catalyst::Plugin::Authorization::Roles>. To use this add
558 "Authorization::Roles" into the "use Catalyst" statement in tutorial.pm.
560 Adding Roles via the Minimal store we are already using is quite simple,
561 we just add a roles key to each user, defining the names of the roles
564 authentication => { 'users' =>
566 { 'password' => 'fred1234',
572 We need an interface for our admins to administer the roles, i.e. assign
573 the users to groups. To restrict access to certain actions, we just need
574 to call C<< $c->check_user_roles() >> in each action. So we can
575 make a restricted I<http://localhost:3000/users/groups> page like this:
579 if($c->check_user_roles('admin')) {
580 # Now we can do things only an admin will see
581 if (my $params = $c->req->params) {
582 my $users = $c->config->{authentication}{users};
583 foreach my $u (keys %$params) {
584 $users->{$u}{roles} = $params->{$u} if($users->{$u});
586 $c->stash->{message} = 'Updated user roles!';
589 $c->stash->{users} = $c->config->{authentication};
591 $c->stash->{template} = 'usersgroups.tt';
594 $c->stash->{message} = 'Admins Only!';
595 $c->stash->{template} = 'error.tt';
599 What we are doing here is checking whether the logged-in user (used by
600 default in the C<check_user_roles> method) is a member of the admin
601 group. If it is, then we display the usergroups template, and update
602 the users hash as required. Otherwise, we just show the user an error
605 For this simple example, the usersgroups.tt and error.tt templates could
608 <html><head><title>[% c.config.name %]</title></head><body>
610 <p>[% c.stash.users %]</p>
613 And that's all there is to it.
616 So it's not clear what the groups action is doing - and with the
617 current template, nothing happens. Running through the sample code,
618 it's clear what's happening (which is very little), but the purpose,
619 and how to display data is not clear.
623 So that you can test this out properly without having to go to the
624 trouble of deleting browser cookies manually, we will add a logout
625 action in the Users controller:
629 $c->stash->{message} = "You have successfully logged out";
634 =head2 Data Storage (Modelling)
636 Whether we want our users to be able to contribute to our website, or
637 just create it from changeable data, we need to store the data
638 somewhere. Generally this is done using a database, but models can also
639 use other data sources, for example another website, or an RSS feed.
641 If you have or want a database, there are still choices to be
642 made. There are several modules for accessing databases using an
643 object-oriented wrapper. The best known are probably L<DBIx::Class> and
644 L<Class::DBI>. Catalyst supports making models using either of these.
646 For a simple example, we will allow our users to store their favorite
647 greeting in our database. Create a table called "greetings" in a
648 database, that contains a "user" field and a "greeting" field. The
649 simplest way to create a model of your database is to use these helper
650 modules, for example with L<DBIx::Class>:
652 script/tutorial_create.pl model UserData DBIC dbi:SQLite:/path/to/mydb.db
654 This will cause the DBIx::Class Loader to inspect your database, and create a
655 module in the Model::UserData namespace for each table in your database.
657 Now we need a form for our users to enter/edit their personal greetings
658 in, so we'll make a I<http://localhost:3000/users/editgreeting> page:
660 sub editgreeting : Local {
662 if($c->req->params->{greeting}) {
663 if(!$c->user_exists) {
664 $c->stash->{message} = "You're not logged in!";
667 my $grtable = $c->model('UserData::Greetings');
668 my $record = $grtable->find_or_create(user => $c->user->id);
669 $record->greeting($c->req->params->{greeting});
671 $c->stash->{message} = 'Greeting updated';
674 $c->stash->{template} = 'usersgreeting.tt';
677 Using C<< $c->user_exists >> from the Authentication plugin, this checks
678 whether the user is logged in already. If they are, and they have
679 entered a new greeting, we use DBIx::Class' C<find_or_create> method to
680 fetch or create a new record in the greetings table for the user. Once
681 we have the record, we change the value of the greeting field, and call
682 C<update> to store the new value in the database.
684 =head2 Engines (Apache and FastCGI)
686 Now that we have the basics together, we can try running our application on a
687 "real" server instead of just using the test server that Catalyst comes
688 with. L<Catalyst::Engine> is the module used to implement various types of
689 servers to run it on. The current popular ones are Apache and FastCGI.
693 Apache needs to be configured: we need to tell it to load your
694 application. You can either use Catalyst for your entire website, or
695 subsections. Use the Location directive to choose a path to run your
699 SetHandler perl-script
700 PerlResponseHandler tutorial
703 You will need to install the perl modules of your application into one
704 of perl's library directories, as listed by B<perl -V>, so that Apache
705 can find them. Alternatively you can use the C<PerlSwitches> directive
706 to tell Apache where to look:
708 PerlSwitches -I/path/to/tutorial/
710 These instructions are for using Apache2 and mod_perl 2.0. If you are
711 using mod_perl 1.3 or 1.99, please refer to either
712 L<Catalyst::Engine::Apache::MP13> or L<Catalyst::Engine::Apache2::MP19>
713 for details of the slightly different ways to do it.
715 If you wish to ensure that Apache pre-loads your application, use the
716 PerlModule directive. This means that there will be less of a delay when
717 your application is accessed.
723 These instructions apply to the use of C<mod_fastcgi> under Apache
724 (either 1 or 2 series).
726 There are 3 ways to attach a program to a URL with C<mod_fastcgi>;
727 we'll examine all of them, and explain how to avoid having the
728 C<tutorial_fastcgi.pl> substring in the user-visible URLs.
730 In all of these examples, we assume that the C<DocumentRoot> is
731 C</var>, that our app is called C<tutorial> and is kept in C</usr>, that
732 you want the users to access the app either from the root of the
733 server-uri-space, or from C</theapp>. We also assume that the general
734 FastCGI settings (C<FastCgiIpcDir>, loading the module) are already
735 correct (they don't depend on Catalyst or your application layout).
737 =head4 static application
739 In this setup, you tell C<mod_fastcgi> that a particular I<file> is to
740 be run as a FastCGI handler. Put this somewhere in Apache's
743 FastCgiServer /usr/apps/tutorial/script/tutorial_fastcgi.pl
744 Alias / /usr/apps/tutorial/script/tutorial_fastcgi.pl/
746 If you want your app under C</theapp>, change the C<Alias> line to:
748 Alias /theapp /usr/apps/tutorial/script/tutorial_fastcgi.pl
750 Note the detail of the trailing C</ >: this is a general rule of the
751 C<Alias> directive, both sides must end with C</ >, or both must not;
752 you can't have one with C</ > and the other without, or strange things
755 =head4 dynamic application
757 In this setup, you tell C<mod_fastcgi> that certain files are to be
758 treated as FastCGI handlers, in the same way you have to tell
759 C<mod_cgi>. Put this in the configuration:
761 FastCgiConfig -autoUpdate
763 <Directory /usr/apps/tutorial/script>
766 SetHandles fastcgi-script
770 Alias / /usr/apps/tutorial/script/tutorial_fastcgi.pl/
772 Again, if you want your app under C</theapp>, change the C<Alias> line to:
774 Alias /theapp /usr/apps/tutorial/script/tutorial_fastcgi.pl
776 =head4 external server
778 In this setup, the application is started separately from Apache, and
779 communicates via a socket with C<mod_fastcgi>. This can be useful if
780 you need to have a particular environment for your application (maybe
781 different between applications), or you want to run them on different
782 machines, or under different users for security reasons.
784 If you want to use a UNIX socket (on the filesystem), put this in
785 Apache's configuration:
787 FastCgiExternalServer /tmp/somewhere -socket /tmp/tutorial-socket
788 Alias / /tmp/somewhere/
790 Note that C</tmp> should I<not> exist: it's just a name to connect the
793 Again, if you want your app under C</theapp>, change the C<Alias> line
796 Alias /theapp /tmp/somewhere
798 Then start your Catalyst application:
800 $ cd /usr/apps/tutorial
801 $ ./script/tutorial_fastcgi -l /tmp/tutorial-socket
803 If you want to use a TCP socket, simply change the C</tmp> to a
804 C<host:port> pair, both in Apache's configuration and on the command
805 line of your application.
809 Upgrading your application to newer Catalyst versions is quite
810 simple. After installing the new Catalyst package, just run:
814 One level above your application directory. This will update the scripts
815 directory only, and leave the rest of your app alone. If you wish to
816 make use of other parts of Catalyst that have been updated, leave off
817 the B<-scripts> argument, this will cause .new files to appear, for each
818 module that has either been updated, or is different to the original
819 because you have changed it. To find out what these changes are, type:
821 diff tutorial/lib/tutorial/View/TT.pm tutorial/lib/tutorial/View/TT.pm.new
823 for each of the changed files. (This is a Unix command; Windows users
824 will need to find some equivalent.) Copy any changes you need into your
825 original file, then remove the .new files. (This makes life less
826 complicated when the next upgrade comes around.)
830 Jess Robinson, C<jrobinson@cpan.org>
831 Andrew Ford, C<A.Ford@ford-mason.co.uk>
832 Marcus Ramberg, C<mramberg@cpan.org>
833 Kieren Diment, C<kd@totaldatasolution.com>
834 Gavin Henry, C<ghenry@cpan.org>
836 Please send comments, corrections and suggestions for improvements to
837 jrobinson@cpan.org, ghenry@cpan.org
841 Finish DBIC examples with templates and tested code. Make /users/groups
842 do something "useful".
844 Many other things....
848 This program is free software, you can redistribute it and/or modify
849 it under the same terms as Perl itself.