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|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|Catalyst::Manual::Tutorial::01_Intro>.
116 =head1 CREATE A CATALYST PROJECT
118 Catalyst provides a number of helper scripts that can be used to
119 quickly flesh out the basic structure of your application. All
120 Catalyst projects begin with the C<catalyst.pl> helper (see
121 L<Catalyst::Helper|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|Catalyst::Runtime>
124 and L<Catalyst::Devel|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
173 View directories. When you use the hello_create.pl script it will
174 create Perl module scaffolds in those directories, plus test files in
175 the "t" 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
178 MaiTai, then the create script would be "maitai_create.pl".
180 Though it's too early for any significant celebration, we already have
181 a functioning application. We can use the Catalyst supplied script to
182 start up a development server and view the default Catalyst page in
183 your browser. All scripts in the script directory should be run from
184 the base directory of your application, so change to the Hello
187 Run the following command to start up the built-in development web
188 server (make sure you didn't forget the "C<cd Hello>" from the
191 B<Note>: the -r enables reloading on code changes so you don't have to stop and
192 start the server when you update code. see perldoc script/hello_server.pl for
195 $ script/hello_server.pl -r
196 [debug] Debug messages enabled
197 [debug] Statistics enabled
198 [debug] Loaded plugins:
199 .----------------------------------------------------------------------------.
200 | Catalyst::Plugin::ConfigLoader 0.27 |
201 '----------------------------------------------------------------------------'
203 [debug] Loaded dispatcher "Catalyst::Dispatcher"
204 [debug] Loaded engine "Catalyst::Engine::HTTP"
205 [debug] Found home "/home/me/Hello"
206 [debug] Loaded Config "/home/me/Hello/hello.conf"
207 [debug] Loaded components:
208 .-----------------------------------------------------------------+----------.
210 +-----------------------------------------------------------------+----------+
211 | Hello::Controller::Root | instance |
212 '-----------------------------------------------------------------+----------'
214 [debug] Loaded Private actions:
215 .----------------------+--------------------------------------+--------------.
216 | Private | Class | Method |
217 +----------------------+--------------------------------------+--------------+
218 | /default | Hello::Controller::Root | default |
219 | /end | Hello::Controller::Root | end |
220 | /index | Hello::Controller::Root | index |
221 '----------------------+--------------------------------------+--------------'
223 [debug] Loaded Path actions:
224 .-------------------------------------+--------------------------------------.
226 +-------------------------------------+--------------------------------------+
229 '-------------------------------------+--------------------------------------'
231 [info] Hello powered by Catalyst 5.80018
232 You can connect to your server at http://debian:3000
234 Point your web browser to L<http://localhost:3000> (substituting a
235 different hostname or IP address as appropriate) and you should be
236 greeted by the Catalyst welcome screen (if you get some other welcome
237 screen or an "Index" screen, you probably forgot to specify port 3000
238 in your URL). Information similar to the following should be appended
239 to the logging output of the development server:
241 [info] *** Request 1 (0.001/s) [23194] [Sat Jan 16 11:09:18 2010] ***
242 [debug] "GET" request for "/" from "127.0.0.1"
244 [info] Request took 0.004851s (206.143/s)
245 .------------------------------------------------------------+-----------.
247 +------------------------------------------------------------+-----------+
248 | /index | 0.000395s |
250 '------------------------------------------------------------+-----------'
252 B<Note>: Press Ctrl-C to break out of the development server if necessary.
257 =head2 The Simplest Way
259 The Root.pm controller is a place to put global actions that usually
260 execute on the root URL. Open the C<lib/Hello/Controller/Root.pm> file in
261 your editor. You will see the "index" subroutine, which is
262 responsible for displaying the welcome screen that you just saw in
263 your browser. Later on you'll want to change that to something more
264 reasonable, such as a "404" message or a redirect, but for now just
267 sub index :Path :Args(0) {
268 my ( $self, $c ) = @_;
271 $c->response->body( $c->welcome_message );
274 The "C<$c>" here refers to the Catalyst context, which is used to
275 access the Catalyst application. In addition to many other things,
276 the Catalyst context provides access to "response" and "request"
277 objects. (See L<Catalyst|Catalyst>,
278 L<Catalyst::Response|Catalyst::Response>, and
279 L<Catalyst::Request|Catalyst::Request>)
281 C<$c-E<gt>response-E<gt>body> sets the HTTP response (see
282 L<Catalyst::Response|Catalyst::Response>), while C<$c-E<gt>welcome_message>
283 is a special method that returns the welcome message that you saw in
286 The ":Path :Args(0)" after the method name are attributes which
287 determine which URLs will be dispatched to this method. (You might see
288 ":Private" if you are using an older version of Catalyst, but using
289 that with 'default' or 'index' is currently deprecated. If so, you
290 should also probably upgrade before continuing the tutorial.)
292 Some MVC frameworks handle dispatching in a central place. Catalyst,
293 by policy, prefers to handle URL dispatching with attributes on
294 controller methods. There is a lot of flexibility in specifying which
295 URLs to match. This particular method will match all URLs, because it
296 doesn't specify the path (nothing comes after "Path"), but will only
297 accept a URL without any args because of the ":Args(0)".
299 The default is to map URLs to controller names, and because of the way
300 that Perl handles namespaces through package names, it is simple to
301 create hierarchical structures in Catalyst. This means that you can
302 create controllers with deeply nested actions in a clean and logical
303 way. For example, the URL C<http://hello.com/admin/articles/create>
304 maps to the package C<Hello::Controller::Admin::Articles>, and the
307 Add the following subroutine to your C<lib/Hello/Controller/Root.pm>
311 my ( $self, $c ) = @_;
313 $c->response->body("Hello, World!");
316 B<TIP>: See Appendix 1 for tips on removing the leading spaces when
317 cutting and pasting example code from POD-based documents.
319 Here you're sending your own string to the webpage.
321 Save the file, and you should notice the following in your server output:
323 Saw changes to the following files:
324 - /srv/http/xenoterracide/Catalyst/Hello/lib/Hello/Controller/Root.pm (modify)
326 Attempting to restart the server
328 [debug] Loaded Private actions:
329 .----------------------+--------------------------------------+--------------.
330 | Private | Class | Method |
331 +----------------------+--------------------------------------+--------------+
332 | /default | Hello::Controller::Root | default |
333 | /end | Hello::Controller::Root | end |
334 | /index | Hello::Controller::Root | index |
335 | /hello | Hello::Controller::Root | hello |
336 '----------------------+--------------------------------------+--------------'
338 [debug] Loaded Path actions:
339 .-------------------------------------+--------------------------------------.
341 +-------------------------------------+--------------------------------------+
345 '-------------------------------------+--------------------------------------'
348 Go to L<http://localhost:3000/hello> to see "Hello, World!".
350 =head2 Hello, World! Using a View and a Template
352 In the Catalyst world a "View" itself is not a page of XHTML or a
353 template designed to present a page to a browser. Rather, it is the
354 module that determines the I<type> of view -- HTML, pdf, XML, etc. For
355 the thing that generates the I<content> of that view (such as the a
356 Toolkit Template template file), the actual templates go under the
359 To create a TT view, run:
361 $ script/hello_create.pl view TT TT
363 This creates the C<lib/Hello/View/TT.pm> module, which is a subclass of
364 C<Catalyst::View::TT>.
370 The "view" keyword tells the create script that you are creating a view.
374 The first "TT" tells the script to name the View module "TT.pm", which is a
375 commonly used name for TT views. (You can name it anything you want, such as
380 The final "TT" tells Catalyst the I<type> of the view, with "TT"
381 indicating that you want to a Template Toolkit view.
385 If you look at C<lib/Hello/View/TT.pm> you will find that it only
386 contains a config statement to set the TT extension to ".tt".
388 Now that the TT.pm "View" exists, Catalyst will autodiscover it and be
389 able to use it to display the view templates using the "process"
390 method that it inherits from the C<Catalyst::View::TT class>.
392 Template Toolkit is a very full featured template facility, with
393 excellent documentation at L<http://template-toolkit.org/>,
394 but since this is not a TT tutorial, we'll stick to only basic TT
395 usage here (and explore some of the more common TT features in later
396 chapters of the tutorial).
398 Create a C<root/hello.tt> template file (put it in the C<root> under
399 the C<Hello> directory that is the base of your application). Here is
403 This is a TT view template, called '[% template.name %]'.
406 [% and %] are markers for the TT parts of the template. Inside you can
407 access Perl variables and classes, and use TT directives. In this
408 case, we're using a special TT variable that defines the name of the
409 template file (C<hello.tt>). The rest of the template is normal HTML.
411 Change the hello method in C<lib/Hello/Controller/Root.pm> to the
415 my ( $self, $c ) = @_;
417 $c->stash->{template} = 'hello.tt';
420 This time, instead of doing C<$c-E<gt>response-E<gt>body()>, you are
421 setting the value of the "template" hash key in the Catalyst "stash",
422 an area for putting information to share with other parts of your
423 application. The "template" key determines which template will be
424 displayed at the end of the request cycle. Catalyst controllers have a
425 default "end" action for all methods which causes the first (or
426 default) view to be rendered (unless there's a C<$c-E<gt>response-
427 E<gt>body()> statement). So your template will be magically displayed
428 at the end of your method.
430 =head1 CREATE A SIMPLE CONTROLLER AND AN ACTION
432 Create a controller named "Site" by executing the create script:
434 $ script/hello_create.pl controller Site
436 This will create a C<lib/Hello/Controller/Site.pm> file (and a test
437 file). Bring Site.pm up in your editor, and you can see that there's
440 In C<lib/Hello/Controller/Site.pm>, add the following method:
443 my ( $self, $c ) = @_;
445 $c->stash->{username} = "John";
446 $c->stash->{template} = 'site/test.tt';
449 Notice the "Local" attribute on the C<test> method. This will cause
450 the C<test> action (now that we have assigned an "action type" to the
451 method it appears as a "controller action" to Catalyst) to be executed
452 on the "controller/method" URL, or, in this case, "site/test". We
453 will see additional information on controller actions throughout the
454 rest of the tutorial, but if you are curious take a look at
455 L<Catalyst::Manual::Intro/Actions>.
457 It's not actually necessary to set the template value as we do here.
458 By default TT will attempt to render a template that follows the
459 naming pattern "controller/method.tt", and we're following that
460 pattern here. However, in other situations you will need to specify
461 the template (such as if you've "forwarded" to the method, or if it
462 doesn't follow the default naming convention).
464 We've also put the variable "username" into the stash, for use in the
467 Make a subdirectory "site" in the "root" directory. Copy the hello.tt
468 file into the directory as C<root/site/test.tt>, or create a new
469 template file at that location. Include a line like:
471 <p>Hello, [% username %]!</p>
473 You should see your test.tt file displayed, including the name "John"
474 that you set in the controller.
479 Gerda Shank, C<gerda.shank@gmail.com>
480 Kennedy Clark, C<hkclark@gmail.com>
482 Please report any errors, issues or suggestions to the author. The
483 most recent version of the Catalyst Tutorial can be found at
484 L<http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Manual/5.80/trunk/lib/Catalyst/Manual/Tutorial/>.
486 Copyright 2006-2008, Kennedy Clark & Gerda Shank, under Creative Commons License
487 (L<http://creativecommons.org/licenses/by-sa/3.0/us/>).