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