make killing the server a note
[catagits/Catalyst-Manual.git] / lib / Catalyst / Manual / Tutorial / 02_CatalystBasics.pod
CommitLineData
d442cc9f 1=head1 NAME
2
3ab6187c 3Catalyst::Manual::Tutorial::02_CatalystBasics - Catalyst Tutorial - Chapter 2: Catalyst Application Development Basics
d442cc9f 4
5
6=head1 OVERVIEW
7
4b4d3884 8This is B<Chapter 2 of 10> for the Catalyst tutorial.
d442cc9f 9
10L<Tutorial Overview|Catalyst::Manual::Tutorial>
11
12=over 4
13
14=item 1
15
3ab6187c 16L<Introduction|Catalyst::Manual::Tutorial::01_Intro>
d442cc9f 17
18=item 2
19
3ab6187c 20B<02_Catalyst Basics>
d442cc9f 21
22=item 3
23
3ab6187c 24L<More Catalyst Basics|Catalyst::Manual::Tutorial::03_MoreCatalystBasics>
d442cc9f 25
26=item 4
27
3ab6187c 28L<Basic CRUD|Catalyst::Manual::Tutorial::04_BasicCRUD>
d442cc9f 29
30=item 5
31
3ab6187c 32L<Authentication|Catalyst::Manual::Tutorial::05_Authentication>
d442cc9f 33
34=item 6
35
3ab6187c 36L<Authorization|Catalyst::Manual::Tutorial::06_Authorization>
d442cc9f 37
38=item 7
39
3ab6187c 40L<Debugging|Catalyst::Manual::Tutorial::07_Debugging>
d442cc9f 41
42=item 8
43
3ab6187c 44L<Testing|Catalyst::Manual::Tutorial::08_Testing>
d442cc9f 45
46=item 9
47
3ab6187c 48L<Advanced CRUD|Catalyst::Manual::Tutorial::09_AdvancedCRUD>
3533daff 49
50=item 10
51
3ab6187c 52L<Appendices|Catalyst::Manual::Tutorial::10_Appendices>
d442cc9f 53
54=back
55
56
57=head1 DESCRIPTION
58
4b4d3884 59In this chapter of the tutorial, we will create a very basic Catalyst
60web application, demonstrating a number of powerful capabilities, such
61as:
d442cc9f 62
63=over 4
64
65=item * Helper Scripts
66
67Catalyst helper scripts that can be used to rapidly bootstrap the
68skeletal structure of an application.
69
70=item * MVC
71
72Model/View/Controller (MVC) provides an architecture that facilitates a
73clean "separation of control" between the different portions of your
74application. Given that many other documents cover this subject in
75detail, MVC will not be discussed in depth here (for an excellent
76introduction to MVC and general Catalyst concepts, please see
865d3efb 77L<Catalyst::Manual::About|Catalyst::Manual::About>). In short:
d442cc9f 78
79=over 4
80
81=item * Model
82
83The model usually represents a data store. In most applications, the
84model equates to the objects that are created from and saved to your SQL
85database.
86
87=item * View
88
89The view takes model objects and renders them into something for the end
90user to look at. Normally this involves a template-generation tool that
91creates HTML for the user's web browser, but it could easily be code
865d3efb 92that generates other forms such as PDF documents, e-mails, spreadsheets,
93or even "behind the scenes" formats such as XML and JSON.
d442cc9f 94
95=item * Controller
96
97As suggested by its name, the controller takes user requests and routes
98them to the necessary model and view.
99
100=back
101
102=item * ORM
103
104The use of Object-Relational Mapping (ORM) technology for database
105access. Specifically, ORM provides an automated and standardized means
444d6b27 106to persist and restore objects to/from a relational database and will
107automatically create our Catalyst model for use with a database.
d442cc9f 108
109=back
110
111You can checkout the source code for this example from the catalyst
112subversion repository as per the instructions in
3ab6187c 113L<Catalyst::Manual::Tutorial::01_Intro|Catalyst::Manual::Tutorial::01_Intro>.
d442cc9f 114
3533daff 115
d442cc9f 116=head1 CREATE A CATALYST PROJECT
117
3533daff 118Catalyst provides a number of helper scripts that can be used to
119quickly flesh out the basic structure of your application. All
120Catalyst projects begin with the C<catalyst.pl> helper (see
121L<Catalyst::Helper|Catalyst::Helper> for more information on helpers).
122Also note that as of Catalyst 5.7000, you will not have the helper
123scripts unless you install both L<Catalyst::Runtime|Catalyst::Runtime>
124and L<Catalyst::Devel|Catalyst::Devel>.
125
4b4d3884 126In this first chapter of the tutorial, use the Catalyst C<catalyst.pl>
127script to initialize the framework for an application called C<Hello>:
3533daff 128
129 $ catalyst.pl Hello
130 created "Hello"
131 created "Hello/script"
132 created "Hello/lib"
133 created "Hello/root"
d442cc9f 134 ...
3533daff 135 created "Hello/script/hello_create.pl"
444d6b27 136 Change to application directory and Run "perl Makefile.PL" to make sure your install is complete
3533daff 137 $ cd Hello
d442cc9f 138
444d6b27 139Note: If you are using Strawberry Perl on Win32, drop the ".pl"
140from the end of the "catalyst.pl" command and simply use
141"catalyst Hello".
142
d442cc9f 143The C<catalyst.pl> helper script will display the names of the
3533daff 144directories and files it creates:
145
146 Changes # Record of application changes
865d3efb 147 lib # Lib directory for your app's Perl modules
148 Hello # Application main code directory
3533daff 149 Controller # Directory for Controller modules
150 Model # Directory for Models
151 View # Directory for Views
152 Hello.pm # Base application module
153 Makefile.PL # Makefile to build application
45d511e0 154 hello.conf # Application configuration file
3533daff 155 README # README file
156 root # Equiv of htdocs, dir for templates, css, javascript
157 favicon.ico
158 static # Directory for static files
159 images # Directory for image files used in welcome screen
160 script # Directory for Perl scripts
161 hello_cgi.pl # To run your app as a cgi (not recommended)
162 hello_create.pl # To create models, views, controllers
163 hello_fastcgi.pl # To run app as a fastcgi program
164 hello_server.pl # The normal development server
165 hello_test.pl # Test your app from the command line
166 t # Directory for tests
167 01app.t # Test scaffold
168 02pod.t
169 03podcoverage.t
170
171
172Catalyst will "auto-discover" modules in the Controller, Model, and
173View directories. When you use the hello_create.pl script it will
174create Perl module scaffolds in those directories, plus test files in
175the "t" directory. The default location for templates is in the "root"
176directory. The scripts in the script directory will always start with
177the lowercased version of your application name. If your app is
178MaiTai, then the create script would be "maitai_create.pl".
179
180Though it's too early for any significant celebration, we already have
181a functioning application. We can use the Catalyst supplied script to
182start up a development server and view the default Catalyst page in
183your browser. All scripts in the script directory should be run from
184the base directory of your application, so change to the Hello
185directory.
186
187Run the following command to start up the built-in development web
acbd7bdd 188server (make sure you didn't forget the "C<cd Hello>" from the
189previous step):
d442cc9f 190
0f1ac65e 191B<Note>: the -r enables reloading on code changes so you don't have to stop and
192start the server when you update code. see perldoc script/hello_server.pl for
193more useful options.
194
195 $ script/hello_server.pl -r
d442cc9f 196 [debug] Debug messages enabled
865d3efb 197 [debug] Statistics enabled
d442cc9f 198 [debug] Loaded plugins:
199 .----------------------------------------------------------------------------.
f34d7f62 200 | Catalyst::Plugin::ConfigLoader 0.27 |
d442cc9f 201 '----------------------------------------------------------------------------'
202
203 [debug] Loaded dispatcher "Catalyst::Dispatcher"
204 [debug] Loaded engine "Catalyst::Engine::HTTP"
3533daff 205 [debug] Found home "/home/me/Hello"
e13f83cc 206 [debug] Loaded Config "/home/me/Hello/hello.conf"
d442cc9f 207 [debug] Loaded components:
208 .-----------------------------------------------------------------+----------.
209 | Class | Type |
210 +-----------------------------------------------------------------+----------+
3533daff 211 | Hello::Controller::Root | instance |
d442cc9f 212 '-----------------------------------------------------------------+----------'
213
214 [debug] Loaded Private actions:
215 .----------------------+--------------------------------------+--------------.
216 | Private | Class | Method |
217 +----------------------+--------------------------------------+--------------+
3533daff 218 | /default | Hello::Controller::Root | default |
219 | /end | Hello::Controller::Root | end |
acbd7bdd 220 | /index | Hello::Controller::Root | index |
d442cc9f 221 '----------------------+--------------------------------------+--------------'
222
865d3efb 223 [debug] Loaded Path actions:
224 .-------------------------------------+--------------------------------------.
225 | Path | Private |
226 +-------------------------------------+--------------------------------------+
865d3efb 227 | / | /index |
08ae25e9 228 | / | /default |
865d3efb 229 '-------------------------------------+--------------------------------------'
acbd7bdd 230
08ae25e9 231 [info] Hello powered by Catalyst 5.80018
acbd7bdd 232 You can connect to your server at http://debian:3000
d442cc9f 233
1435672d 234Point your web browser to L<http://localhost:3000> (substituting a
d442cc9f 235different hostname or IP address as appropriate) and you should be
acbd7bdd 236greeted by the Catalyst welcome screen (if you get some other welcome
237screen or an "Index" screen, you probably forgot to specify port 3000
238in your URL). Information similar to the following should be appended
239to the logging output of the development server:
240
3dfcf16a 241 [info] *** Request 1 (0.001/s) [23194] [Sat Jan 16 11:09:18 2010] ***
242 [debug] "GET" request for "/" from "127.0.0.1"
243 [debug] Path is "/"
244 [info] Request took 0.004851s (206.143/s)
245 .------------------------------------------------------------+-----------.
246 | Action | Time |
247 +------------------------------------------------------------+-----------+
248 | /index | 0.000395s |
249 | /end | 0.000425s |
250 '------------------------------------------------------------+-----------'
d442cc9f 251
9b531c13 252B<Note>: Press Ctrl-C to break out of the development server if necessary.
d442cc9f 253
254
3533daff 255=head1 HELLO WORLD
d442cc9f 256
3533daff 257=head2 The Simplest Way
d442cc9f 258
3533daff 259The Root.pm controller is a place to put global actions that usually
260execute on the root URL. Open the C<lib/Hello/Controller/Root.pm> file in
865d3efb 261your editor. You will see the "index" subroutine, which is
3533daff 262responsible for displaying the welcome screen that you just saw in
263your browser. Later on you'll want to change that to something more
865d3efb 264reasonable, such as a "404" message or a redirect, but for now just
265leave it alone.
d442cc9f 266
865d3efb 267 sub index :Path :Args(0) {
3533daff 268 my ( $self, $c ) = @_;
865d3efb 269
270 # Hello World
3533daff 271 $c->response->body( $c->welcome_message );
d442cc9f 272 }
273
3533daff 274The "C<$c>" here refers to the Catalyst context, which is used to
275access the Catalyst application. In addition to many other things,
276the Catalyst context provides access to "response" and "request"
d0496197 277objects. (See L<Catalyst|Catalyst>,
278L<Catalyst::Response|Catalyst::Response>, and
279L<Catalyst::Request|Catalyst::Request>)
d442cc9f 280
14e5ed66 281C<$c-E<gt>response-E<gt>body> sets the HTTP response (see
282L<Catalyst::Response|Catalyst::Response>), while C<$c-E<gt>welcome_message>
d0496197 283is a special method that returns the welcome message that you saw in
284your browser.
d442cc9f 285
444d6b27 286The ":Path :Args(0)" after the method name are attributes which
287determine which URLs will be dispatched to this method. (You might see
288":Private" if you are using an older version of Catalyst, but using
289that with 'default' or 'index' is currently deprecated. If so, you
290should also probably upgrade before continuing the tutorial.)
d442cc9f 291
3533daff 292Some MVC frameworks handle dispatching in a central place. Catalyst,
293by policy, prefers to handle URL dispatching with attributes on
294controller methods. There is a lot of flexibility in specifying which
295URLs to match. This particular method will match all URLs, because it
865d3efb 296doesn't specify the path (nothing comes after "Path"), but will only
444d6b27 297accept a URL without any args because of the ":Args(0)".
d442cc9f 298
444d6b27 299The default is to map URLs to controller names, and because of the way
300that Perl handles namespaces through package names, it is simple to
301create hierarchical structures in Catalyst. This means that you can
302create controllers with deeply nested actions in a clean and logical
303way. For example, the URL C<http://hello.com/admin/articles/create>
304maps to the package C<Hello::Controller::Admin::Articles>, and the
305C<create> method.
d442cc9f 306
d0496197 307Add the following subroutine to your C<lib/Hello/Controller/Root.pm>
308file:
d442cc9f 309
3d0b2e0b 310 sub hello :Global {
3533daff 311 my ( $self, $c ) = @_;
d0496197 312
3533daff 313 $c->response->body("Hello, World!");
314 }
d442cc9f 315
acbd7bdd 316B<TIP>: See Appendix 1 for tips on removing the leading spaces when
317cutting and pasting example code from POD-based documents.
318
3533daff 319Here you're sending your own string to the webpage.
320
321Save the file, start the server (stop and restart it if it's still
444d6b27 322running), and go to L<http://localhost:3000/hello> to
323see "Hello, World!" Also notice that a new action is listed under
324"Loaded Private actions" in the development server debug output.
3533daff 325
865d3efb 326
3533daff 327=head2 Hello, World! Using a View and a Template
328
444d6b27 329In the Catalyst world a "View" itself is not a page of XHTML or a
330template designed to present a page to a browser. Rather, it is the
331module that determines the I<type> of view -- HTML, pdf, XML, etc. For
332the thing that generates the I<content> of that view (such as the a
333Toolkit Template template file), the actual templates go under the
865d3efb 334"root" directory.
3533daff 335
336To create a TT view, run:
337
338 $ script/hello_create.pl view TT TT
339
340This creates the C<lib/Hello/View/TT.pm> module, which is a subclass of
1435672d 341C<Catalyst::View::TT>.
342
343=over 4
344
345=item *
346
347The "view" keyword tells the create script that you are creating a view.
348
349=item *
350
351The first "TT" tells the script to name the View module "TT.pm", which is a
352commonly used name for TT views. (You can name it anything you want, such as
353"HTML.pm".)
354
355=item *
356
444d6b27 357The final "TT" tells Catalyst the I<type> of the view, with "TT"
358indicating that you want to a Template Toolkit view.
1435672d 359
360=back
361
444d6b27 362If you look at C<lib/Hello/View/TT.pm> you will find that it only
363contains a config statement to set the TT extension to ".tt".
3533daff 364
365Now that the TT.pm "View" exists, Catalyst will autodiscover it and be
444d6b27 366able to use it to display the view templates using the "process"
3533daff 367method that it inherits from the C<Catalyst::View::TT class>.
368
c010ae0d 369Template Toolkit is a very full featured template facility, with
865d3efb 370excellent documentation at L<http://template-toolkit.org/>,
3533daff 371but since this is not a TT tutorial, we'll stick to only basic TT
372usage here (and explore some of the more common TT features in later
4b4d3884 373chapters of the tutorial).
3533daff 374
375Create a C<root/hello.tt> template file (put it in the C<root> under
376the C<Hello> directory that is the base of your application). Here is
377a simple sample:
378
3533daff 379 <p>
1435672d 380 This is a TT view template, called '[% template.name %]'.
3533daff 381 </p>
382
383[% and %] are markers for the TT parts of the template. Inside you can
1435672d 384access Perl variables and classes, and use TT directives. In this
385case, we're using a special TT variable that defines the name of the
386template file (C<hello.tt>). The rest of the template is normal HTML.
387
388Change the hello method in C<lib/Hello/Controller/Root.pm> to the
389following:
3533daff 390
3d0b2e0b 391 sub hello :Global {
3533daff 392 my ( $self, $c ) = @_;
d0496197 393
3533daff 394 $c->stash->{template} = 'hello.tt';
395 }
d442cc9f 396
444d6b27 397This time, instead of doing C<$c-E<gt>response-E<gt>body()>, you are
398setting the value of the "template" hash key in the Catalyst "stash",
399an area for putting information to share with other parts of your
400application. The "template" key determines which template will be
401displayed at the end of the request cycle. Catalyst controllers have a
402default "end" action for all methods which causes the first (or
403default) view to be rendered (unless there's a C<$c-E<gt>response-
404E<gt>body()> statement). So your template will be magically displayed
405at the end of your method.
d442cc9f 406
3533daff 407After saving the file, restart the development server, and look at
d0496197 408L<http://localhost:3000/hello> again. You should
3533daff 409see the template that you just made.
d442cc9f 410
d442cc9f 411
3533daff 412=head1 CREATE A SIMPLE CONTROLLER AND AN ACTION
d442cc9f 413
3533daff 414Create a controller named "Site" by executing the create script:
d442cc9f 415
3533daff 416 $ script/hello_create.pl controller Site
d442cc9f 417
3533daff 418This will create a C<lib/Hello/Controller/Site.pm> file (and a test
419file). Bring Site.pm up in your editor, and you can see that there's
444d6b27 420not much there.
d442cc9f 421
d0496197 422In C<lib/Hello/Controller/Site.pm>, add the following method:
d442cc9f 423
3d0b2e0b 424 sub test :Local {
3533daff 425 my ( $self, $c ) = @_;
d0496197 426
3533daff 427 $c->stash->{username} = "John";
428 $c->stash->{template} = 'site/test.tt';
d442cc9f 429 }
430
1435672d 431Notice the "Local" attribute on the C<test> method. This will cause
444d6b27 432the C<test> action (now that we have assigned an "action type" to the
433method it appears as a "controller action" to Catalyst) to be executed
1435672d 434on the "controller/method" URL, or, in this case, "site/test". We
435will see additional information on controller actions throughout the
436rest of the tutorial, but if you are curious take a look at
437L<Catalyst::Manual::Intro/Actions>.
438
439It's not actually necessary to set the template value as we do here.
440By default TT will attempt to render a template that follows the
441naming pattern "controller/method.tt", and we're following that
442pattern here. However, in other situations you will need to specify
443the template (such as if you've "forwarded" to the method, or if it
444doesn't follow the default naming convention).
445
446We've also put the variable "username" into the stash, for use in the
447template.
d442cc9f 448
3533daff 449Make a subdirectory "site" in the "root" directory. Copy the hello.tt
d0496197 450file into the directory as C<root/site/test.tt>, or create a new
451template file at that location. Include a line like:
d442cc9f 452
d0496197 453 <p>Hello, [% username %]!</p>
d442cc9f 454
3533daff 455Bring up or restart the server. Notice in the server output that
456C</site/test> is listed in the Loaded Path actions. Go to
865d3efb 457L<http://localhost:3000/site/test> in your browser.
d442cc9f 458
3533daff 459You should see your test.tt file displayed, including the name "John"
460that you set in the controller.
d442cc9f 461
d442cc9f 462
3533daff 463=head1 AUTHORS
d442cc9f 464
3533daff 465Gerda Shank, C<gerda.shank@gmail.com>
d442cc9f 466Kennedy Clark, C<hkclark@gmail.com>
467
468Please report any errors, issues or suggestions to the author. The
469most recent version of the Catalyst Tutorial can be found at
59884771 470L<http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Manual/5.80/trunk/lib/Catalyst/Manual/Tutorial/>.
d442cc9f 471
45c7830f 472Copyright 2006-2008, Kennedy Clark & Gerda Shank, under Creative Commons License
865d3efb 473(L<http://creativecommons.org/licenses/by-sa/3.0/us/>).