759d3fca5c04d3911642968655220c5b5e922ed3
[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>). 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>.
114
115
116 =head1 CREATE A CATALYST PROJECT
117
118 Catalyst provides a number of helper scripts that can be used to quickly
119 flesh out the basic structure of your application. All Catalyst projects
120 begin with the C<catalyst.pl> helper (see
121 L<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>
124 and L<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 View
173 directories. When you use the C<hello_create.pl> script it will create Perl
174 module scaffolds in those directories, plus test files in the "t"
175 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 MaiTai,
178 then the create script would be "maitai_create.pl".
179
180 Though it's too early for any significant celebration, we already have a
181 functioning application. We can use the Catalyst supplied script to
182 start up a development server and view the default Catalyst page in your
183 browser. All scripts in the script directory should be run from the base
184 directory of your application, so change to the Hello directory.
185
186 Run the following command to start up the built-in development web
187 server (make sure you didn't forget the "C<cd Hello>" from the previous
188 step):
189
190 B<Note>: The "-r" argument enables reloading on code changes so you
191 don't have to stop and start the server when you update code. See
192 C<perldoc script/hello_server.pl> or C<script/hello_server.pl --help>
193 for additional options you might find helpful. Most of the rest of the
194 tutorial will assume that you are using "-r" when you start the
195 development server, but feel free to manually start and stop it (use
196 C<Ctrl-C> to breakout of the dev server) if you prefer.
197
198     $ script/hello_server.pl -r
199     [debug] Debug messages enabled
200     [debug] Statistics enabled
201     [debug] Loaded plugins:
202     .----------------------------------------------------------------------------.
203     | Catalyst::Plugin::ConfigLoader  0.27                                       |
204     '----------------------------------------------------------------------------'
205     
206     [debug] Loaded dispatcher "Catalyst::Dispatcher"
207     [debug] Loaded engine "Catalyst::Engine::HTTP"
208     [debug] Found home "/home/me/Hello"
209     [debug] Loaded Config "/home/me/Hello/hello.conf"
210     [debug] Loaded components:
211     .-----------------------------------------------------------------+----------.
212     | Class                                                           | Type     |
213     +-----------------------------------------------------------------+----------+
214     | Hello::Controller::Root                                         | instance |
215     '-----------------------------------------------------------------+----------'
216     
217     [debug] Loaded Private actions:
218     .----------------------+--------------------------------------+--------------.
219     | Private              | Class                                | Method       |
220     +----------------------+--------------------------------------+--------------+
221     | /default             | Hello::Controller::Root              | default      |
222     | /end                 | Hello::Controller::Root              | end          |
223     | /index               | Hello::Controller::Root              | index        |
224     '----------------------+--------------------------------------+--------------'
225     
226     [debug] Loaded Path actions:
227     .-------------------------------------+--------------------------------------.
228     | Path                                | Private                              |
229     +-------------------------------------+--------------------------------------+
230     | /                                   | /index                               |
231     | /                                   | /default                             |
232     '-------------------------------------+--------------------------------------'
233     
234     [info] Hello powered by Catalyst 5.80025
235     You can connect to your server at http://debian:3000
236
237 Point your web browser to L<http://localhost:3000> (substituting a
238 different hostname or IP address as appropriate) and you should be
239 greeted by the Catalyst welcome screen (if you get some other welcome
240 screen or an "Index" screen, you probably forgot to specify port 3000 in
241 your URL).  Information similar to the following should be appended to
242 the logging output of the development server:
243
244     [info] *** Request 1 (0.001/s) [23194] [Sat Jan 16 11:09:18 2010] ***
245     [debug] "GET" request for "/" from "127.0.0.1"
246     [debug] Path is "/"
247     [info] Request took 0.004851s (206.143/s)
248     .------------------------------------------------------------+-----------.
249     | Action                                                     | Time      |
250     +------------------------------------------------------------+-----------+
251     | /index                                                     | 0.000395s |
252     | /end                                                       | 0.000425s |
253     '------------------------------------------------------------+-----------'
254
255 B<Note>: Press C<Ctrl-C> to break out of the development server if
256 necessary.
257
258
259 =head1 HELLO WORLD
260
261 =head2 The Simplest Way
262
263 The Root.pm controller is a place to put global actions that usually
264 execute on the root URL. Open the C<lib/Hello/Controller/Root.pm> file
265 in your editor. You will see the "index" subroutine, which is
266 responsible for displaying the welcome screen that you just saw in your
267 browser.
268
269     sub index :Path :Args(0) {
270         my ( $self, $c ) = @_;
271         
272         # Hello World
273         $c->response->body( $c->welcome_message );
274     }
275
276 Later on you'll want to change that to something more reasonable, such
277 as a "404" message or a redirect, but for now just leave it alone.
278
279 The "C<$c>" here refers to the Catalyst context, which is used to access
280 the Catalyst application. In addition to many other things, the Catalyst
281 context provides access to "response" and "request" objects. (See
282 L<Catalyst>, L<Catalyst::Response>, and
283 L<Catalyst::Request>)
284
285 C<$c-E<gt>response-E<gt>body> sets the HTTP response (see
286 L<Catalyst::Response>), while
287 C<$c-E<gt>welcome_message> is a special method that returns the welcome
288 message that you saw in your browser.
289
290 The ":Path :Args(0)" after the method name are attributes which
291 determine which URLs will be dispatched to this method. (You might see
292 ":Private" if you are using an older version of Catalyst, but using that
293 with "default" or "index" is currently deprecated.  If so, you should
294 also probably upgrade before continuing the tutorial.)
295
296 Some MVC frameworks handle dispatching in a central place. Catalyst, by
297 policy, prefers to handle URL dispatching with attributes on controller
298 methods. There is a lot of flexibility in specifying which URLs to
299 match.  This particular method will match all URLs, because it doesn't
300 specify the path (nothing comes after "Path"), but will only accept a
301 URL without any args because of the ":Args(0)".
302
303 The default is to map URLs to controller names, and because of the way
304 that Perl handles namespaces through package names, it is simple to
305 create hierarchical structures in Catalyst. This means that you can
306 create controllers with deeply nested actions in a clean and logical
307 way. For example, the URL C<http://hello.com/admin/articles/create> maps
308 to the package C<Hello::Controller::Admin::Articles>, and the C<create>
309 method.
310
311 Add the following subroutine to your C<lib/Hello/Controller/Root.pm>
312 file:
313
314     sub hello :Global {
315         my ( $self, $c ) = @_;
316         
317         $c->response->body("Hello, World!");
318     }
319
320 Once you restart the server, you will need to use the new address
321 L<http://localhost:3000/hello> instead of L<http://localhost:3000/> to see the
322 changes.
323
324 B<TIP>: See Appendix 1 for tips on removing the leading spaces when
325 cutting and pasting example code from POD-based documents.
326
327 Here you're sending your own string to the webpage.
328
329 Save the file, and you should notice the following in your server output:
330
331     Saw changes to the following files:
332      - /home/me/Hello/lib/Hello/Controller/Root.pm (modify)
333     
334     Attempting to restart the server
335     ...
336     [debug] Loaded Private actions:
337     .----------------------+--------------------------------------+--------------.
338     | Private              | Class                                | Method       |
339     +----------------------+--------------------------------------+--------------+
340     | /default             | Hello::Controller::Root              | default      |
341     | /end                 | Hello::Controller::Root              | end          |
342     | /index               | Hello::Controller::Root              | index        |
343     | /hello               | Hello::Controller::Root              | hello        |
344     '----------------------+--------------------------------------+--------------'
345     
346     [debug] Loaded Path actions:
347     .-------------------------------------+--------------------------------------.
348     | Path                                | Private                              |
349     +-------------------------------------+--------------------------------------+
350     | /                                   | /index                               |
351     | /                                   | /default                             |
352     | /hello                              | /hello                               |
353     '-------------------------------------+--------------------------------------'
354     ...
355
356 Go to L<http://localhost:3000/hello> to see "Hello, World!".   Also
357 notice that the newly defined 'hello' action is listed under "Loaded
358 Private actions" in the development server debug output.
359
360
361 =head2 Hello, World! Using a View and a Template
362
363 In the Catalyst world a "View" itself is not a page of XHTML or a
364 template designed to present a page to a browser. Rather, it is the
365 module that determines the I<type> of view -- HTML, pdf, XML, etc. For
366 the thing that generates the I<content> of that view (such as a
367 Toolkit Template template file), the actual templates go under the
368 "root" directory.
369
370 To create a TT view, run:
371
372     $ script/hello_create.pl view HTML TT
373
374 This creates the C<lib/Hello/View/HTML.pm> module, which is a subclass
375 of C<Catalyst::View::TT>.
376
377 =over 4
378
379 =item *
380
381 The "view" keyword tells the create script that you are creating a view.
382
383 =item *
384
385 The first argument "HTML" tells the script to name the View module "HTML.pm",
386 which is a commonly used name for TT views.  You can name it anything you want,
387 such as "MyView.pm". If you have more than one view, be sure to set the
388 default_view in Hello.pm (See L<Catalyst::View::TT> for more
389 details on setting this).
390
391 =item *
392
393 The final "TT" tells Catalyst the I<type> of the view, with "TT"
394 indicating that you want to a Template Toolkit view.
395
396 =back
397
398 If you look at C<lib/Hello/View/HTML.pm> you will find that it only
399 contains a config statement to set the TT extension to ".tt".
400
401 Now that the HTML.pm "View" exists, Catalyst will autodiscover it and be
402 able to use it to display the view templates using the "process" method
403 that it inherits from the C<Catalyst::View::TT> class.
404
405 Template Toolkit is a very full featured template facility, with
406 excellent documentation at L<http://template-toolkit.org/>, but since
407 this is not a TT tutorial, we'll stick to only basic TT usage here (and
408 explore some of the more common TT features in later chapters of the
409 tutorial).
410
411 Create a C<root/hello.tt> template file (put it in the C<root> under the
412 C<Hello> directory that is the base of your application). Here is a
413 simple sample:
414
415     <p>
416         This is a TT view template, called '[% template.name %]'.
417     </p>
418
419 [% and %] are markers for the TT parts of the template. Inside you can
420 access Perl variables and classes, and use TT directives. In this case,
421 we're using a special TT variable that defines the name of the template
422 file (C<hello.tt>).  The rest of the template is normal HTML.
423
424 Change the hello method in C<lib/Hello/Controller/Root.pm> to the
425 following:
426
427     sub hello :Global {
428         my ( $self, $c ) = @_;
429     
430         $c->stash(template => 'hello.tt');
431     }
432
433 This time, instead of doing C<$c-E<gt>response-E<gt>body()>, you are
434 setting the value of the "template" hash key in the Catalyst "stash", an
435 area for putting information to share with other parts of your
436 application. The "template" key determines which template will be
437 displayed at the end of the request cycle. Catalyst controllers have a
438 default "end" action for all methods which causes the first (or default)
439 view to be rendered (unless there's a C<$c-E<gt>response- E<gt>body()>
440 statement). So your template will be magically displayed at the end of
441 your method.
442
443 After saving the file, the development server should automatically
444 restart (again, the tutorial is written to assume that you are using the
445 "-r" option -- manually restart it if you aren't), and look at
446 L<http://localhost:3000/hello> in your again. You should see the
447 template that you just made.
448
449 B<TIP:> If you keep the server running with "-r" in a "background
450 window," don't let that window get totally hidden... if you have an
451 syntax error in your code, the debug server output will contain the
452 error information.
453
454 B<Note:> You will probably run into a variation of the "stash"
455 statement above that looks like:
456
457     $c->stash->{template} = 'hello.tt';
458
459 Although this style is still relatively common, the approach we
460 used previous is becoming more common because it allows you to
461 set multiple stash variables in one line.  For example:
462
463     $c->stash(template => 'hello.tt', foo => 'bar', 
464               another_thing => 1);
465
466 You can also set multiple stash values with a hashref:
467
468     $c->stash({template => 'hello.tt', foo => 'bar', 
469               another_thing => 1});
470
471 Any of these formats work, but the C<$c-E<gt>stash(name =E<gt> value);>
472 style is growing in popularity -- you may wish to use it all the time
473 (even when you are only setting a single value).
474
475
476 =head1 CREATE A SIMPLE CONTROLLER AND AN ACTION
477
478 Create a controller named "Site" by executing the create script:
479
480     $ script/hello_create.pl controller Site
481
482 This will create a C<lib/Hello/Controller/Site.pm> file (and a test
483 file). Bring Site.pm up in your editor, and you can see that there's not
484 much there.
485
486 In C<lib/Hello/Controller/Site.pm>, add the following method:
487
488     sub test :Local {
489         my ( $self, $c ) = @_;
490     
491         $c->stash(username => 'John',
492                   template => 'site/test.tt');
493     }
494
495 Notice the "Local" attribute on the C<test> method. This will cause the
496 C<test> action (now that we have assigned an "action type" to the method
497 it appears as a "controller action" to Catalyst) to be executed on the
498 "controller/method" URL, or, in this case, "site/test".  We will see
499 additional information on controller actions throughout the rest of the
500 tutorial, but if you are curious take a look at
501 L<Catalyst::Manual::Intro/Actions>.
502
503 It's not actually necessary to set the template value as we do here.  By
504 default TT will attempt to render a template that follows the naming
505 pattern "controller/method.tt", and we're following that pattern here.
506 However, in other situations you will need to specify the template (such
507 as if you've "forwarded" to the method, or if it doesn't follow the
508 default naming convention).
509
510 We've also put the variable "username" into the stash, for use in the
511 template.
512
513 Make a subdirectory "site" in the "root" directory.
514
515     $ mkdir root/site
516
517 Create a new template file in that direction named C<root/site/test.tt>
518 and include a line like:
519
520     <p>Hello, [% username %]!</p>
521
522 Once the server automatically restarts, notice in the server output that
523 C</site/test> is listed in the Loaded Path actions.  Go to
524 L<http://localhost:3000/site/test> in your browser and you should see
525 your test.tt file displayed, including the name "John" that you set in
526 the controller.
527
528
529 =head1 AUTHORS
530
531 Gerda Shank, C<gerda.shank@gmail.com>
532 Kennedy Clark, C<hkclark@gmail.com>
533
534 Feel free to contact the author for any errors or suggestions, but the
535 best way to report issues is via the CPAN RT Bug system at
536 <https://rt.cpan.org/Public/Dist/Display.html?Name=Catalyst-Manual>.
537
538 The most recent version of the Catalyst Tutorial can be found at
539 L<http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Manual/5.80/trunk/lib/Catalyst/Manual/Tutorial/>.
540
541 Copyright 2006-2010, Kennedy Clark, under the
542 Creative Commons Attribution Share-Alike License Version 3.0
543 (L<http://creativecommons.org/licenses/by-sa/3.0/us/>).