Update for Ubuntu 8.10, update license, misc updates
[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
d0496197 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
3533daff 223Point your web browser to
224L<http://localhost:3000|http://localhost:3000> (substituting a
d442cc9f 225different hostname or IP address as appropriate) and you should be
226greeted by the Catalyst welcome screen. Information similar to the
227following should be appended to the logging output of the development
228server:
229
865d3efb 230 [info] *** Request 1 (1.000/s) [10301] [Sun Nov 23 10:11:36 2008] ***
d442cc9f 231 [debug] "GET" request for "/" from "127.0.0.1"
3533daff 232 [info] Request took 0.017964s (55.667/s)
d442cc9f 233 .----------------------------------------------------------------+-----------.
234 | Action | Time |
235 +----------------------------------------------------------------+-----------+
3533daff 236 | /default | 0.000540s |
237 | /end | 0.001246s |
d442cc9f 238 '----------------------------------------------------------------+-----------'
239
240Press Ctrl-C to break out of the development server.
241
242
3533daff 243=head1 HELLO WORLD
d442cc9f 244
3533daff 245=head2 The Simplest Way
d442cc9f 246
3533daff 247The Root.pm controller is a place to put global actions that usually
248execute on the root URL. Open the C<lib/Hello/Controller/Root.pm> file in
865d3efb 249your editor. You will see the "index" subroutine, which is
3533daff 250responsible for displaying the welcome screen that you just saw in
251your browser. Later on you'll want to change that to something more
865d3efb 252reasonable, such as a "404" message or a redirect, but for now just
253leave it alone.
d442cc9f 254
865d3efb 255 sub index :Path :Args(0) {
3533daff 256 my ( $self, $c ) = @_;
865d3efb 257
258 # Hello World
3533daff 259 $c->response->body( $c->welcome_message );
d442cc9f 260 }
261
3533daff 262The "C<$c>" here refers to the Catalyst context, which is used to
263access the Catalyst application. In addition to many other things,
264the Catalyst context provides access to "response" and "request"
d0496197 265objects. (See L<Catalyst|Catalyst>,
266L<Catalyst::Response|Catalyst::Response>, and
267L<Catalyst::Request|Catalyst::Request>)
d442cc9f 268
14e5ed66 269C<$c-E<gt>response-E<gt>body> sets the HTTP response (see
270L<Catalyst::Response|Catalyst::Response>), while C<$c-E<gt>welcome_message>
d0496197 271is a special method that returns the welcome message that you saw in
272your browser.
d442cc9f 273
865d3efb 274The ":Path :Args(0)" after the method name are attributes which determine
3533daff 275which URLs will be dispatched to this method. (Depending on your version of
865d3efb 276Catalyst, it used to say "Private" but using that with 'default' or 'index'
277is currently deprecated.)
d442cc9f 278
3533daff 279Some MVC frameworks handle dispatching in a central place. Catalyst,
280by policy, prefers to handle URL dispatching with attributes on
281controller methods. There is a lot of flexibility in specifying which
282URLs to match. This particular method will match all URLs, because it
865d3efb 283doesn't specify the path (nothing comes after "Path"), but will only
284accept a single args because of the ":Args(0)".
d442cc9f 285
3533daff 286The default is to map URLs to controller names, and because of
287the way that Perl handles namespaces through package names,
288it is simple to create hierarchical structures in
289Catalyst. This means that you can create controllers with deeply
290nested actions in a clean and logical way.
d442cc9f 291
3533daff 292For example, the URL C<http://hello.com/admin/articles/create> maps
293to the package C<Hello::Controller::Admin::Articles>, and the C<create>
294method.
d442cc9f 295
d0496197 296Add the following subroutine to your C<lib/Hello/Controller/Root.pm>
297file:
d442cc9f 298
3533daff 299 sub hello : Global {
300 my ( $self, $c ) = @_;
d0496197 301
3533daff 302 $c->response->body("Hello, World!");
303 }
d442cc9f 304
3533daff 305Here you're sending your own string to the webpage.
306
307Save the file, start the server (stop and restart it if it's still
d0496197 308up), and go to L<http://localhost:3000/hello> to
3533daff 309see "Hello, World!"
310
865d3efb 311
3533daff 312=head2 Hello, World! Using a View and a Template
313
314In the Catalyst world a "View" is not a page of XHTML or a template
315designed to present a page to a browser. It is the module that
865d3efb 316determines the I<type> of view -- HTML, pdf, XML, etc. For the
317thing that generates the I<content> of that view, (such as the
318default Toolkit Template) the actual templates go under the
319"root" directory.
3533daff 320
321To create a TT view, run:
322
323 $ script/hello_create.pl view TT TT
324
325This creates the C<lib/Hello/View/TT.pm> module, which is a subclass of
326C<Catalyst::View::TT>. The "view" keyword tells the create script that
9555f8ab 327you are creating a view, the second "TT" tells it that you are creating
328a Template Toolkit view, and the first "TT" tells the script to name
3533daff 329the View module "TT.pm", which is a commonly used name for TT views.
330(You can name it anything you want, such as "HTML.pm".) If you look at
331TT.pm, you will find that it only contains a config statement to set
332the TT extension to ".tt".
333
334Now that the TT.pm "View" exists, Catalyst will autodiscover it and be
335able to use it to display the view templates, using the "process"
336method that it inherits from the C<Catalyst::View::TT class>.
337
c010ae0d 338Template Toolkit is a very full featured template facility, with
865d3efb 339excellent documentation at L<http://template-toolkit.org/>,
3533daff 340but since this is not a TT tutorial, we'll stick to only basic TT
341usage here (and explore some of the more common TT features in later
342parts of the tutorial).
343
344Create a C<root/hello.tt> template file (put it in the C<root> under
345the C<Hello> directory that is the base of your application). Here is
346a simple sample:
347
348 [% META title = 'Hello, World!' %]
349 <p>
d0496197 350 This is a TT view template, located in the 'root/' directory.
3533daff 351 </p>
352
353[% and %] are markers for the TT parts of the template. Inside you can
354access Perl variables and classes, and use TT directives. The rest of
d0496197 355the template is normal HTML. Change the hello method in
356C<lib/Hello/Controller/Root.pm> to the following:
3533daff 357
358 sub hello : Global {
359 my ( $self, $c ) = @_;
d0496197 360
3533daff 361 $c->stash->{template} = 'hello.tt';
362 }
d442cc9f 363
14e5ed66 364This time, instead of doing C<$c-E<gt>response->body()>, you are setting
3533daff 365the value of the "template" hash key in the Catalyst "stash", an area
366for putting information to share with other parts of your application.
367The "template" key determines which template will be displayed at the
368end of the method. Catalyst controllers have a default "end" action
369for all methods which causes the first (or default) view to be
14e5ed66 370rendered (unless there's a C<$c-E<gt>response->body()> statement). So your
3533daff 371template will be magically displayed at the end of your method.
d442cc9f 372
3533daff 373After saving the file, restart the development server, and look at
d0496197 374L<http://localhost:3000/hello> again. You should
3533daff 375see the template that you just made.
d442cc9f 376
d442cc9f 377
3533daff 378=head1 CREATE A SIMPLE CONTROLLER AND AN ACTION
d442cc9f 379
3533daff 380Create a controller named "Site" by executing the create script:
d442cc9f 381
3533daff 382 $ script/hello_create.pl controller Site
d442cc9f 383
3533daff 384This will create a C<lib/Hello/Controller/Site.pm> file (and a test
385file). Bring Site.pm up in your editor, and you can see that there's
386not much there. Most people probably don't bother to use the create
387script to make controllers after they're used to using Catalyst.
d442cc9f 388
d0496197 389In C<lib/Hello/Controller/Site.pm>, add the following method:
d442cc9f 390
3533daff 391 sub test : Local {
392 my ( $self, $c ) = @_;
d0496197 393
3533daff 394 $c->stash->{username} = "John";
395 $c->stash->{template} = 'site/test.tt';
d442cc9f 396 }
397
3533daff 398Notice the "Local" attribute on the method. This will allow the action
399to be executed on the "controller/method" URL, or, in this case,
400"site/test", instead of at the root site URL, like "Global". It's not
401actually necessary to set the template value, since by default TT will
402attempt to render a template that follows the naming pattern
403"controller/method.tt", and we're following that pattern here, but in
404other situations you will need to specify the template (such as if
405you've "forwarded" to the method, or if it doesn't follow the default
406naming convention). We've also put the variable "name" into the stash,
407for use in the template.
d442cc9f 408
3533daff 409Make a subdirectory "site" in the "root" directory. Copy the hello.tt
d0496197 410file into the directory as C<root/site/test.tt>, or create a new
411template file at that location. Include a line like:
d442cc9f 412
d0496197 413 <p>Hello, [% username %]!</p>
d442cc9f 414
3533daff 415Bring up or restart the server. Notice in the server output that
416C</site/test> is listed in the Loaded Path actions. Go to
865d3efb 417L<http://localhost:3000/site/test> in your browser.
d442cc9f 418
3533daff 419You should see your test.tt file displayed, including the name "John"
420that you set in the controller.
d442cc9f 421
d442cc9f 422
3533daff 423=head1 AUTHORS
d442cc9f 424
3533daff 425Gerda Shank, C<gerda.shank@gmail.com>
d442cc9f 426Kennedy Clark, C<hkclark@gmail.com>
427
428Please report any errors, issues or suggestions to the author. The
429most recent version of the Catalyst Tutorial can be found at
d712b826 430L<http://dev.catalyst.perl.org/repos/Catalyst/trunk/Catalyst-Manual/lib/Catalyst/Manual/Tutorial/>.
d442cc9f 431
45c7830f 432Copyright 2006-2008, Kennedy Clark & Gerda Shank, under Creative Commons License
865d3efb 433(L<http://creativecommons.org/licenses/by-sa/3.0/us/>).