3 Catalyst::Manual::Tutorial::CatalystBasics - Catalyst Tutorial - Part 2: Catalyst Application Development Basics
8 This is B<Part 2 of 10> for the Catalyst tutorial.
10 L<Tutorial Overview|Catalyst::Manual::Tutorial>
16 L<Introduction|Catalyst::Manual::Tutorial::Intro>
24 L<More Catalyst Basics|Catalyst::Manual::Tutorial::MoreCatalystBasics>
28 L<Basic CRUD|Catalyst::Manual::Tutorial::BasicCRUD>
32 L<Authentication|Catalyst::Manual::Tutorial::Authentication>
36 L<Authorization|Catalyst::Manual::Tutorial::Authorization>
40 L<Debugging|Catalyst::Manual::Tutorial::Debugging>
44 L<Testing|Catalyst::Manual::Tutorial::Testing>
48 L<Advanced CRUD|Catalyst::Manual::Tutorial::AdvancedCRUD>
52 L<Appendices|Catalyst::Manual::Tutorial::Appendices>
59 In this part of the tutorial, we will create a very basic Catalyst web
60 application, demonstrating a number of powerful capabilities, such as:
64 =item * Helper Scripts
66 Catalyst helper scripts that can be used to rapidly bootstrap the
67 skeletal structure of an application.
71 Model/View/Controller (MVC) provides an architecture that facilitates a
72 clean "separation of control" between the different portions of your
73 application. Given that many other documents cover this subject in
74 detail, MVC will not be discussed in depth here (for an excellent
75 introduction to MVC and general Catalyst concepts, please see
76 L<Catalyst::Manual::About|Catalyst::Manual::About>). In short:
82 The model usually represents a data store. In most applications, the
83 model equates to the objects that are created from and saved to your SQL
88 The view takes model objects and renders them into something for the end
89 user to look at. Normally this involves a template-generation tool that
90 creates HTML for the user's web browser, but it could easily be code
91 that generates other forms such as PDF documents, e-mails, spreadsheets,
92 or even "behind the scenes" formats such as XML and JSON.
96 As suggested by its name, the controller takes user requests and routes
97 them to the necessary model and view.
103 The use of Object-Relational Mapping (ORM) technology for database
104 access. Specifically, ORM provides an automated and standardized means
105 to persist and restore objects to/from a relational database.
109 You can checkout the source code for this example from the catalyst
110 subversion repository as per the instructions in
111 L<Catalyst::Manual::Tutorial::Intro|Catalyst::Manual::Tutorial::Intro>.
114 =head1 CREATE A CATALYST PROJECT
116 Catalyst provides a number of helper scripts that can be used to
117 quickly flesh out the basic structure of your application. All
118 Catalyst projects begin with the C<catalyst.pl> helper (see
119 L<Catalyst::Helper|Catalyst::Helper> for more information on helpers).
120 Also note that as of Catalyst 5.7000, you will not have the helper
121 scripts unless you install both L<Catalyst::Runtime|Catalyst::Runtime>
122 and L<Catalyst::Devel|Catalyst::Devel>.
124 In this first part of the tutorial, use the Catalyst
125 C<catalyst.pl> script to initialize the framework for an
126 application called C<Hello>:
130 created "Hello/script"
134 created "Hello/script/hello_create.pl"
137 The C<catalyst.pl> helper script will display the names of the
138 directories and files it creates:
140 Changes # Record of application changes
141 lib # Lib directory for your app's Perl modules
142 Hello # Application main 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
148 hello.conf # Application configuration file
150 root # Equiv of htdocs, dir for templates, css, javascript
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
166 Catalyst will "auto-discover" modules in the Controller, Model, and
167 View directories. When you use the hello_create.pl script it will
168 create Perl module scaffolds in those directories, plus test files in
169 the "t" directory. The default location for templates is in the "root"
170 directory. The scripts in the script directory will always start with
171 the lowercased version of your application name. If your app is
172 MaiTai, then the create script would be "maitai_create.pl".
174 Though it's too early for any significant celebration, we already have
175 a functioning application. We can use the Catalyst supplied script to
176 start up a development server and view the default Catalyst page in
177 your browser. All scripts in the script directory should be run from
178 the base directory of your application, so change to the Hello
181 Run the following command to start up the built-in development web
182 server (make sure you didn't forget the "C<cd Hello>" from the
185 $ script/hello_server.pl
186 [debug] Debug messages enabled
187 [debug] Statistics enabled
188 [debug] Loaded plugins:
189 .----------------------------------------------------------------------------.
190 | Catalyst::Plugin::ConfigLoader 0.20 |
191 | Catalyst::Plugin::Static::Simple 0.20 |
192 '----------------------------------------------------------------------------'
194 [debug] Loaded dispatcher "Catalyst::Dispatcher"
195 [debug] Loaded engine "Catalyst::Engine::HTTP"
196 [debug] Found home "/home/me/Hello"
197 [debug] Loaded Config "/home/me/Hello/hello.conf"
198 [debug] Loaded components:
199 .-----------------------------------------------------------------+----------.
201 +-----------------------------------------------------------------+----------+
202 | Hello::Controller::Root | instance |
203 '-----------------------------------------------------------------+----------'
205 [debug] Loaded Private actions:
206 .----------------------+--------------------------------------+--------------.
207 | Private | Class | Method |
208 +----------------------+--------------------------------------+--------------+
209 | /default | Hello::Controller::Root | default |
210 | /end | Hello::Controller::Root | end |
211 | /index | Hello::Controller::Root | index |
212 '----------------------+--------------------------------------+--------------'
214 [debug] Loaded Path actions:
215 .-------------------------------------+--------------------------------------.
217 +-------------------------------------+--------------------------------------+
220 '-------------------------------------+--------------------------------------'
222 [info] Hello powered by Catalyst 5.71000
223 You can connect to your server at http://debian:3000
225 Point your web browser to L<http://localhost:3000> (substituting a
226 different hostname or IP address as appropriate) and you should be
227 greeted by the Catalyst welcome screen (if you get some other welcome
228 screen or an "Index" screen, you probably forgot to specify port 3000
229 in your URL). Information similar to the following should be appended
230 to the logging output of the development server:
232 [info] *** Request 1 (0.005/s) [20712] [Sun Mar 8 15:49:09 2009] ***
233 [debug] "GET" request for "/" from "1.1.1.98"
234 [info] Request took 0.007342s (136.203/s)
235 .----------------------------------------------------------------+-----------.
237 +----------------------------------------------------------------+-----------+
238 | /index | 0.000491s |
240 '----------------------------------------------------------------+-----------'
242 Press Ctrl-C to break out of the development server.
247 =head2 The Simplest Way
249 The Root.pm controller is a place to put global actions that usually
250 execute on the root URL. Open the C<lib/Hello/Controller/Root.pm> file in
251 your editor. You will see the "index" subroutine, which is
252 responsible for displaying the welcome screen that you just saw in
253 your browser. Later on you'll want to change that to something more
254 reasonable, such as a "404" message or a redirect, but for now just
257 sub index :Path :Args(0) {
258 my ( $self, $c ) = @_;
261 $c->response->body( $c->welcome_message );
264 The "C<$c>" here refers to the Catalyst context, which is used to
265 access the Catalyst application. In addition to many other things,
266 the Catalyst context provides access to "response" and "request"
267 objects. (See L<Catalyst|Catalyst>,
268 L<Catalyst::Response|Catalyst::Response>, and
269 L<Catalyst::Request|Catalyst::Request>)
271 C<$c-E<gt>response-E<gt>body> sets the HTTP response (see
272 L<Catalyst::Response|Catalyst::Response>), while C<$c-E<gt>welcome_message>
273 is a special method that returns the welcome message that you saw in
276 The ":Path :Args(0)" after the method name are attributes which determine
277 which URLs will be dispatched to this method. (Depending on your version of
278 Catalyst, it used to say "Private" but using that with 'default' or 'index'
279 is currently deprecated.)
281 Some MVC frameworks handle dispatching in a central place. Catalyst,
282 by policy, prefers to handle URL dispatching with attributes on
283 controller methods. There is a lot of flexibility in specifying which
284 URLs to match. This particular method will match all URLs, because it
285 doesn't specify the path (nothing comes after "Path"), but will only
286 accept a single args because of the ":Args(0)".
288 The default is to map URLs to controller names, and because of
289 the way that Perl handles namespaces through package names,
290 it is simple to create hierarchical structures in
291 Catalyst. This means that you can create controllers with deeply
292 nested actions in a clean and logical way.
294 For example, the URL C<http://hello.com/admin/articles/create> maps
295 to the package C<Hello::Controller::Admin::Articles>, and the C<create>
298 Add the following subroutine to your C<lib/Hello/Controller/Root.pm>
302 my ( $self, $c ) = @_;
304 $c->response->body("Hello, World!");
307 B<TIP>: See Appendix 1 for tips on removing the leading spaces when
308 cutting and pasting example code from POD-based documents.
310 Here you're sending your own string to the webpage.
312 Save the file, start the server (stop and restart it if it's still
313 up), and go to L<http://localhost:3000/hello> to
317 =head2 Hello, World! Using a View and a Template
319 In the Catalyst world a "View" is not a page of XHTML or a template
320 designed to present a page to a browser. It is the module that
321 determines the I<type> of view -- HTML, pdf, XML, etc. For the
322 thing that generates the I<content> of that view, (such as the
323 default Toolkit Template) the actual templates go under the
326 To create a TT view, run:
328 $ script/hello_create.pl view TT TT
330 This creates the C<lib/Hello/View/TT.pm> module, which is a subclass of
331 C<Catalyst::View::TT>.
337 The "view" keyword tells the create script that you are creating a view.
341 The first "TT" tells the script to name the View module "TT.pm", which is a
342 commonly used name for TT views. (You can name it anything you want, such as
347 The final "TT" tells it that you are creating a Template Toolkit view.
351 If you look at C<lib/Hello/View/TT.pm> you will find that it only contains a
352 config statement to set the TT extension to ".tt".
354 Now that the TT.pm "View" exists, Catalyst will autodiscover it and be
355 able to use it to display the view templates, using the "process"
356 method that it inherits from the C<Catalyst::View::TT class>.
358 Template Toolkit is a very full featured template facility, with
359 excellent documentation at L<http://template-toolkit.org/>,
360 but since this is not a TT tutorial, we'll stick to only basic TT
361 usage here (and explore some of the more common TT features in later
362 parts of the tutorial).
364 Create a C<root/hello.tt> template file (put it in the C<root> under
365 the C<Hello> directory that is the base of your application). Here is
369 This is a TT view template, called '[% template.name %]'.
372 [% and %] are markers for the TT parts of the template. Inside you can
373 access Perl variables and classes, and use TT directives. In this
374 case, we're using a special TT variable that defines the name of the
375 template file (C<hello.tt>). The rest of the template is normal HTML.
377 Change the hello method in C<lib/Hello/Controller/Root.pm> to the
381 my ( $self, $c ) = @_;
383 $c->stash->{template} = 'hello.tt';
386 This time, instead of doing C<$c-E<gt>response-E<gt>body()>, you are setting
387 the value of the "template" hash key in the Catalyst "stash", an area
388 for putting information to share with other parts of your application.
389 The "template" key determines which template will be displayed at the
390 end of the method. Catalyst controllers have a default "end" action
391 for all methods which causes the first (or default) view to be
392 rendered (unless there's a C<$c-E<gt>response-E<gt>body()> statement). So your
393 template will be magically displayed at the end of your method.
395 After saving the file, restart the development server, and look at
396 L<http://localhost:3000/hello> again. You should
397 see the template that you just made.
400 =head1 CREATE A SIMPLE CONTROLLER AND AN ACTION
402 Create a controller named "Site" by executing the create script:
404 $ script/hello_create.pl controller Site
406 This will create a C<lib/Hello/Controller/Site.pm> file (and a test
407 file). Bring Site.pm up in your editor, and you can see that there's
408 not much there. Most people probably don't bother to use the create
409 script to make controllers after they're used to using Catalyst.
411 In C<lib/Hello/Controller/Site.pm>, add the following method:
414 my ( $self, $c ) = @_;
416 $c->stash->{username} = "John";
417 $c->stash->{template} = 'site/test.tt';
420 Notice the "Local" attribute on the C<test> method. This will cause
421 the C<test> action (now that we have assigned an action type to the
422 method it appears as a controller "action" to Catalyst) to be executed
423 on the "controller/method" URL, or, in this case, "site/test". We
424 will see additional information on controller actions throughout the
425 rest of the tutorial, but if you are curious take a look at
426 L<Catalyst::Manual::Intro/Actions>.
428 It's not actually necessary to set the template value as we do here.
429 By default TT will attempt to render a template that follows the
430 naming pattern "controller/method.tt", and we're following that
431 pattern here. However, in other situations you will need to specify
432 the template (such as if you've "forwarded" to the method, or if it
433 doesn't follow the default naming convention).
435 We've also put the variable "username" into the stash, for use in the
438 Make a subdirectory "site" in the "root" directory. Copy the hello.tt
439 file into the directory as C<root/site/test.tt>, or create a new
440 template file at that location. Include a line like:
442 <p>Hello, [% username %]!</p>
444 Bring up or restart the server. Notice in the server output that
445 C</site/test> is listed in the Loaded Path actions. Go to
446 L<http://localhost:3000/site/test> in your browser.
448 You should see your test.tt file displayed, including the name "John"
449 that you set in the controller.
454 Gerda Shank, C<gerda.shank@gmail.com>
455 Kennedy Clark, C<hkclark@gmail.com>
457 Please report any errors, issues or suggestions to the author. The
458 most recent version of the Catalyst Tutorial can be found at
459 L<http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Manual/5.70/trunk/lib/Catalyst/Manual/Tutorial/>.
461 Copyright 2006-2008, Kennedy Clark & Gerda Shank, under Creative Commons License
462 (L<http://creativecommons.org/licenses/by-sa/3.0/us/>).