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