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