3 Catalyst::Manual::Tutorial::02_CatalystBasics - Catalyst Tutorial - Chapter 2: Catalyst Application Development Basics
8 This is B<Chapter 2 of 10> for the Catalyst tutorial.
10 L<Tutorial Overview|Catalyst::Manual::Tutorial>
16 L<Introduction|Catalyst::Manual::Tutorial::01_Intro>
24 L<More Catalyst Basics|Catalyst::Manual::Tutorial::03_MoreCatalystBasics>
28 L<Basic CRUD|Catalyst::Manual::Tutorial::04_BasicCRUD>
32 L<Authentication|Catalyst::Manual::Tutorial::05_Authentication>
36 L<Authorization|Catalyst::Manual::Tutorial::06_Authorization>
40 L<Debugging|Catalyst::Manual::Tutorial::07_Debugging>
44 L<Testing|Catalyst::Manual::Tutorial::08_Testing>
48 L<Advanced CRUD|Catalyst::Manual::Tutorial::09_AdvancedCRUD>
52 L<Appendices|Catalyst::Manual::Tutorial::10_Appendices>
59 In this chapter of the tutorial, we will create a very basic Catalyst
60 web application, demonstrating a number of powerful capabilities, such
65 =item * Helper Scripts
67 Catalyst helper scripts that can be used to rapidly bootstrap the
68 skeletal structure of an application.
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:
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
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.
97 As suggested by its name, the controller takes user requests and routes
98 them to the necessary model and view.
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.
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>.
116 =head1 CREATE A CATALYST PROJECT
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>.
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>:
131 created "Hello/script"
135 created "Hello/script/hello_create.pl"
136 Change to application directory and Run "perl Makefile.PL" to make sure your install is complete
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
143 The C<catalyst.pl> helper script will display the names of the
144 directories and files it creates:
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
156 root # Equiv of htdocs, dir for templates, css, javascript
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
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".
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.
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
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.
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.30 |
204 '----------------------------------------------------------------------------'
206 [debug] Loaded dispatcher "Catalyst::Dispatcher"
207 [debug] Loaded engine "Catalyst::Engine"
208 [debug] Found home "/root/Hello"
209 [debug] Loaded Config "/root/Hello/hello.conf"
210 [debug] Loaded components:
211 .-----------------------------------------------------------------+----------.
213 +-----------------------------------------------------------------+----------+
214 | Hello::Controller::Root | instance |
215 '-----------------------------------------------------------------+----------'
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 '----------------------+--------------------------------------+--------------'
226 [debug] Loaded Path actions:
227 .-------------------------------------+--------------------------------------.
229 +-------------------------------------+--------------------------------------+
232 '-------------------------------------+--------------------------------------'
234 [info] Hello powered by Catalyst 5.90002
235 HTTP::Server::PSGI: Accepting connections at http://0:3000/
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:
244 [info] Hello powered by Catalyst 5.90002
245 HTTP::Server::PSGI: Accepting connections at http://0:3000/
246 [info] *** Request 1 (0.067/s) [19026] [Tue Aug 30 17:24:32 2011] ***
247 [debug] "GET" request for "/" from "192.168.245.2"
249 [debug] Response Code: 200; Content-Type: text/html; charset=utf-8; Content-Length: 5613
250 [info] Request took 0.040895s (24.453/s)
251 .------------------------------------------------------------+-----------.
253 +------------------------------------------------------------+-----------+
254 | /index | 0.000916s |
256 '------------------------------------------------------------+-----------'
258 B<Note>: Press C<Ctrl-C> to break out of the development server if
264 =head2 The Simplest Way
266 The Root.pm controller is a place to put global actions that usually
267 execute on the root URL. Open the C<lib/Hello/Controller/Root.pm> file
268 in your editor. You will see the "index" subroutine, which is
269 responsible for displaying the welcome screen that you just saw in your
272 sub index :Path :Args(0) {
273 my ( $self, $c ) = @_;
276 $c->response->body( $c->welcome_message );
279 Later on you'll want to change that to something more reasonable, such
280 as a "404" message or a redirect, but for now just leave it alone.
282 The "C<$c>" here refers to the Catalyst context, which is used to access
283 the Catalyst application. In addition to many other things, the Catalyst
284 context provides access to "response" and "request" objects. (See
285 L<Catalyst>, L<Catalyst::Response>, and
286 L<Catalyst::Request>)
288 C<$c-E<gt>response-E<gt>body> sets the HTTP response (see
289 L<Catalyst::Response>), while
290 C<$c-E<gt>welcome_message> is a special method that returns the welcome
291 message that you saw in your browser.
293 The ":Path :Args(0)" after the method name are attributes which
294 determine which URLs will be dispatched to this method. (You might see
295 ":Private" if you are using an older version of Catalyst, but using that
296 with "default" or "index" is currently deprecated. If so, you should
297 also probably upgrade before continuing the tutorial.)
299 Some MVC frameworks handle dispatching in a central place. Catalyst, by
300 policy, prefers to handle URL dispatching with attributes on controller
301 methods. There is a lot of flexibility in specifying which URLs to
302 match. This particular method will match all URLs, because it doesn't
303 specify the path (nothing comes after "Path"), but will only accept a
304 URL without any args because of the ":Args(0)".
306 The default is to map URLs to controller names, and because of the way
307 that Perl handles namespaces through package names, it is simple to
308 create hierarchical structures in Catalyst. This means that you can
309 create controllers with deeply nested actions in a clean and logical
310 way. For example, the URL C<http://hello.com/admin/articles/create> maps
311 to the package C<Hello::Controller::Admin::Articles>, and the C<create>
314 While you leave the C<script/hello_server.pl -r> command running the
315 development server in one window (don't forget the "-r" on the end!),
316 open another window and add the following subroutine to your
317 C<lib/Hello/Controller/Root.pm> file:
320 my ( $self, $c ) = @_;
322 $c->response->body("Hello, World!");
325 B<TIP>: See Appendix 1 for tips on removing the leading spaces when
326 cutting and pasting example code from POD-based documents.
328 Notice in the window running the Development Server that you should
329 get output similar to the following:
331 Saw changes to the following files:
332 - /root/Hello/lib/Hello/Controller/Root.pm (modify)
334 Attempting to restart the server
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 '----------------------+--------------------------------------+--------------'
347 The development server noticed the change in C<Hello::Controller::Root>
348 and automatically restarted itself.
350 Go to L<http://localhost:3000/hello> to see "Hello, World!". Also
351 notice that the newly defined 'hello' action is listed under "Loaded
352 Private actions" in the development server debug output.
355 =head2 Hello, World! Using a View and a Template
357 In the Catalyst world a "View" itself is not a page of XHTML or a
358 template designed to present a page to a browser. Rather, it is the
359 module that determines the I<type> of view -- HTML, pdf, XML, etc. For
360 the thing that generates the I<content> of that view (such as a
361 Toolkit Template template file), the actual templates go under the
364 To create a TT view, run:
366 $ script/hello_create.pl view HTML TT
368 This creates the C<lib/Hello/View/HTML.pm> module, which is a subclass
369 of C<Catalyst::View::TT>.
375 The "view" keyword tells the create script that you are creating a view.
379 The first argument "HTML" tells the script to name the View module "HTML.pm",
380 which is a commonly used name for TT views. You can name it anything you want,
381 such as "MyView.pm". If you have more than one view, be sure to set the
382 default_view in Hello.pm (See L<Catalyst::View::TT> for more
383 details on setting this).
387 The final "TT" tells Catalyst the I<type> of the view, with "TT"
388 indicating that you want to a Template Toolkit view.
392 If you look at C<lib/Hello/View/HTML.pm> you will find that it only
393 contains a config statement to set the TT extension to ".tt".
395 Now that the HTML.pm "View" exists, Catalyst will autodiscover it and be
396 able to use it to display the view templates using the "process" method
397 that it inherits from the C<Catalyst::View::TT> class.
399 Template Toolkit is a very full featured template facility, with
400 excellent documentation at L<http://template-toolkit.org/>, but since
401 this is not a TT tutorial, we'll stick to only basic TT usage here (and
402 explore some of the more common TT features in later chapters of the
405 Create a C<root/hello.tt> template file (put it in the C<root> under the
406 C<Hello> directory that is the base of your application). Here is a
410 This is a TT view template, called '[% template.name %]'.
413 [% and %] are markers for the TT parts of the template. Inside you can
414 access Perl variables and classes, and use TT directives. In this case,
415 we're using a special TT variable that defines the name of the template
416 file (C<hello.tt>). The rest of the template is normal HTML.
418 Change the hello method in C<lib/Hello/Controller/Root.pm> to the
422 my ( $self, $c ) = @_;
424 $c->stash(template => 'hello.tt');
427 This time, instead of doing C<$c-E<gt>response-E<gt>body()>, you are
428 setting the value of the "template" hash key in the Catalyst "stash", an
429 area for putting information to share with other parts of your
430 application. The "template" key determines which template will be
431 displayed at the end of the request cycle. Catalyst controllers have a
432 default "end" action for all methods which causes the first (or default)
433 view to be rendered (unless there's a C<$c-E<gt>response- E<gt>body()>
434 statement). So your template will be magically displayed at the end of
437 After saving the file, the development server should automatically
438 restart (again, the tutorial is written to assume that you are using the
439 "-r" option -- manually restart it if you aren't), and look at
440 L<http://localhost:3000/hello> in your again. You should see the
441 template that you just made.
443 B<TIP:> If you keep the server running with "-r" in a "background
444 window," don't let that window get totally hidden... if you have an
445 syntax error in your code, the debug server output will contain the
448 B<Note:> You will probably run into a variation of the "stash"
449 statement above that looks like:
451 $c->stash->{template} = 'hello.tt';
453 Although this style is still relatively common, the approach we
454 used previous is becoming more common because it allows you to
455 set multiple stash variables in one line. For example:
457 $c->stash(template => 'hello.tt', foo => 'bar',
460 You can also set multiple stash values with a hashref:
462 $c->stash({template => 'hello.tt', foo => 'bar',
463 another_thing => 1});
465 Any of these formats work, but the C<$c-E<gt>stash(name =E<gt> value);>
466 style is growing in popularity -- you may wish to use it all the time
467 (even when you are only setting a single value).
470 =head1 CREATE A SIMPLE CONTROLLER AND AN ACTION
472 Create a controller named "Site" by executing the create script:
474 $ script/hello_create.pl controller Site
476 This will create a C<lib/Hello/Controller/Site.pm> file (and a test
477 file). Bring Site.pm up in your editor, and you can see that there's not
480 In C<lib/Hello/Controller/Site.pm>, add the following method:
483 my ( $self, $c ) = @_;
485 $c->stash(username => 'John',
486 template => 'site/test.tt');
489 Notice the "Local" attribute on the C<test> method. This will cause the
490 C<test> action (now that we have assigned an "action type" to the method
491 it appears as a "controller action" to Catalyst) to be executed on the
492 "controller/method" URL, or, in this case, "site/test". We will see
493 additional information on controller actions throughout the rest of the
494 tutorial, but if you are curious take a look at
495 L<Catalyst::Manual::Intro/Actions>.
497 It's not actually necessary to set the template value as we do here. By
498 default TT will attempt to render a template that follows the naming
499 pattern "controller/method.tt", and we're following that pattern here.
500 However, in other situations you will need to specify the template (such
501 as if you've "forwarded" to the method, or if it doesn't follow the
502 default naming convention).
504 We've also put the variable "username" into the stash, for use in the
507 Make a subdirectory "site" in the "root" directory.
511 Create a new template file in that direction named C<root/site/test.tt>
512 and include a line like:
514 <p>Hello, [% username %]!</p>
516 Once the server automatically restarts, notice in the server output that
517 C</site/test> is listed in the Loaded Path actions. Go to
518 L<http://localhost:3000/site/test> in your browser and you should see
519 your test.tt file displayed, including the name "John" that you set in
523 You can jump to the next chapter of the tutorial here:
524 L<More Catalyst Basics|Catalyst::Manual::Tutorial::03_MoreCatalystBasics>
530 Gerda Shank, C<gerda.shank@gmail.com>
531 Kennedy Clark, C<hkclark@gmail.com>
533 Feel free to contact the author for any errors or suggestions, but the
534 best way to report issues is via the CPAN RT Bug system at
535 <https://rt.cpan.org/Public/Dist/Display.html?Name=Catalyst-Manual>.
537 The most recent version of the Catalyst Tutorial can be found at
538 L<http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Manual/5.80/trunk/lib/Catalyst/Manual/Tutorial/>.
540 Copyright 2006-2010, Kennedy Clark, under the
541 Creative Commons Attribution Share-Alike License Version 3.0
542 (L<http://creativecommons.org/licenses/by-sa/3.0/us/>).