Cleaned up Tut files; no substantive changes
Matt S Trout [Thu, 8 Jun 2006 14:37:14 +0000 (14:37 +0000)]
r8782@cain (orig r4168):  jester | 2006-05-20 04:39:30 +0000

12 files changed:
lib/Catalyst/Manual/Installation.pod
lib/Catalyst/Manual/Installation/CentOS4.pod
lib/Catalyst/Manual/Tutorial.pod
lib/Catalyst/Manual/Tutorial/AdvancedCRUD.pod
lib/Catalyst/Manual/Tutorial/Appendices.pod
lib/Catalyst/Manual/Tutorial/Authentication.pod
lib/Catalyst/Manual/Tutorial/Authorization.pod
lib/Catalyst/Manual/Tutorial/BasicCRUD.pod
lib/Catalyst/Manual/Tutorial/CatalystBasics.pod
lib/Catalyst/Manual/Tutorial/Debugging.pod
lib/Catalyst/Manual/Tutorial/Intro.pod
lib/Catalyst/Manual/Tutorial/Testing.pod

index f21dd5b..a942b7a 100644 (file)
@@ -1,45 +1,61 @@
 =head1 NAME
 
-Catalyst::Manual::Installation – Catalyst Installation
+Catalyst::Manual::Installation - Catalyst Installation
 
 
 
 =head1 DESCRIPTION
 
-This section of the Catalyst tutorial looks at a number of items required to first get going with Catalyst development.
+This section of the Catalyst tutorial looks at a number of items
+required to first get going with Catalyst development.
 
 
 
 =head1 INSTALLATION
 
-On one hand, Catalyst gains immediate power and flexibility through is use of CPAN (the Comprehensive Perl Archive Network, an enormous global repository containing over 10,000 free modules).  On the other hand, Catalyst's reliance on CPAN can complicate initial installations.  Fortunately, there are a growing number of methods that can dramatically ease this undertaking:
+On one hand, Catalyst gains immediate power and flexibility through is
+use of CPAN (the Comprehensive Perl Archive Network, an enormous global
+repository containing over 10,000 free modules).  On the other hand,
+Catalyst's reliance on CPAN can complicate initial installations.
+Fortunately, there are a growing number of methods that can dramatically
+ease this undertaking:
 
 =over 4
 
 =item * 
 
-Matt Trout’s C<cat-install>
+Matt Trout's C<cat-install>
 
-Available at L<http://www.shadowcatsystems.co.uk/static/cat-install>, C<cat-install> can be a quick and painless way to get Catalyst up and running.  Just download the script from the link above and type C<perl cat-install>.
+Available at L<http://www.shadowcatsystems.co.uk/static/cat-install>,
+C<cat-install> can be a quick and painless way to get Catalyst up and
+running.  Just download the script from the link above and type C<perl
+cat-install>.
 
 =item * 
 
 Chris Laco's CatInABox
 
-Download the tarball from L<http://handelframework.com/downloads/CatInABox.tar.gz> and unpack it on your machine.  Depending on your OS platform, either run C<start.bat> or C<start.sh>.
+Download the tarball from
+L<http://handelframework.com/downloads/CatInABox.tar.gz> and unpack it
+on your machine.  Depending on your OS platform, either run C<start.bat>
+or C<start.sh>.
 
 =item * 
 
 Pre-Built VMWare Images
 
-Under the VMWare community program, work is ongoing to develop a number of VMWare images where an entire Catalyst development environment has already been installed, complete with database engines and a full complement of Catalyst plugins.
+Under the VMWare community program, work is ongoing to develop a number
+of VMWare images where an entire Catalyst development environment has
+already been installed, complete with database engines and a full
+complement of Catalyst plugins.
 
 =back
 
 
 =head2 OTHER METHODS
 
-In addition to the "all-in-one" approaches mentioned above, there are a variety of other installation techniques:
+In addition to the "all-in-one" approaches mentioned above, there are a
+variety of other installation techniques:
 
 =over 4
 
@@ -47,33 +63,48 @@ In addition to the "all-in-one" approaches mentioned above, there are a variety
 
 CPAN
 
-The traditional way to install Catalyst is directly from CPAN using C<Task::Catalyst> bundle:
+The traditional way to install Catalyst is directly from CPAN using
+C<Task::Catalyst> bundle:
 
-       $ perl –MCPAN –e 'install Task::Catalyst'
+       $ perl -MCPAN -e 'install Task::Catalyst'
 
-Unless you have a particularly complete set of Perl modules already installed, be prepared for a large number of nested dependencies.
+Unless you have a particularly complete set of Perl modules already
+installed, be prepared for a large number of nested dependencies.
 
 =item * 
 
 Gentoo Linux
 
-For users of Gentoo, see C<http://gentoo-wiki.com/HOWTO_Catalyst_Framework> for automated installations.  In short, simply mount the portage overlay and type C<emerge catalystframework>.
+For users of Gentoo, see
+C<http://gentoo-wiki.com/HOWTO_Catalyst_Framework> for automated
+installations.  In short, simply mount the portage overlay and type
+C<emerge catalystframework>.
 
 =items * 
 
 FreeBSD
 
-FreeBSD users can get up and running quickly by typing C<cd /usr/ports/www/p5-Catalyst && make install>.
+FreeBSD users can get up and running quickly by typing C<cd
+/usr/ports/www/p5-Catalyst && make install>.
 
 =item * 
 
 Windows ActivePerl
 
-Windows users can take advantage of the PPM tool that comes with ActivePerl to jumpstart their Catalyst environment.  Directions are available at L<http://catalyst.infogami.com/katalytes/cat_on_windows>.
+Windows users can take advantage of the PPM tool that comes with
+ActivePerl to jumpstart their Catalyst environment.  Directions are
+available at L<http://catalyst.infogami.com/katalytes/cat_on_windows>.
 
 =back
 
-B<NOTE:> Although all of the above methods can be used to install a base Catalyst system, only the VMWare image is likely to have all of the plugins and modules you need to complete this tutorial.  When you start the C<script/myapp_server.pl> development server later to run your application, it will tell you about any modules that are missing.  To add them, type something along the lines of the following (C<Catalyst::Model::DBIC::Schema> is used here as a representative example):
+B<NOTE:> Although all of the above methods can be used to install a base
+Catalyst system, only the VMWare image is likely to have all of the
+plugins and modules you need to complete this tutorial.  When you start
+the C<script/myapp_server.pl> development server later to run your
+application, it will tell you about any modules that are missing.  To
+add them, type something along the lines of the following
+(C<Catalyst::Model::DBIC::Schema> is used here as a representative
+example):
 
     # perl -MCPAN -e shell
     
@@ -86,7 +117,10 @@ B<NOTE:> Although all of the above methods can be used to install a base Catalys
 
 =head2 OTHER ITEMS
 
-Although Catalyst is a very flexible platform that can be used for wide variety of applications, the bulk of Catalyst developers use it to build web applications that set on top of a relational database.  Consequently, you will very likely need:
+Although Catalyst is a very flexible platform that can be used for wide
+variety of applications, the bulk of Catalyst developers use it to build
+web applications that set on top of a relational database.
+Consequently, you will very likely need:
 
 =over 4
 
@@ -94,19 +128,25 @@ Although Catalyst is a very flexible platform that can be used for wide variety
 
 A Web Server
 
-Although Apache is obviously an extremely popular choice, lighttpd has a growing following.  Catalyst applications can also be run under IIS. 
+Although Apache is obviously an extremely popular choice, lighttpd has a
+growing following.  Catalyst applications can also be run under IIS.
 
 =item * 
 
 A Database
 
-Although other databases with support for Perl are certainly possible, most Catalyst applications tend to use one of the following:
+Although other databases with support for Perl are certainly possible,
+most Catalyst applications tend to use one of the following:
 
 =item * 
 
 SQLite
 
-SQLite is a popular choice for development and testing because it does note require that a database daemon be running or configured.  It operates on C<.db> files that are generally located in the directory of your Catalyst application project.  More information is available at L<www.sqlite.org>.
+SQLite is a popular choice for development and testing because it does
+note require that a database daemon be running or configured.  It
+operates on C<.db> files that are generally located in the directory of
+your Catalyst application project.  More information is available at
+L<www.sqlite.org>.
 
 =item * 
 
@@ -118,13 +158,20 @@ MySQL is an extremely popular database available at L<www.mysql.com>.
 
 PostgreSQL
 
-PostgreSQL is a well-respected database available at L<http://www.postgresql.org/>.
+PostgreSQL is a well-respected database available at
+L<http://www.postgresql.org/>.
 
 =back
 
-This tutorial will primarily focus on SQLite because of its simplicity; however, modifications in the script required to support MySQL and PostgreSQL will be presented in Appendix X.
+This tutorial will primarily focus on SQLite because of its simplicity;
+however, modifications in the script required to support MySQL and
+PostgreSQL will be presented in the Appendix.
 
-B<Note:> One of the advantages of the MVC design patterns is that applications become much more database independent.  As such, you will notice that only the C<.sql> files used to initialize the database change between database systems... the Catalyst code all remains the same.
+B<Note:> One of the advantages of the MVC design patterns is that
+applications become much more database independent.  As such, you will
+notice that only the C<.sql> files used to initialize the database
+change between database systems... the Catalyst code all remains the
+same.
 
 =back
 
index 1b12864..2b90186 100644 (file)
@@ -1,26 +1,31 @@
 =head1 NAME
 
-Catalyst::Manual::Installation::CentOS4 – Catalyst Installation on CentOS 4
+Catalyst::Manual::Installation::CentOS4 - Catalyst Installation on CentOS 4
 
 
 
 =head1 DESCRIPTION
 
-This document provides directions on how to install CentOS 4 (a rebuild of RedHat Enterprise 4) and then install Catalyst.
+This document provides directions on how to install CentOS 4 (a rebuild
+of RedHat Enterprise 4) and then install Catalyst.
 
-If you already have a functioning install of CentOS, RHEL, or a comparable Linux OS, you should be able to skip this first section and go straight to the C<INSTALL CATALYST> section.
+If you already have a functioning install of CentOS, RHEL, or a
+comparable Linux OS, you should be able to skip this first section and
+go straight to the C<INSTALL CATALYST> section.
 
 
 =head1 INSTALL CENTOS
 
-These directions are written for CentOS 4.3 on an i386 machine; however, you can substitute other versions as they become available.
+These directions are written for CentOS 4.3 on an i386 machine; however,
+you can substitute other versions as they become available.
 
 
 =over 4
 
 =item * 
 
-Go to L<http://isoredirect.centos.org/centos/4/isos/i386/> and click the nearest mirror.
+Go to L<http://isoredirect.centos.org/centos/4/isos/i386/> and click the
+nearest mirror.
 
 =item * 
 
@@ -40,11 +45,13 @@ Hit C<Enter> at the C<boot:> prompt.
 
 =item * 
 
-CD media test: you can either select C<OK> or C<Skip> depending on whether or not you trust your burn.
+CD media test: you can either select C<OK> or C<Skip> depending on
+whether or not you trust your burn.
 
 =item * 
 
-The installation GUI should start.  Click next at the "Welcome to CentOS-4" screen.
+The installation GUI should start.  Click next at the "Welcome to
+CentOS-4" screen.
 
 =item * 
 
@@ -60,11 +67,14 @@ Select C<Custom> for the installation type and click C<Next>.
 
 =item * 
 
-Leave C<Automatically partition> selected on the C<Disk Partitioning Setup> and click C<Next>.
+Leave C<Automatically partition> selected on the C<Disk Partitioning
+Setup> and click C<Next>.
 
 =item * 
 
-Uncheck C<Review (and modify if needed) the partitions created>, but leave the rest of the default settings on the C<Automatic Partitioning> screen.  Then click C<Next>.
+Uncheck C<Review (and modify if needed) the partitions created>, but
+leave the rest of the default settings on the C<Automatic Partitioning>
+screen.  Then click C<Next>.
 
 =item * 
 
@@ -80,7 +90,8 @@ Update the C<Network Configuration> screen as necessary and click C<Next>.
 
 =item * 
 
-Check C<Remote Login (SSH)> and click C<Next> on the C<Firewall Configuration> screen.
+Check C<Remote Login (SSH)> and click C<Next> on the C<Firewall
+Configuration> screen.
 
 =item * 
 
@@ -96,7 +107,8 @@ Enter a root password and click C<Next>.
 
 =item * 
 
-Scroll to the bottom of the C<Package Group Selection> screen and check C<Minimal> (the last option).  Click C<Next>.
+Scroll to the bottom of the C<Package Group Selection> screen and check
+C<Minimal> (the last option).  Click C<Next>.
 
 =item * 
 
@@ -104,7 +116,8 @@ Click C<Next> at the C<About to Install> screen.
 
 =item * 
 
-The installation will prepare the hard drive and then install the required rpm packages.
+The installation will prepare the hard drive and then install the
+required rpm packages.
 
 =item * 
 
@@ -112,17 +125,21 @@ Once the installation completes, remove the CD and click C<Reboot>.
 
 =item * 
 
-Type C<vi /etc/sysconfig/iptables> and add the following line as the third to last line of the file (I<above> the C<-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited> line):
+Type C<vi /etc/sysconfig/iptables> and add the following line as the
+third to last line of the file (I<above> the C<-A RH-Firewall-1-INPUT -j
+REJECT --reject-with icmp-host-prohibited> line):
 
     -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 3000 -j ACCEPT
 
-This will allow Catalyst to make use of port 3000 (the default for the development server).
+This will allow Catalyst to make use of port 3000 (the default for the
+development server).
 
-Type C<service iptables restart> to restart the iptables firewall using the updated configuration.
+Type C<service iptables restart> to restart the iptables firewall using
+the updated configuration.
 
 =item * 
 
-Type C<yum –y update> to retrieve the latest patches.
+Type C<yum -y update> to retrieve the latest patches.
 
 =back
 
@@ -133,7 +150,8 @@ Type C<yum 
 
 =item * 
 
-Type <yum -y install gcc expat-devel sqlite3> to install several packages used by Catalyst.
+Type <yum -y install gcc expat-devel sqlite3> to install several
+packages used by Catalyst.
 
 =item * 
 
@@ -158,11 +176,14 @@ Type the following:
 
 =item * 
 
-Type C<wget http://www.shadowcatsystems.co.uk/static/cat-install> to retrieve a copy of the C<cat-install> script.
+Type C<wget http://www.shadowcatsystems.co.uk/static/cat-install> to
+retrieve a copy of the C<cat-install> script.
 
 =item * 
 
-Type C<vi cat-install> to open the installer script, then insert the following lines at the bottom of the file (after the C<install('Catalyst');> line):
+Type C<vi cat-install> to open the installer script, then insert the
+following lines at the bottom of the file (after the
+C<install('Catalyst');> line):
 
     install('Class::DBI');
     install('DBIx::Class');
@@ -187,8 +208,8 @@ Type C<perl cat-install>.  It will take a while to complete.
 
 =back
 
-You should now have a functioning Catalyst installation with the modules and plugins required to run the Catalyst tutorial.
-
+You should now have a functioning Catalyst installation with the modules
+and plugins required to run the Catalyst tutorial.
 
 
 =head1 AUTHOR
@@ -197,7 +218,8 @@ Kennedy Clark, C<hkclark@gmail.com>
 
 Please report any errors, issues or suggestions to the author.
 
-Copyright 2006, Kennedy Clark, under Creative Commons License (L<http://creativecommons.org/licenses/by-nc-sa/2.5/>).
+Copyright 2006, Kennedy Clark, under Creative Commons License
+(L<http://creativecommons.org/licenses/by-nc-sa/2.5/>).
 
 Version: .01
 
index d69d300..91d11ac 100644 (file)
@@ -6,7 +6,10 @@ Catalyst::Manual::Tutorial - Catalyst Tutorial: Overview
 
 =head1 DESCRIPTION
 
-The Catalyst framework is a flexible and comprehensive environment for quickly building high-functionality web applications.  This tutorial is design to provide a rapid introduction to its basics and most commonly used features while focusing on real-world best practices.
+The Catalyst framework is a flexible and comprehensive environment for
+quickly building high-functionality web applications.  This tutorial is
+design to provide a rapid introduction to its basics and most commonly
+used features while focusing on real-world best practices.
 
 The tutorial is broken down into the following sections:
 
@@ -14,48 +17,51 @@ The tutorial is broken down into the following sections:
 
 =item *
 
-L<Introduction|Catalyst::Manual::Tutorial01_Intro>
+L<Introduction|Catalyst::Manual::Tutorial_Intro>
 
 =item * 
 
-L<Catalyst Basics|Catalyst::Manual::Tutorial02_CatalystBasics>
+L<Catalyst Basics|Catalyst::Manual::Tutorial_CatalystBasics>
 
 =item * 
 
-L<CRUD|Catalyst::Manual::Tutorial03_BasicCRUD>
+L<CRUD|Catalyst::Manual::Tutorial_BasicCRUD>
 
 =item * 
 
-L<Authentication|Catalyst::Manual::Tutorial04_Authentication>
+L<Authentication|Catalyst::Manual::Tutorial_Authentication>
 
 =item * 
 
-L<Authorization|Catalyst::Manual::Tutorial05_Authorization>
+L<Authorization|Catalyst::Manual::Tutorial_Authorization>
 
 =item * 
 
-L<Debugging|Catalyst::Manual::Tutorial06_Debugging>
+L<Debugging|Catalyst::Manual::Tutorial_Debugging>
 
 =item * 
 
-L<Testing|Catalyst::Manual::Tutorial07_Testing>
+L<Testing|Catalyst::Manual::Tutorial_Testing>
 
 =item * 
 
-L<CRUD|Catalyst::Manual::Tutorial08_AdvancedCRUD>
+L<CRUD|Catalyst::Manual::Tutorial_AdvancedCRUD>
 
 =item * 
 
-L<Appendicies|Catalyst::Manual::Tutorial09_Appendicies>
+L<Appendicies|Catalyst::Manual::Tutorial_Appendicies>
 
 =back
 
 
-Full source code is available for each section via the main Catalyst Subversion repository at L<http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/>.  See the end of each section for the specifics on retrieving code for that section.
-
-A tarball of the final application is available at C<to_be_compled_in_final_version>.
-
+Full source code is available for each section via the main Catalyst
+Subversion repository at
+L<http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/>.  See the
+end of each section for the specifics on retrieving code for that
+section.
 
+A tarball of the final application is available at
+C<to_be_compled_in_final_version>.
 
 =head1 Detailed Table Of Contents
 
@@ -82,7 +88,6 @@ WHERE TO GET WORKING CODE
 =back
 
 
-
 =head2 Part 2: Catalyst Application Development Basics
 
 =over 4
@@ -150,7 +155,6 @@ RUN THE APPLICATION
 =back
 
 
-
 =head2 Part 3: Basic CRUD
 
 =over 4
@@ -222,7 +226,6 @@ Try the Delete Feature
 =back
 
 
-
 =head2 Part 4: Authentication
 
 =over 4
@@ -239,7 +242,7 @@ Add Users and Roles to the Database
 
 =item *
 
-Add User and Role Information to Dbic Schema
+Add User and Role Information to DBIC Schema
 
 =item *
 
@@ -306,7 +309,6 @@ Try Out the Hashed Passwords
 =back
 
 
-
 =head2 Part 5: Authorization
 
 =over 4
@@ -319,7 +321,7 @@ BASIC AUTHORIZATION
 
 =item *
 
-Update Plugins to Include Support Authorization
+Update Plugins to Include Support  for Authorization
 
 =item *
 
@@ -377,7 +379,6 @@ RUNNING CATALYST UNDER THE PERL DEBUGGER
 =back
 
 
-
 =head2 Part 7: Testing
 
 =over 4
@@ -401,7 +402,6 @@ SUPPORTING BOTH PRODUCTION AND TEST DATABASES
 =back
 
 
-
 =head2 Part 8: Advanced CRUD
 
 =over 4
@@ -481,7 +481,6 @@ Use populate_from_widget in hw_create_do
 =back
 
 
-
 =head2 Part 9: Appendices
 
 =over 4
index ba003ae..22f562b 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-Catalyst::Manual::Tutorial::AdvancedCRUD - Catalyst Tutorial – Part 8: Advanced CRUD
+Catalyst::Manual::Tutorial::AdvancedCRUD - Catalyst Tutorial - Part 8: Advanced CRUD
 
 
 
@@ -8,7 +8,7 @@ Catalyst::Manual::Tutorial::AdvancedCRUD - Catalyst Tutorial 
 
 This is B<Part 8 of 9> for the Catalyst tutorial.
 
-L<Totorial Overview|Catalyst::Manual::Tutorial>
+L<Tutorial Overview|Catalyst::Manual::Tutorial>
 
 =over 4
 
@@ -22,7 +22,7 @@ L<Catalyst Basics|Catalyst::Manual::Tutorial::CatalystBasics>
 
 =item 3
 
-L<Basic CRUD|Catalyst::Manual::Tutorial03_BasicCRUD>
+L<Basic CRUD|Catalyst::Manual::Tutorial_BasicCRUD>
 
 =item 4
 
@@ -54,15 +54,38 @@ L<Appendicies|Catalyst::Manual::Tutorial::Appendicies>
 
 =head1 DESCRIPTION
 
-This part of the tutorial explores more advanced functionality for Create, Read, Update, and Delete (CRUD) than we saw in Part 3.  In particular, it looks at a number of techniques that can be useful for the Update portion of CRUD, such as automated form generation, validation of user-entered data, and automated transfer of data between forms and model objects.
-
-In keeping with the Catalyst (and Perl) spirit of flexibility, there are many different ways approach advanced CRUD operations in a Catalyst environment.  One alternative is to use L<Catalyst::Helper::Controller::Scaffold|Catalyst::Helper::Controller::Scaffold> to instantly construct a set of Controller methods and templates for basic CRUD operations.  Although a popular subject in Quicktime movies that serve as promotional material for various frameworks, more real-world applications require more control.  Other options include L<Data::FormValidator|Data::FormValidator> and L<HTML::FillInForm|HTML::FillInForm>.
-
-Here, we will make use of the L<HTML::Widget|HTML::Widget> to not only ease form creation, but to also provide validation of the submitted data.  The approached used by the part of the tutorial is to slowly incorporate additional L<HTML::Widget|HTML::Widget> functionality in a step-wise fashion (we start with fairly simple form creation and then move on to more complex and "magical" features such as validation and auto-population/auto-saving).
-
-B<Note:> Part 8 of the tutorial is optional.  Users who do not which to use L<HTML::Widget|HTML::Widget> may skip this section.
-
-B<TIP>: Note that all of the code for this part of the tutorial can be pulled from the Catalyst Subversion repository in one step with the following command:
+This part of the tutorial explores more advanced functionality for
+Create, Read, Update, and Delete (CRUD) than we saw in Part 3.  In
+particular, it looks at a number of techniques that can be useful for
+the Update portion of CRUD, such as automated form generation,
+validation of user-entered data, and automated transfer of data between
+forms and model objects.
+
+In keeping with the Catalyst (and Perl) spirit of flexibility, there are
+many different ways approach advanced CRUD operations in a Catalyst
+environment.  One alternative is to use
+L<Catalyst::Helper::Controller::Scaffold|Catalyst::Helper::Controller::Scaffold>
+to instantly construct a set of Controller methods and templates for
+basic CRUD operations.  Although a popular subject in Quicktime movies
+that serve as promotional material for various frameworks, more
+real-world applications require more control.  Other options include
+L<Data::FormValidator|Data::FormValidator> and
+L<HTML::FillInForm|HTML::FillInForm>.
+
+Here, we will make use of the L<HTML::Widget|HTML::Widget> to not only
+ease form creation, but to also provide validation of the submitted
+data.  The approached used by the part of the tutorial is to slowly
+incorporate additional L<HTML::Widget|HTML::Widget> functionality in a
+step-wise fashion (we start with fairly simple form creation and then
+move on to more complex and "magical" features such as validation and
+auto-population/auto-saving).
+
+B<Note:> Part 8 of the tutorial is optional.  Users who do not which to
+use L<HTML::Widget|HTML::Widget> may skip this section.
+
+B<TIP>: Note that all of the code for this part of the tutorial can be
+pulled from the Catalyst Subversion repository in one step with the
+following command:
 
     svn checkout http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/Tutorial@###
     IMPORTANT: Does not work yet.  Will be completed for final version.
@@ -71,19 +94,22 @@ B<TIP>: Note that all of the code for this part of the tutorial can be pulled fr
 
 =head1 C<HTML::WIDGET> FORM CREATION
 
-This section looks at how L<HTML::Widget|HTML::Widget> can be used to add additional functionality to the manually created form from Part 3.
+This section looks at how L<HTML::Widget|HTML::Widget> can be used to
+add additional functionality to the manually created form from Part 3.
 
 
 =head2 Add the C<HTML::Widget> Plugin
 
-Open C<lib/MyApp.pm> in your editor and add the following to the list of plugins (be sure to leave the existing plugins enabled:
+Open C<lib/MyApp.pm> in your editor and add the following to the list of
+plugins (be sure to leave the existing plugins enabled:
 
     HTML::Widget
 
 
 =head2 Add a Form Creation Helper Method
 
-Open C<lib/MyApp/Controller/Books.pm> in your editor and add the following method:
+Open C<lib/MyApp/Controller/Books.pm> in your editor and add the
+following method:
 
     =head2 make_book_widget
     
@@ -113,12 +139,19 @@ Open C<lib/MyApp/Controller/Books.pm> in your editor and add the following metho
         return $w;
     }
 
-This method provides a central location (so it can be called by multiple actions, such as create and edit) that builds an HTML::Wiget-based form with the appropriate fields.  The "Get Authors" code uses DBIC to retrieve a list of model objects and then uses C<map> to quickly create a hash where the hash keys are the database primary keys from the authors table and the associated values are the last names of the authors.
+This method provides a central location (so it can be called by multiple
+actions, such as create and edit) that builds an HTML::Wiget-based form
+with the appropriate fields.  The "Get Authors" code uses DBIC to
+retrieve a list of model objects and then uses C<map> to quickly create
+a hash where the hash keys are the database primary keys from the
+authors table and the associated values are the last names of the
+authors.
 
 
 =head2 Add Actions to Display and Save the Form
 
-Open C<lib/MyApp/Controller/Books.pm> in your editor and add the following methods:
+Open C<lib/MyApp/Controller/Books.pm> in your editor and add the
+following methods:
 
     =head2 hw_create
     
@@ -174,12 +207,18 @@ Open C<lib/MyApp/Controller/Books.pm> in your editor and add the following metho
     
     }
 
-Note how we use C<make_book_widget> to build the core parts of the form in one location, but we set the action (the URL the form is sent to when the user clicks the 'Submit' button) separately in C<hw_create>.  Doing so allows us to have the same form submit the data to different actions (e.g., C<hw_create_do> for a create operation but C<hw_update_do> to update an existing book object).
+Note how we use C<make_book_widget> to build the core parts of the form
+in one location, but we set the action (the URL the form is sent to when
+the user clicks the 'Submit' button) separately in C<hw_create>.  Doing
+so allows us to have the same form submit the data to different actions
+(e.g., C<hw_create_do> for a create operation but C<hw_update_do> to
+update an existing book object).
 
 
 =head2 Update the CSS
 
-Edit C<root/src/ttsite.css> and add the following lines to the bottom of the file:
+Edit C<root/src/ttsite.css> and add the following lines to the bottom of
+the file:
 
     label {
         display: block;
@@ -202,7 +241,11 @@ Edit C<root/src/ttsite.css> and add the following lines to the bottom of the fil
         color: [% site.col.error %];
     }
 
-These changes will display form elements vertically and also show error messages in red.  Note that we are pulling the color scheme settings from the C<root/lib/config/col> file that was created by the TTSite helper.  This allows us to change the color used by various error styles in the CCS from a single location.
+These changes will display form elements vertically and also show error
+messages in red.  Note that we are pulling the color scheme settings
+from the C<root/lib/config/col> file that was created by the TTSite
+helper.  This allows us to change the color used by various error styles
+in the CCS from a single location.
 
 
 =head2 Create a Template Page To Display The Form
@@ -217,7 +260,8 @@ C<root/src/books/hw_form.tt2>
 
 =head2 Add Links for Create and Update via C<HTML::Widget>
 
-Open C<root/src/books/list.tt2> in your editor and add the following to the bottom of the existing file:
+Open C<root/src/books/list.tt2> in your editor and add the following to
+the bottom of the existing file:
 
     <p>
       HTML::Widget:
@@ -228,25 +272,50 @@ Open C<root/src/books/list.tt2> in your editor and add the following to the bott
 
 =head2 Test The <HTML::Widget> Create Form
 
-Press C<Ctrl-C> to kill the previous server instance (if it's still running) and restart it:
+Press C<Ctrl-C> to kill the previous server instance (if it's still
+running) and restart it:
 
     $ script/myapp_server.pl
 
-Login as C<test01>.  Once at the Book List page, click the HTML::Widget "Create" link to display for form produced by C<make_book_widget>.  Fill out the form with the following values: Title = "Internetworking with TCP/IP Vol. II", Rating = "4", and Author = "Comer".  Click Submit, and you will be returned to the Create/Update Book page with a "Book created" status message displayed.  Click "Return to book list" to view the newly created book on the main list.
+Login as C<test01>.  Once at the Book List page, click the HTML::Widget
+"Create" link to display for form produced by C<make_book_widget>.  Fill
+out the form with the following values: Title = "Internetworking with
+TCP/IP Vol. II", Rating = "4", and Author = "Comer".  Click Submit, and
+you will be returned to the Create/Update Book page with a "Book
+created" status message displayed.  Click "Return to book list" to view
+the newly created book on the main list.
 
-Also note that this implementation allows you to can create books with bogus information.  Although we have constrained the authors with the drop-down list, there are no restrictions on items such as the length of the title (for example, you can create a one-letter title) and value for the rating (you can use any number you want, and even non-numeric values with SQLite).  The next section seeks to address this concern.
+Also note that this implementation allows you to can create books with
+bogus information.  Although we have constrained the authors with the
+drop-down list, there are no restrictions on items such as the length of
+the title (for example, you can create a one-letter title) and value for
+the rating (you can use any number you want, and even non-numeric values
+with SQLite).  The next section seeks to address this concern.
 
-B<Note:> Depending on the database you are using and how you established the columns in your tables, the database could obviously provide various levels of "type enforcement" on your data.  The key point being made in the previous paragraph is that the I<web application> itself is not performing any validation.
+B<Note:> Depending on the database you are using and how you established
+the columns in your tables, the database could obviously provide various
+levels of "type enforcement" on your data.  The key point being made in
+the previous paragraph is that the I<web application> itself is not
+performing any validation.
 
 
 =head1 C<HTML::WIDGET> VALIDATION AND FILTERING
 
-Although the use of L<HTML::Widget|HTML::Widget> in the previous section did provide an automated mechanism to build the form, the real power of this module stems from functionality that can automatically validate and filter the user input.  Validation uses constraints to be sure that users input appropriate data (for example, that the email field of a form contains a valid email address).  Filtering can be used to remove extraneous whitespace from fields or to escape meta-characters in user input.
+Although the use of L<HTML::Widget|HTML::Widget> in the previous section
+did provide an automated mechanism to build the form, the real power of
+this module stems from functionality that can automatically validate and
+filter the user input.  Validation uses constraints to be sure that
+users input appropriate data (for example, that the email field of a
+form contains a valid email address).  Filtering can be used to remove
+extraneous whitespace from fields or to escape meta-characters in user
+input.
 
 
 =head2 Add Constraints and Filters to the Widget Creation Method
 
-Open C<lib/MyApp/Controller/Books.pm> in your editor and update the C<make_book_widget> method to match the following (new sections have been marked with a C<*** NEW:> comment):
+Open C<lib/MyApp/Controller/Books.pm> in your editor and update the
+C<make_book_widget> method to match the following (new sections have
+been marked with a C<*** NEW:> comment):
 
     sub make_book_widget {
         my ($self, $c) = @_;
@@ -293,7 +362,9 @@ The main changes are:
 
 =item *
 
-The C<Select> element for C<authors> is changed from a single-select drop-down to a multi-select list by adding calls to C<multiple> (set to C<true>) and C<size> (set to the number of rows to display).
+The C<Select> element for C<authors> is changed from a single-select
+drop-down to a multi-select list by adding calls to C<multiple> (set to
+C<true>) and C<size> (set to the number of rows to display).
 
 =item *
 
@@ -308,7 +379,9 @@ Two filters are run on every field to remove and escape unwanted input.
 
 =head2 Rebuild the Form Submission Method to Include Validation
 
-Edit C<lib/MyApp/Controller/Books.pm> and change C<hw_create_do> to match the following code (enough of the code is different that you probably want to cut and paste this over code the existing method):
+Edit C<lib/MyApp/Controller/Books.pm> and change C<hw_create_do> to
+match the following code (enough of the code is different that you
+probably want to cut and paste this over code the existing method):
 
     sub hw_create_do : Local {
         my ($self, $c) = @_;
@@ -365,15 +438,28 @@ The key changes to C<hw_create_do> are:
 
 =item *
 
-C<hw_create_do> no longer does a C<detach> to C<hw_create> to redisplay the form.  Now that C<hw_create_do> has to process the form in order to perform the validation, we go ahead and build a complete set of form presentation logic into C<hw_create_do> (for example, C<hw_create_do> now has a C<$c-E<gt>stash-E<gt>{template}> line).  Note that if we process the form in C<hw_create_do> I<and> forward/detach back to <hw_create>, we would end up with C<make_book_widget> being called twice, resulting in a duplicate set of elements being added to the form.
+C<hw_create_do> no longer does a C<detach> to C<hw_create> to redisplay
+the form.  Now that C<hw_create_do> has to process the form in order to
+perform the validation, we go ahead and build a complete set of form
+presentation logic into C<hw_create_do> (for example, C<hw_create_do>
+now has a C<$c-E<gt>stash-E<gt>{template}> line).  Note that if we
+process the form in C<hw_create_do> I<and> forward/detach back to
+<hw_create>, we would end up with C<make_book_widget> being called
+twice, resulting in a duplicate set of elements being added to the form.
 
 =item *
 
-C<$w-E<gt>process($c-E<gt>req)> is called to run the validation logic.  Not only does this set the C<has_errors> flag if validation errors are encountered, it returns a string containing any field-specific warning messages.
+C<$w-E<gt>process($c-E<gt>req)> is called to run the validation logic.
+Not only does this set the C<has_errors> flag if validation errors are
+encountered, it returns a string containing any field-specific warning
+messages.
 
 =item *
 
-An C<if> statement checks if any validation errors were encountered.  If so, C<$c-E<gt>stash-E<gt>{error_msg}> is set and the input form is redisplayed.  If no errors were found, the object is created in a manner similar to the prior version of the C<hw_create_do> method.
+An C<if> statement checks if any validation errors were encountered.  If
+so, C<$c-E<gt>stash-E<gt>{error_msg}> is set and the input form is
+redisplayed.  If no errors were found, the object is created in a manner
+similar to the prior version of the C<hw_create_do> method.
 
 =back
 
@@ -384,12 +470,19 @@ Press C<Ctrl-C> to kill the previous server instance (if it's still running) and
 
     $ script/myapp_server.pl
 
-Now try adding a book with various errors: title less than 5 characters, non-numeric rating, a rating of 0 or 6, etc.  Also try selecting one, two, and zero authors.  When you click Submit, the HTML::Widget C<constraint> items will validate the logic and insert feedback as appropriate.
+Now try adding a book with various errors: title less than 5 characters,
+non-numeric rating, a rating of 0 or 6, etc.  Also try selecting one,
+two, and zero authors.  When you click Submit, the HTML::Widget
+C<constraint> items will validate the logic and insert feedback as
+appropriate.
 
 
 =head1 Enable C<DBIx::Class::HTMLWidget> Support
 
-In this section we will take advantage of some of the "auto-population" features of C<DBIx::Class::HTMLWidget>.  Enabling C<DBIx::Class::HTMLWidget> provides two additional methods to your DBIC model classes: 
+In this section we will take advantage of some of the "auto-population"
+features of C<DBIx::Class::HTMLWidget>.  Enabling
+C<DBIx::Class::HTMLWidget> provides two additional methods to your DBIC
+model classes:
 
 =over 4
 
@@ -403,23 +496,30 @@ Takes data from the database and transfers it to your form widget.
 
 populate_from_widget()
 
-Takes data from a form widget and uses it to update the corresponding records in the database.
+Takes data from a form widget and uses it to update the corresponding
+records in the database.
 
 =back
 
-In other words, the two methods are a mirror image of each other: one reads from the database while the other writes to the database.
+In other words, the two methods are a mirror image of each other: one
+reads from the database while the other writes to the database.
 
 
 =head2 Add C<DBIx::Class::HTMLWidget> to DBIC Model
 
-In order to use L<DBIx::Class::HTMLWidget|DBIx::Class::HTMLWidget>, we need to add C<HTMLWidget> to the C<load_components> line of DBIC result source files that need to use the C<fill_widget> and C<populate_from_widget> methods.  In this case, open C<lib/MyAppDB/Book.pm> and update the C<load_components> line to match:
+In order to use L<DBIx::Class::HTMLWidget|DBIx::Class::HTMLWidget>, we
+need to add C<HTMLWidget> to the C<load_components> line of DBIC result
+source files that need to use the C<fill_widget> and
+C<populate_from_widget> methods.  In this case, open
+C<lib/MyAppDB/Book.pm> and update the C<load_components> line to match:
 
        __PACKAGE__->load_components(qw/PK::Auto Core HTMLWidget/);
 
 
 =head2 Use C<populate_from_widget> in C<hw_create_do>
 
-Edit C<lib/MyApp/Controller/Books.pm> and update C<hw_create_do> to match the following code:
+Edit C<lib/MyApp/Controller/Books.pm> and update C<hw_create_do> to
+match the following code:
 
     =head2 hw_create_do
     
@@ -468,7 +568,13 @@ Edit C<lib/MyApp/Controller/Books.pm> and update C<hw_create_do> to match the fo
         $c->stash->{template} = 'books/hw_form.tt2';
     }
 
-In this version of C<hw_create_do> we removed the logic that manually pulled the form variables and used them to call C<$c-E<gt>model('MyAppDB::Book')-E<gt>create> and replaced it with a single call to C<$book-E<gt>populate_from_widget>.  Note that we still have to call C<$book-E<gt>add_to_book_authors> once per author because C<populate_from_widget> does not currently handle the relationships between tables.
+In this version of C<hw_create_do> we removed the logic that manually
+pulled the form variables and used them to call
+C<$c-E<gt>model('MyAppDB::Book')-E<gt>create> and replaced it with a
+single call to C<$book-E<gt>populate_from_widget>.  Note that we still
+have to call C<$book-E<gt>add_to_book_authors> once per author because
+C<populate_from_widget> does not currently handle the relationships
+between tables.
 
 
 
index 7bd0f4f..c408e82 100644 (file)
@@ -1,14 +1,13 @@
 =head1 NAME
 
-Catalyst::Manual::Tutorial::Appendices - Catalyst Tutorial – Part 9: Appendices
-
+Catalyst::Manual::Tutorial::Appendices - Catalyst Tutorial - Part 9: Appendices
 
 
 =head1 OVERVIEW
 
-This is B<Part 9 of 9> for the Catalyst tutorial.
+This is B<Part 9 of 9> of the Catalyst tutorial.
 
-L<Totorial Overview|Catalyst::Manual::Tutorial>
+L<Tutorial Overview|Catalyst::Manual::Tutorial>
 
 =over 4
 
@@ -22,7 +21,7 @@ L<Catalyst Basics|Catalyst::Manual::Tutorial::CatalystBasics>
 
 =item 3
 
-L<Basic CRUD|Catalyst::Manual::Tutorial03_BasicCRUD>
+L<Basic CRUD|Catalyst::Manual::Tutorial_BasicCRUD>
 
 =item 4
 
@@ -54,18 +53,24 @@ B<Appendicies>
 
 =head1 DESCRIPTION
 
-This part of the tutorial provides supporting information relevant to the Catalyst tutorial.
+This part of the tutorial provides supporting information relevant to
+the Catalyst tutorial.
 
 
 
 =head1 APPENDIX 1: CUT AND PASTE FOR POD-BASED EXAMPLES
 
-You may notice that Pod indents example code with four spaces.  This section provides some quick advice to "un-indent" this text in common editors.
+You may notice that Pod indents example code with four spaces.  This
+section provides some quick advice to "un-indent" this text in common
+editors.
 
 
 =head2 "Un-indenting" with Vi/Vim
 
-When cutting and pasting multi-line text from Pod-based documents, the following vi/vim regexs can be helpful to "un-indent" the inserted text (do NOT type the quotes, they are only included to show spaces in the regex patterns).  I<Note that all 3 of the regexs end in 4 spaces>:
+When cutting and pasting multi-line text from Pod-based documents, the
+following vi/vim regexs can be helpful to "un-indent" the inserted text
+(do NOT type the quotes, they are only included to show spaces in the
+regex patterns).  I<Note that all 3 of the regexs end in 4 spaces>:
 
 =over 4
 
@@ -73,41 +78,55 @@ When cutting and pasting multi-line text from Pod-based documents, the following
 
 ":0,$s/^    "
 
-Removes four leading spaces from the entire file (from the first line, C<0>, to the last line, C<$>).
+Removes four leading spaces from the entire file (from the first line,
+C<0>, to the last line, C<$>).
 
 =item * 
 
 ":.,$s/^    "
 
-Removes the first four spaces from the line the cursor is on at the time the regex command is executed (".") to the last line of the file.
+Removes the first four spaces from the line the cursor is on at the time
+the regex command is executed (".") to the last line of the file.
 
 =item * 
 
 ":.,44s/^    "
 
-Removes four leading space from the current line through line 44 (obviously adjust the C<44> to the appropriate value in your example).
+Removes four leading space from the current line through line 44
+(obviously adjust the C<44> to the appropriate value in your example).
 
 =back
 
 
 =head2 "Un-indenting" with Emacs
 
-B<todo>
+B<TODO>
 
 
 
 =head1 APPENDIX 2: USING MYSQL AND POSTGRESQL
 
-The main database used in this tutorial is the very simple yet deceptively powerful SQLite.  This section provides information that can be used to "convert" the tutorial to use MySQL and PostgreSQL.  However, note that part of the beauty of the MVC architecture is that very little database-specific code is spread throughout the system (at least when MVC is "done right").  Consequently, converting from one database to another is relatively painless with most Catalyst applications.  In general, you just need to adapt the schema definition C<.sql> file you use to initialize your database and adjust a few configuration parameters.
+The main database used in this tutorial is the very simple yet powerful
+SQLite.  This section provides information that can be used to "convert"
+the tutorial to use MySQL and PostgreSQL.  However, note that part of
+the beauty of the MVC architecture is that very little database-specific
+code is spread throughout the system (at least when MVC is "done
+right").  Consequently, converting from one database to another is
+relatively painless with most Catalyst applications.  In general, you
+just need to adapt the schema definition C<.sql> file you use to
+initialize your database and adjust a few configuration parameters.
 
-Also note that the purpose of the data definition statements for this section are not designed to take maximum advantage of the various features in each database for issues such as referential integrity and field types/constraints.
+Also note that the purpose of the data definition statements for this
+section are not designed to take maximum advantage of the various
+features in each database for issues such as referential integrity and
+field types/constraints.
 
 
 =head2 MySQL
 
-B<todo>
+B<TODO>
 
 =head2 PostgreSQL
 
-B<todo>
+B<TODO>
 
index e1ac250..438bdbd 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-Catalyst::Manual::Tutorial::Authentication - Catalyst Tutorial – Part 4: Authentication
+Catalyst::Manual::Tutorial::Authentication - Catalyst Tutorial - Part 4: Authentication
 
 
 
@@ -8,7 +8,7 @@ Catalyst::Manual::Tutorial::Authentication - Catalyst Tutorial 
 
 This is B<Part 4 of 9> for the Catalyst tutorial.
 
-L<Totorial Overview|Catalyst::Manual::Tutorial>
+L<Tutorial Overview|Catalyst::Manual::Tutorial>
 
 =over 4
 
@@ -22,7 +22,7 @@ L<Catalyst Basics|Catalyst::Manual::Tutorial::CatalystBasics>
 
 =item 3
 
-L<Basic CRUD|Catalyst::Manual::Tutorial03_BasicCRUD>
+L<Basic CRUD|Catalyst::Manual::Tutorial_BasicCRUD>
 
 =item 4
 
@@ -54,11 +54,15 @@ L<Appendicies|Catalyst::Manual::Tutorial::Appendicies>
 
 =head1 DESCRIPTION
 
-Now that we finally have a simple yet functional application, we can focus on providing authentication (with authorization coming in Part 5).
+Now that we finally have a simple yet functional application, we can
+focus on providing authentication (with authorization coming in Part 5).
 
-This part of the tutorial is divided into two main sections: 1) basic, cleartext authentication and 2) hash-based authentication.
+This part of the tutorial is divided into two main sections: 1) basic,
+cleartext authentication and 2) hash-based authentication.
 
-B<TIP>: Note that all of the code for this part of the tutorial can be pulled from the Catalyst Subversion repository in one step with the following command:
+B<TIP>: Note that all of the code for this part of the tutorial can be
+pulled from the Catalyst Subversion repository in one step with the
+following command:
 
     svn checkout http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/Tutorial@###
     IMPORTANT: Does not work yet.  Will be completed for final version.
@@ -72,7 +76,10 @@ This section explores how add authentication logic to a Catalyst application.
 
 =head2 Add Users and Roles to the Database
 
-First, we add both user and role information to the database (we add the role information here although it will not be used until the authorization section, Part 5).  Create a new SQL script file by opening C<myapp02.sql> in your editor and insert:
+First, we add both user and role information to the database (we add the
+role information here although it will not be used until the
+authorization section, Part 5).  Create a new SQL script file by opening
+C<myapp02.sql> in your editor and insert:
 
     --
     -- Add users and roles tables, along with a many-to-many join table
@@ -115,9 +122,12 @@ Then load this into the C<myapp.db> database with the following command:
 
 =head2 Add User and Role Information to Dbic Schema
 
-This step adds DBIC-based classes for the user-related database tables (the role information will not be used until the Part 5):
+This step adds DBIC-based classes for the user-related database tables
+(the role information will not be used until the Part 5):
 
-Edit C<lib/MyAppDB.pm> and update the contents to match (only the C<MyAppDB =E<gt> [qw/Book BookAuthor Author User UserRole Role/]> line has changed):
+Edit C<lib/MyAppDB.pm> and update the contents to match (only the
+C<MyAppDB =E<gt> [qw/Book BookAuthor Author User UserRole Role/]> line
+has changed):
 
     package MyAppDB;
     
@@ -344,12 +354,24 @@ Edit C<lib/MyApp.pm> and update it as follows (everything below C<DefaultEnd> is
             Session::State::Cookie
             /;
 
-The three C<Authentication> plugins work together to support Authentication while the C<Session> plugins are required to maintain state across multiple HTTP requests.  Note that there are several options for L<Session::Store|Catalyst::Plugin::Session::Store> (although L<Session::Store::FastMmap|Catalyst::Plugin::Session::Store::FastMmap> is generally a good choice if you are on Unix; try L<Cache::FileCache|Catalyst::Plugin::Cache::FileCache> if you are on Win32) -- consult L<Session::Store|Catalyst::Plugin::Session::Store> and its subclasses for additional information.
+The three C<Authentication> plugins work together to support
+Authentication while the C<Session> plugins are required to maintain
+state across multiple HTTP requests.  Note that there are several
+options for L<Session::Store|Catalyst::Plugin::Session::Store> (although
+L<Session::Store::FastMmap|Catalyst::Plugin::Session::Store::FastMmap>
+is generally a good choice if you are on Unix; try
+L<Cache::FileCache|Catalyst::Plugin::Cache::FileCache> if you are on
+Win32) -- consult L<Session::Store|Catalyst::Plugin::Session::Store> and
+its subclasses for additional information.
 
 
 =head2 Configure Authentication
 
-Although C<__PACKAGE__-E<gt>config(name =E<gt> 'value');> is still supported, newer Catalyst applications tend to place all configuration information in C<myapp.yml> and automatically load this information into C<MyApp-E<gt>config> using the L<ConfigLoader|Catalyst::Plugin::ConfigLoader> plugin.
+Although C<__PACKAGE__-E<gt>config(name =E<gt> 'value');> is still
+supported, newer Catalyst applications tend to place all configuration
+information in C<myapp.yml> and automatically load this information into
+C<MyApp-E<gt>config> using the
+L<ConfigLoader|Catalyst::Plugin::ConfigLoader> plugin.
 
 Edit the C<myapp.yml> YAML and update it to match:
 
@@ -374,7 +396,11 @@ Edit the C<myapp.yml> YAML and update it to match:
 
 Inline comments in the code above explain how each field is being used.
 
-B<TIP>: Although YAML uses a very simple and easy-to-ready format, it does require the use of a consistent level of indenting.  Be sure you line up everything on a given 'level' with the same number of indents.  Also, be sure not to use C<tab> characters (YAML does not support them because they are handled inconsistently across editors). 
+B<TIP>: Although YAML uses a very simple and easy-to-ready format, it
+does require the use of a consistent level of indenting.  Be sure you
+line up everything on a given 'level' with the same number of indents.
+Also, be sure not to use C<tab> characters (YAML does not support them
+because they are handled inconsistently across editors).
 
 
 =head2 Add Login and Logout Controllers
@@ -384,7 +410,10 @@ Use the Catalyst create script to create two stub controller files:
     $ script/myapp_create.pl controller Login
     $ script/myapp_create.pl controller Logout
 
-B<NOTE>: You could easily use a single controller here.  For example, you could have a C<User> controller with both C<login> and C<logout> actions.  Remember, Catalyst is designed to be very flexible, and leaves such matters up to you, the designer and programmer.
+B<NOTE>: You could easily use a single controller here.  For example,
+you could have a C<User> controller with both C<login> and C<logout>
+actions.  Remember, Catalyst is designed to be very flexible, and leaves
+such matters up to you, the designer and programmer.
 
 Then open C<lib/MyApp/Controller/Login.pm> and add:
 
@@ -418,7 +447,12 @@ Then open C<lib/MyApp/Controller/Login.pm> and add:
         $c->stash->{template} = 'login.tt2';
     }
 
-This controller fetches the C<username> and C<password> values from the login form and attempts to perform a login.  If successful, it redirects the user to the book list page.  If the login fails, the user will stay at the login page but receive an error message.  If the C<username> and C<password> values are not present in the form, the user will be taken to the empty login form.
+This controller fetches the C<username> and C<password> values from the
+login form and attempts to perform a login.  If successful, it redirects
+the user to the book list page.  If the login fails, the user will stay
+at the login page but receive an error message.  If the C<username> and
+C<password> values are not present in the form, the user will be taken
+to the empty login form.
 
 Next, create a corresponding method in C<lib/MyApp/Controller/Logout.pm>:
 
@@ -465,7 +499,12 @@ Create a login form by opening C<root/src/login.tt2> and inserting:
 
 =head2 Add Valid User Check
 
-We need something that provides enforcement for the authentication mechanism -- a I<global> mechanism that prevents users who have not passed authentication from reaching any pages except the login page.  This is generally done via an C<auto> action/method (prior to Catalyst v5.66, this sort of thing would go in C<MyApp.pm>, but starting in v5.66, the preferred location is C<lib/MyApp/Controller/Root.pm>).
+We need something that provides enforcement for the authentication
+mechanism -- a I<global> mechanism that prevents users who have not
+passed authentication from reaching any pages except the login page.
+This is generally done via an C<auto> action/method (prior to Catalyst
+v5.66, this sort of thing would go in C<MyApp.pm>, but starting in
+v5.66, the preferred location is C<lib/MyApp/Controller/Root.pm>).
 
 Edit the existing C<lib/MyApp/Controller/Root.pm> class file and insert the following method:
 
@@ -499,30 +538,44 @@ Edit the existing C<lib/MyApp/Controller/Root.pm> class file and insert the foll
         return 1;
     }
 
-B<Note:> Catalyst provides a number of different types of actions, such as C<Local>, C<Regex>, and C<Private>.  You should refer to L<Catalyst::Manual::Intro|Catalyst::Manual::Intro> for a more detailed explanation, but the following bullet points provide a quick introduction:
+B<Note:> Catalyst provides a number of different types of actions, such
+as C<Local>, C<Regex>, and C<Private>.  You should refer to
+L<Catalyst::Manual::Intro|Catalyst::Manual::Intro> for a more detailed
+explanation, but the following bullet points provide a quick
+introduction:
 
 =over 4
 
 =item *
 
-The majority of application use C<Local> actions for items that respond to user requests and C<Private> actions for those that do not directly respond to user input.
+The majority of application use C<Local> actions for items that respond
+to user requests and C<Private> actions for those that do not directly
+respond to user input.
 
 =item *
 
-There are five types of C<Private> actions: C<begin>, C<end>, C<default>, C<index>, and C<auto>.
+There are five types of C<Private> actions: C<begin>, C<end>,
+C<default>, C<index>, and C<auto>.
 
 =item *
 
-Unlike the other private C<Private> actions where only a single method is called for each request, I<every> auto action along the chain of namespaces will be called.
+Unlike the other private C<Private> actions where only a single method
+is called for each request, I<every> auto action along the chain of
+namespaces will be called.
 
 =back
 
-By placing the authentication enforcement code inside the C<auto> method of C<lib/MyApp/Controller/Root.pm> (or C<lib/MyApp.pm>), it will be called for I<every> request that is received by the entire application.
+By placing the authentication enforcement code inside the C<auto> method
+of C<lib/MyApp/Controller/Root.pm> (or C<lib/MyApp.pm>), it will be
+called for I<every> request that is received by the entire application.
 
 
 =head2 Displaying Content Only to Authenticated Users
 
-Let's say you want to provide some information on the login page that changes depending on whether the user has authenticated yet.  To do this, open C<root/src/login.tt2> in your editor and add the following lines to the bottom of the file:
+Let's say you want to provide some information on the login page that
+changes depending on whether the user has authenticated yet.  To do
+this, open C<root/src/login.tt2> in your editor and add the following
+lines to the bottom of the file:
 
     <p>
     [%
@@ -543,19 +596,39 @@ Let's say you want to provide some information on the login page that changes de
        comments.
     %]
 
-Although most of the code is comments, the middle few lines provide a "you are already logged in" reminder if the user returns to the login page after they have already authenticated.  For users who have not yet authenticated, a "You need to log in..." message is displayed (note the use of an IF-THEN-ELSE construct in TT).
+Although most of the code is comments, the middle few lines provide a
+"you are already logged in" reminder if the user returns to the login
+page after they have already authenticated.  For users who have not yet
+authenticated, a "You need to log in..." message is displayed (note the
+use of an IF-THEN-ELSE construct in TT).
 
 
 =head2 Try Out Authentication
 
-Press C<Ctrl-C> to kill the previous server instance (if it's still running) and 
-restart it:
+Press C<Ctrl-C> to kill the previous server instance (if it's still
+running) and restart it:
 
     $ script/myapp_server.pl
 
-B<IMPORTANT NOTE>: If you happen to be using Internet Explorer, you may need to use the command C<script/myapp_server.pl -k> to enable the keepalive feature in the development server.  Otherwise, the HTTP redirect on successful login may not work correctly with IE (it seems to work without –k if you are running the web browser and development server on the same machine).  If you are using browser a browser other than IE, it should work either way.  If you want to make keepalive the default, you can edit C<script/myapp_server.pl> and change the initialization value for C<$keepalive> to C<1>.  (You will need to do this every time you create a new Catalyst application or rebuild the C<myapp_server.pl> script.)
-
-Now trying going to L<http://localhost:3000/books/list> and you should be redirected to the login page, hitting Shift+Reload if necessary (the "You are already logged in" message should I<not> appear -- if it does, click the C<logout> button and try again).  Make note of the C<***Root::auto User not found...> debug message in the development server output.  Enter username C<test01> and password C<mypass>, and you should be taken to the Book List page.  
+B<IMPORTANT NOTE>: If you happen to be using Internet Explorer, you may
+need to use the command C<script/myapp_server.pl -k> to enable the
+keepalive feature in the development server.  Otherwise, the HTTP
+redirect on successful login may not work correctly with IE (it seems to
+work without -k if you are running the web browser and development
+server on the same machine).  If you are using browser a browser other
+than IE, it should work either way.  If you want to make keepalive the
+default, you can edit C<script/myapp_server.pl> and change the
+initialization value for C<$keepalive> to C<1>.  (You will need to do
+this every time you create a new Catalyst application or rebuild the
+C<myapp_server.pl> script.)
+
+Now trying going to L<http://localhost:3000/books/list> and you should
+be redirected to the login page, hitting Shift+Reload if necessary (the
+"You are already logged in" message should I<not> appear -- if it does,
+click the C<logout> button and try again).  Make note of the
+C<***Root::auto User not found...> debug message in the development
+server output.  Enter username C<test01> and password C<mypass>, and you
+should be taken to the Book List page.
 
 Open C< root/src/books/list.tt2> and add the following lines to the bottom:
 
@@ -564,24 +637,40 @@ Open C< root/src/books/list.tt2> and add the following lines to the bottom:
       <a href="[% Catalyst.uri_for('form_create') %]">Create</a>
     </p>
 
-Reload your browser and you should now see a "Login" link at the bottom of the page (as mentioned earlier, you can update template files without reloading the development server).  Click this link to return to the login page.  This time you I<should> see the "You are already logged in" message.
+Reload your browser and you should now see a "Login" link at the bottom
+of the page (as mentioned earlier, you can update template files without
+reloading the development server).  Click this link to return to the
+login page.  This time you I<should> see the "You are already logged in"
+message.
 
-Finally, click the C<You can logout here> link on the C</login> page.  You should stay at the login page, but the message should change to "You need to log in to use this application."
+Finally, click the C<You can logout here> link on the C</login> page.
+You should stay at the login page, but the message should change to "You
+need to log in to use this application."
 
 
 
 =head1 USING PASSWORD HASHES
 
-In this section we increase the security of our system by converting from cleartext passwords to SHA-1 password hashes.
+In this section we increase the security of our system by converting
+from cleartext passwords to SHA-1 password hashes.
 
-B<Note:> This section is optional.  You can skip it and the rest of the tutorial will function normally.  
+B<Note:> This section is optional.  You can skip it and the rest of the
+tutorial will function normally.
 
-Note that even with the techniques shown in this section, the browser still transmits the passwords in cleartext to your application.  We are just avoiding the I<storage> of cleartext passwords in the database by using a SHA-1 hash.  If you are concerned about cleartext passwords between the browser and your application, consider using SSL/TLS.
+Note that even with the techniques shown in this section, the browser
+still transmits the passwords in cleartext to your application.  We are
+just avoiding the I<storage> of cleartext passwords in the database by
+using a SHA-1 hash.  If you are concerned about cleartext passwords
+between the browser and your application, consider using SSL/TLS.
 
 
 =head2 Get a SHA-1 Hash for the Password
 
-Catalyst uses the C<Digest > module to support a variety of hashing algorithms.  Here we will use SHA-1 (SHA = Secure Hash Algorithm).  First, we should compute the SHA-1 hash for the "mypass" password we are using.  The following command-line Perl script provides a "quick and dirty" way to do this:
+Catalyst uses the C<Digest> module to support a variety of hashing
+algorithms.  Here we will use SHA-1 (SHA = Secure Hash Algorithm).
+First, we should compute the SHA-1 hash for the "mypass" password we are
+using.  The following command-line Perl script provides a "quick and
+dirty" way to do this:
 
     $ perl -MDigest::SHA -e 'print Digest::SHA::sha1_hex("mypass"), "\n"'
     e727d1464ae12436e899a726da5b2f11d8381b26
@@ -590,7 +679,9 @@ Catalyst uses the C<Digest > module to support a variety of hashing algorithms.
 
 =head2 Switch to SHA-1 Password Hashes in the Database
 
-Next, we need to change the C<password> column of our C<users> table to store this hash value vs. the existing cleartext password.  Open C<myapp03.sql> in your editor and enter:
+Next, we need to change the C<password> column of our C<users> table to
+store this hash value vs. the existing cleartext password.  Open
+C<myapp03.sql> in your editor and enter:
 
     --
     -- Convert passwords to SHA-1 hashes
@@ -603,12 +694,15 @@ Then use the following command to update the SQLite database:
 
     $ sqlite3 myapp.db < myapp03.sql
 
-B<Note:> We are using SHA-1 hashes here, but many other hashing algorithms are supported.  See C<Digest > for more information.
+B<Note:> We are using SHA-1 hashes here, but many other hashing
+algorithms are supported.  See C<Digest> for more information.
 
 
-=head2 Enable SHA-1 Hash Passwords in C<Catalyst::Plugin::Authentication::Store::DBIC>
+=head2 Enable SHA-1 Hash Passwords in
+C<Catalyst::Plugin::Authentication::Store::DBIC>
 
-Edit C<myapp.yml> and update it to match (the C<password_type> and C<password_hash_type> are new, everything else is the same):
+Edit C<myapp.yml> and update it to match (the C<password_type> and
+C<password_hash_type> are new, everything else is the same):
 
     ---
     name: MyApp
@@ -636,13 +730,14 @@ Edit C<myapp.yml> and update it to match (the C<password_type> and C<password_ha
 
 =head2 Try Out the Hashed Passwords
 
-Press C<Ctrl-C> to kill the previous server instance (if it's still running) and restart it:
+Press C<Ctrl-C> to kill the previous server instance (if it's still
+running) and restart it:
 
     $ script/myapp_server.pl
 
-You should now be able to go to L<http://localhost:3000/books/list> and login as before.  When done, click the "Logout" link on the login page (or point your browser at L<http://localhost:3000/logout>).
-
-
+You should now be able to go to L<http://localhost:3000/books/list> and
+login as before.  When done, click the "Logout" link on the login page
+(or point your browser at L<http://localhost:3000/logout>).
 
 =head1 AUTHOR
 
@@ -652,7 +747,8 @@ Please report any errors, issues or suggestions to the author.
 
 Copyright 2006, Kennedy Clark. All rights reserved.
 
-This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
+This library is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
 
 Version: .94
 
index d83f5e3..9a620fa 100644 (file)
@@ -1,14 +1,13 @@
 =head1 NAME
 
-Catalyst::Manual::Tutorial::Authorization - Catalyst Tutorial – Part 5: Authorization
-
+Catalyst::Manual::Tutorial::Authorization - Catalyst Tutorial - Part 5: Authorization
 
 
 =head1 OVERVIEW
 
 This is B<Part 5 of 9> for the Catalyst tutorial.
 
-L<Totorial Overview|Catalyst::Manual::Tutorial>
+L<Tutorial Overview|Catalyst::Manual::Tutorial>
 
 =over 4
 
@@ -22,7 +21,7 @@ L<Catalyst Basics|Catalyst::Manual::Tutorial::CatalystBasics>
 
 =item 3
 
-L<Basic CRUD|Catalyst::Manual::Tutorial03_BasicCRUD>
+L<Basic CRUD|Catalyst::Manual::Tutorial_BasicCRUD>
 
 =item 4
 
@@ -54,9 +53,15 @@ L<Appendicies|Catalyst::Manual::Tutorial::Appendicies>
 
 =head1 DESCRIPTION
 
-This part of the tutorial adds role-based authorization to the existing authentication implemented in Part 4.  It provides simple examples of how to use roles in both TT templates and controller actions.  The first half looks at manually configured authorization.  The second half looks at how the ACL authorization plugin can simplify your code.
+This part of the tutorial adds role-based authorization to the existing
+authentication implemented in Part 4.  It provides simple examples of
+how to use roles in both TT templates and controller actions.  The first
+half looks at manually configured authorization.  The second half looks
+at how the ACL authorization plugin can simplify your code.
 
-B<TIP>: Note that all of the code for this part of the tutorial can be pulled from the Catalyst Subversion repository in one step with the following command:
+B<TIP>: Note that all of the code for this part of the tutorial can be
+pulled from the Catalyst Subversion repository in one step with the
+following command:
 
     svn checkout http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/Tutorial@###
     IMPORTANT: Does not work yet.  Will be completed for final version.
@@ -136,7 +141,8 @@ Edit C<myapp.yml> and update it to match (everything from the "authorization:" l
 
 =head2 Add Role-Specific Logic to the "Book List" Template
 
-Open C<root/src/books/list.tt2> in your editor and add the following lines to the bottom of the file:
+Open C<root/src/books/list.tt2> in your editor and add the following
+lines to the bottom of the file:
 
     <p>Hello [% Catalyst.user.username %], you have the following roles:</p>
     
@@ -165,9 +171,15 @@ This code displays a different combination of links depending on the roles assig
 
 =head2 Limit C<Books::add> to C<admin> Users
 
-C<IF> statements in TT templates simply control the output that is sent to the user's browser; it provides no real enforcement (if users know or guess the appropriate URLs, they are still perfectly free to hit any action within your application).  We need to enhance the controller logic to wrap restricted actions with role validation logic.  
+C<IF> statements in TT templates simply control the output that is sent
+to the user's browser; it provides no real enforcement (if users know or
+guess the appropriate URLs, they are still perfectly free to hit any
+action within your application).  We need to enhance the controller
+logic to wrap restricted actions with role validation logic.
 
-For example, we might want to restrict the "formless create" action to admin-level users by editing C<lib/MyApp/Controller/Books.pm> and updating C<url_create> to match the following code:
+For example, we might want to restrict the "formless create" action to
+admin-level users by editing C<lib/MyApp/Controller/Books.pm> and
+updating C<url_create> to match the following code:
 
     =head2 url_create
 
@@ -217,9 +229,20 @@ For example, we might want to restrict the "formless create" action to admin-lev
     }
 
 
-To add authorization, we simply write the main code of this method in an C<if> statement that calls C<check_user_roles>.  If the user does not have the appropriate permissions, they receive an "Unauthorized!" message.  Note that we intentionally chose to display the message this way to demonstrate that TT templates will not be used if the response body has already been set.  In reality you would probably want to use a technique that maintains the visual continuity of your template layout (for example, using the "status" or "error" message feature added in Part 2).
+To add authorization, we simply write the main code of this method in an
+C<if> statement that calls C<check_user_roles>.  If the user does not
+have the appropriate permissions, they receive an "Unauthorized!"
+message.  Note that we intentionally chose to display the message this
+way to demonstrate that TT templates will not be used if the response
+body has already been set.  In reality you would probably want to use a
+technique that maintains the visual continuity of your template layout
+(for example, using the "status" or "error" message feature added in
+Part 2).
 
-B<TIP>: If you want to keep your existing C<url_create> method, you can create a new copy and comment out the original by making it look like a Pod comment.  For example, put something like C<=begin> before C<sub add : Local {> and C<=end> after the closing C<}>.
+B<TIP>: If you want to keep your existing C<url_create> method, you can
+create a new copy and comment out the original by making it look like a
+Pod comment.  For example, put something like C<=begin> before C<sub add
+: Local {> and C<=end> after the closing C<}>.
 
 
 =head2 Try Out Authentication And Authorization
@@ -228,33 +251,48 @@ Press C<Ctrl-C> to kill the previous server instance (if it's still running) and
 
     $ script/myapp_server.pl
 
-Now trying going to L<http://localhost:3000/books/list> and you should be taken to the login page (you might have to C<Shift+Reload> your browser).  Try logging in with both C<test01> and C<test02> (both use a password of C<mypass>) and notice how the roles information updates at the bottom of the "Book List" page. Also try the C<Logout> link on the book list page.
+Now trying going to L<http://localhost:3000/books/list> and you should
+be taken to the login page (you might have to C<Shift+Reload> your
+browser).  Try logging in with both C<test01> and C<test02> (both use a
+password of C<mypass>) and notice how the roles information updates at
+the bottom of the "Book List" page. Also try the C<Logout> link on the
+book list page.
 
-Now the "url_create" URL will work if you are already logged in as user C<test01>, but receive an authorization failure if you are logged in as C<test02>.  Try:
+Now the "url_create" URL will work if you are already logged in as user
+C<test01>, but receive an authorization failure if you are logged in as
+C<test02>.  Try:
 
     http://localhost:3000/books/url_create/test/1/6
 
-while logged in as each user.  Use one of the 'Logout' links (or go to L<http://localhost:3000/logout> in you browser directly) when you are done.
+while logged in as each user.  Use one of the 'Logout' links (or go to
+L<http://localhost:3000/logout> in you browser directly) when you are
+done.
 
 
 
 =head1 ENABLE ACL-BASED AUTHORIZATION
 
-This section takes a brief look at how the L<Catalyst::Plugin::Authorization::ACL|Catalyst::Plugin::Authorization::ACL> can automate much of the work required to perform role-based authorization in a Catalyst application.
+This section takes a brief look at how the
+L<Catalyst::Plugin::Authorization::ACL|Catalyst::Plugin::Authorization::ACL>
+can automate much of the work required to perform role-based
+authorization in a Catalyst application.
 
 
 =head2 Add the C<Catalyst::Plugin::Authorization::ACL> Plugin
 
-Open C<lib/MyApp.pm> in your editor and add the following plugin to the C<use Catalyst> statement:
+Open C<lib/MyApp.pm> in your editor and add the following plugin to the
+C<use Catalyst> statement:
 
     Authorization::ACL
 
-Note that the remaining C<use Catalyst> plugins from earlier sections are not shown here, but they should still be included.
+Note that the remaining C<use Catalyst> plugins from earlier sections
+are not shown here, but they should still be included.
 
 
 =head2 Add ACL Rules to the Application Class
 
-Open C<lib/MyApp.pm> in your editor and add the following B<BELOW> the C<__PACKAGE__-E<gt>setup;> statement:
+Open C<lib/MyApp.pm> in your editor and add the following B<BELOW> the
+C<__PACKAGE__-E<gt>setup;> statement:
 
     # Authorization::ACL Rules
     __PACKAGE__->deny_access_unless(
@@ -270,19 +308,35 @@ Open C<lib/MyApp.pm> in your editor and add the following B<BELOW> the C<__PACKA
             [qw/user admin/],
         );
 
-Each of the three statements above comprises an ACL plugin "rule".  The first two rules only allow admin-level users to create new books using the form (both the form itself and the data submission logic are protected).  The third statement allows both users and admin to delete books.  The C</books/url_create> action will continue to be protected by the "manually configured" authorization created earlier in this part of the tutorial.
+Each of the three statements above comprises an ACL plugin "rule".  The
+first two rules only allow admin-level users to create new books using
+the form (both the form itself and the data submission logic are
+protected).  The third statement allows both users and admin to delete
+books.  The C</books/url_create> action will continue to be protected by
+the "manually configured" authorization created earlier in this part of
+the tutorial.
 
-The ACL plugin permits you to apply allow/deny logic in a variety of ways.  The following provides a basic overview of the capabilities:
+The ACL plugin permits you to apply allow/deny logic in a variety of
+ways.  The following provides a basic overview of the capabilities:
 
 =over 4
 
 =item * 
 
-The ACL plugin only operates on the Catalyst "private namespace".  You are using the private namespace when you use C<Local> actions.  C<Path>, C<Regex>, and C<Global> allow you to specify actions where the path and the namespace differ -- the ACL plugin will not work in these cases.
+The ACL plugin only operates on the Catalyst "private namespace".  You
+are using the private namespace when you use C<Local> actions.  C<Path>,
+C<Regex>, and C<Global> allow you to specify actions where the path and
+the namespace differ -- the ACL plugin will not work in these cases.
 
 =item * 
 
-Each rule is expressed in a separate C<__PACKAGE__-E<gt>deny_access_unless()> or C<__PACKAGE__-E<gt>allow_access_if()> line (there are several other methods that can be used for more complex policies, see the C<METHODS> portion of the L<Catalyst::Plugin::Authorization::ACL|Catalyst::Plugin::Authorization::ACL> documentation for more details).
+Each rule is expressed in a separate
+C<__PACKAGE__-E<gt>deny_access_unless()> or
+C<__PACKAGE__-E<gt>allow_access_if()> line (there are several other
+methods that can be used for more complex policies, see the C<METHODS>
+portion of the
+L<Catalyst::Plugin::Authorization::ACL|Catalyst::Plugin::Authorization::ACL>
+documentation for more details).
 
 =item * 
 
@@ -290,7 +344,12 @@ Each rule can contain multiple roles but only a single path.
 
 =item * 
 
-The rules are tried in order (with the "most specific" rules tested first), and processing stops at the first "match" where an allow or deny is specified.  Rules "fall through" if there is not a "match" (where a "match" means the user has the specified role).  If a "match" is found, then processing stops there and the appropriate allow/deny action is taken.
+The rules are tried in order (with the "most specific" rules tested
+first), and processing stops at the first "match" where an allow or deny
+is specified.  Rules "fall through" if there is not a "match" (where a
+"match" means the user has the specified role).  If a "match" is found,
+then processing stops there and the appropriate allow/deny action is
+taken.
 
 =item * 
 
@@ -298,16 +357,24 @@ If none of the rules match, then access is allowed.
 
 =item * 
 
-The rules currently need to be specific in the application class C<lib\MyApp.pm> B<after> the C<__PACKAGE__-E<gt>setup;> line.
+The rules currently need to be specific in the application class
+C<lib\MyApp.pm> B<after> the C<__PACKAGE__-E<gt>setup;> line.
 
 =back
 
 
 =head2 Add a Method to Handle Access Violations
 
-By default, L<Catalyst::Plugin::Authorization::ACL|Catalyst::Plugin::Authorization::ACL> throws an exception when authorization fails.  This will take the user to the Catalyst debug screen, or a "Please come back later" message if you are not using the C<-Debug> flag. This step uses the C<access_denied> method in order to provide more appropriate feedback to the user.
+By default,
+L<Catalyst::Plugin::Authorization::ACL|Catalyst::Plugin::Authorization::ACL>
+throws an exception when authorization fails.  This will take the user
+to the Catalyst debug screen, or a "Please come back later" message if
+you are not using the C<-Debug> flag. This step uses the
+C<access_denied> method in order to provide more appropriate feedback to
+the user.
 
-Open C<lib/MyApp/Controller/Books.pm> in your editor and add the following method:
+Open C<lib/MyApp/Controller/Books.pm> in your editor and add the
+following method:
 
     =head2 access_denied
     
@@ -330,9 +397,16 @@ Then run the Catalyst development server script:
 
     $ script/myapp_server.pl
 
-Log in as C<test02>.  Once at the book list, click the "Create" link to try the C<form_create> action.  You should receive a red "Unauthorized!" error message at the top of the list.  (Note that in reality you would probably want to place the "Create" link code in C<root/src/books/list.tt2> inside an C<IF> statement that only displays the list to admin-level users.)  If you log in as C<test01> you should be able to view the C<form_create> form and add a new book.
+Log in as C<test02>.  Once at the book list, click the "Create" link to
+try the C<form_create> action.  You should receive a red "Unauthorized!"
+error message at the top of the list.  (Note that in reality you would
+probably want to place the "Create" link code in
+C<root/src/books/list.tt2> inside an C<IF> statement that only displays
+the list to admin-level users.)  If you log in as C<test01> you should
+be able to view the C<form_create> form and add a new book.
 
-When you are done, use one of the 'Logout' links (or go to the L<http://localhost:3000/logout> URL directly) when you are done.
+When you are done, use one of the 'Logout' links (or go to the
+L<http://localhost:3000/logout> URL directly) when you are done.
 
 
 
@@ -342,9 +416,7 @@ Kennedy Clark, C<hkclark@gmail.com>
 
 Please report any errors, issues or suggestions to the author.
 
-Copyright 2006, Kennedy Clark. All rights reserved.
-
-This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
+Copyright 2006, Kennedy Clark, under Creative Commons License (L<http://creativecommons.org/licenses/by-nc-sa/2.5/>).
 
 Version: .94
 
index a6034c0..f6685ec 100644 (file)
@@ -1,14 +1,13 @@
 =head1 NAME
 
-Catalyst::Manual::Tutorial::BasicCRUD - Catalyst Tutorial – Part 3: Basic CRUD
-
+Catalyst::Manual::Tutorial::BasicCRUD - Catalyst Tutorial - Part 3: Basic CRUD
 
 
 =head1 OVERVIEW
 
 This is B<Part 3 of 9> for the Catalyst tutorial.
 
-L<Totorial Overview|Catalyst::Manual::Tutorial>
+L<Tutorial Overview|Catalyst::Manual::Tutorial>
 
 =over 4
 
@@ -54,9 +53,19 @@ L<Appendicies|Catalyst::Manual::Tutorial::Appendicies>
 
 =head1 DESCRIPTION
 
-This part of the tutorial builds on the fairly primitive application created in Part 2 to add basic support for Create, Read, Update, and Delete (CRUD) of C<Book> objects.  Note that the 'list' function in Part 2 already implements the Read portion of Crud (although Read normally refers to reading a single object; you could implement full read functionality using the techniques introduced below).  This section will focus on the Create and Delete aspects of CRUD.  More advanced capabilities, including full Update functionality, will be addressed in Part 8.
+This part of the tutorial builds on the fairly primitive application
+created in Part 2 to add basic support for Create, Read, Update, and
+Delete (CRUD) of C<Book> objects.  Note that the 'list' function in Part
+2 already implements the Read portion of Crud (although Read normally
+refers to reading a single object; you could implement full read
+functionality using the techniques introduced below).  This section will
+focus on the Create and Delete aspects of CRUD.  More advanced
+capabilities, including full Update functionality, will be addressed in
+Part 8.
 
-B<TIP>: Note that all of the code for this part of the tutorial can be pulled from the Catalyst Subversion repository in one step with the following command:
+B<TIP>: Note that all of the code for this part of the tutorial can be
+pulled from the Catalyst Subversion repository in one step with the
+following command:
 
     svn checkout http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/Tutorial@###
     IMPORTANT: Does not work yet.  Will be completed for final version.
@@ -65,7 +74,9 @@ B<TIP>: Note that all of the code for this part of the tutorial can be pulled fr
 
 =head1 FORMLESS SUBMISSION
 
-Our initial attempt at object creation will utilize the "URL arguments" feature of Catalyst (we will employ the more common form-based submission in the sections that follow).
+Our initial attempt at object creation will utilize the "URL arguments"
+feature of Catalyst (we will employ the more common form-based
+submission in the sections that follow).
 
 
 =head2 Include a Create Action in the Books Controller
@@ -112,7 +123,13 @@ Edit C<lib/MyApp/Controller/Books.pm> and enter the following method:
         $c->stash->{template} = 'books/create_done.tt2';
     }
 
-Notice that Catalyst takes "extra slash-separated information" from the URL and passes it as arguments in C<@_>.  The C<url_create> action then uses a simple call to the DBIC C<create> method to add the requested information to the database (with a separate call to C<add_to_book_authors> to update the join table).  As do virtually all controller methods (at least the ones that directly handle user input), it then sets the template that should handle this request.
+Notice that Catalyst takes "extra slash-separated information" from the
+URL and passes it as arguments in C<@_>.  The C<url_create> action then
+uses a simple call to the DBIC C<create> method to add the requested
+information to the database (with a separate call to
+C<add_to_book_authors> to update the join table).  As do virtually all
+controller methods (at least the ones that directly handle user input),
+it then sets the template that should handle this request.
 
 
 =head2 Include a Template for the C<url_create> Action:
@@ -142,37 +159,59 @@ Edit C<root/src/books/create_done.tt2> and then enter:
     [% Dumper.dump(book) %]
     </pre>
 
-The TT C<USE> directive allows access to a variety of plugin modules (we are talking TT plugins here, not Catalyst plugins) to add extra functionality to the base TT capabilities.  Here, the plugin allows L<Data::Dumper|Data::Dumper> "pretty printing" of objects and variables.  Other than that, the rest of the code should be familiar from the examples in Part 2.
+The TT C<USE> directive allows access to a variety of plugin modules (we
+are talking TT plugins here, not Catalyst plugins) to add extra
+functionality to the base TT capabilities.  Here, the plugin allows
+L<Data::Dumper|Data::Dumper> "pretty printing" of objects and variables.
+Other than that, the rest of the code should be familiar from the
+examples in Part 2.
 
-B<IMPORTANT NOTE> As mentioned earlier, the C<MyApp::View::TT.pm> view class created by TTSite redefines the name used to access the Catalyst context object in TT templates from the usual C<c> to C<Catalyst>.
+B<IMPORTANT NOTE> As mentioned earlier, the C<MyApp::View::TT.pm> view
+class created by TTSite redefines the name used to access the Catalyst
+context object in TT templates from the usual C<c> to C<Catalyst>.
 
 
 =head2 Try the C<url_create> Feature
 
-If the application is still running from before, use C<Ctrl-C> to kill it.  Then restart the server:
+If the application is still running from before, use C<Ctrl-C> to kill
+it.  Then restart the server:
 
     $ script/myapp_server.pl
 
-Note that new path for C</books/url_create> appears in the startup debug output.
+Note that new path for C</books/url_create> appears in the startup debug
+output.
 
-B<TIP>: You can use C<script/myapp_server.pl -r> to have the development server auto-detect changed files and reload itself (if your browser acts odd, you should also try throwing in a C<-k>).  If you make changes to just the TT templates, you do not need to reload the development server (only changes to "compiled code" such as Controller and Model C<.pm> files require a reload).
+B<TIP>: You can use C<script/myapp_server.pl -r> to have the development
+server auto-detect changed files and reload itself (if your browser acts
+odd, you should also try throwing in a C<-k>).  If you make changes to
+just the TT templates, you do not need to reload the development server
+(only changes to "compiled code" such as Controller and Model C<.pm>
+files require a reload).
 
 Next, use your browser to enter the following URL:
 
     http://localhost:3000/books/url_create/TCPIP_Illustrated_Vol-2/5/4
 
-Your browser should display " Added book 'TCPIP_Illustrated_Vol-2' by 'Stevens' with a rating of 5." along with a dump of the new book model object.  You should also see the following DBIC debug messages displayed in the development server log messages:
+Your browser should display " Added book 'TCPIP_Illustrated_Vol-2' by
+'Stevens' with a rating of 5." along with a dump of the new book model
+object.  You should also see the following DBIC debug messages displayed
+in the development server log messages:
 
     INSERT INTO books (rating, title) VALUES (?, ?): `5', `TCPIP_Illustrated_Vol-2'
     INSERT INTO book_authors (author_id, book_id) VALUES (?, ?): `4', `6'
 
-If you then click the "Return to list" link, you should find that there are now six books shown (if necessary, Shift-Reload your browser at the C</books/list> page).
+If you then click the "Return to list" link, you should find that there
+are now six books shown (if necessary, Shift-Reload your browser at the
+C</books/list> page).
 
 
 
 =head1 MANUALLY BUILDING A CREATE FORM
 
-Although the C<url_create> action in the previous step does begin to reveal the power and flexibility of both Catalyst and DBIC, it's obviously not a very realistic example of how users should be expected to enter data.  This section begins to address that concern.
+Although the C<url_create> action in the previous step does begin to
+reveal the power and flexibility of both Catalyst and DBIC, it's
+obviously not a very realistic example of how users should be expected
+to enter data.  This section begins to address that concern.
 
 
 =head2 Add Method to Display The Form
@@ -210,12 +249,14 @@ Open C<root/src/books/form_create.tt2> in your editor and enter:
     <input type="submit" name="Submit" value="Submit">
     </form>
 
-Note that we have specified the target of the form data as C<form_create_do>, the method created in the section that follows.
+Note that we have specified the target of the form data as
+C<form_create_do>, the method created in the section that follows.
 
 
 =head2 Add Method to Process Form Values and Update Database
 
-Edit C<lib/MyApp/Controller/Books.pm> and add the following method to save the form information to the databse:
+Edit C<lib/MyApp/Controller/Books.pm> and add the following method to
+save the form information to the databse:
 
     =head2 form_create_do
     
@@ -257,20 +298,30 @@ If the application is still running from before, use C<Ctrl-C> to kill it.  Then
 
     $ script/myapp_server.pl
 
-Point your browser to L<http://localhost:3000/books/form_create> and enter "TCP/IP Illustrated, Vol 3" for the title, a rating of 5, and an author ID of 4.  You should then be forwarded to the same C<create_done.tt2> template seen in earlier examples.  Finally, click "Return to list" to view the full list of books.
+Point your browser to L<http://localhost:3000/books/form_create> and
+enter "TCP/IP Illustrated, Vol 3" for the title, a rating of 5, and an
+author ID of 4.  You should then be forwarded to the same
+C<create_done.tt2> template seen in earlier examples.  Finally, click
+"Return to list" to view the full list of books.
 
-B<Note:> Having the user enter the primary key ID for the author is obviously a bit crude; we will address this concern with a drop-down list in Part 8.
+B<Note:> Having the user enter the primary key ID for the author is
+obviously a bit crude; we will address this concern with a drop-down
+list in Part 8.
 
 
 
 =head1 A SIMPLE DELETE FEATURE
 
-Turning out attention to the delete portion of CRUD, this section illustrates some basic techniques that can be used to remove information from the database.
+Turning out attention to the delete portion of CRUD, this section
+illustrates some basic techniques that can be used to remove information
+from the database.
 
 
 =head2 Include a Delete Link in the List
 
-Edit C<root/src/books/list.tt2> and update it to the following (two sections have changed: 1) the additional '<th>Links</th>' table header, and 2) the four lines for the Delete link near the bottom).
+Edit C<root/src/books/list.tt2> and update it to the following (two
+sections have changed: 1) the additional '<th>Links</th>' table header,
+and 2) the four lines for the Delete link near the bottom).
 
     [% # This is a TT comment.  The '-' at the end "chomps" the newline.  You won't -%]
     [% # see this "chomping" in your browser because HTML ignores blank lines, but  -%]
@@ -307,12 +358,15 @@ Edit C<root/src/books/list.tt2> and update it to the following (two sections hav
     [% END -%]
     </table>
 
-The additional code is obviously designed to add a new column to the right side of the table with a C<Delete> "button" (for simplicity, links will be used instead of full HTML buttons).
+The additional code is obviously designed to add a new column to the
+right side of the table with a C<Delete> "button" (for simplicity, links
+will be used instead of full HTML buttons).
 
 
 =head2 Add a Delete Action to the Controller
 
-Open C<lib/MyApp/Controller/Books.pm> in your editor and add the following method:
+Open C<lib/MyApp/Controller/Books.pm> in your editor and add the
+following method:
 
     =head2 Delete 
     
@@ -334,23 +388,43 @@ Open C<lib/MyApp/Controller/Books.pm> in your editor and add the following metho
         $c->forward('list');
     }
 
-This method first deletes the book with the specified primary key ID.  However, it also removes the corresponding entry from the C<book_authors> table.  Note that C<delete_all> was used instead of C<delete>: whereas C<delete_all> also removes the join table entries in C<book_authors>, C<delete> does not.
+This method first deletes the book with the specified primary key ID.
+However, it also removes the corresponding entry from the
+C<book_authors> table.  Note that C<delete_all> was used instead of
+C<delete>: whereas C<delete_all> also removes the join table entries in
+C<book_authors>, C<delete> does not.
 
-Then, rather than forwarding to a "delete done" page as we did with the earlier create example, it simply sets the C<status_msg> to display a notification to the user as the normal list view is rendered.  
+Then, rather than forwarding to a "delete done" page as we did with the
+earlier create example, it simply sets the C<status_msg> to display a
+notification to the user as the normal list view is rendered.
 
-The C<delete> action uses the context C<forward> method to return the user to the book list.  The C<detach> method could have also been used.  Whereas C<forward> I<returns> to the original action once it is completed, C<detach> does I<not> return.  Other than that, the two are equivalent.
+The C<delete> action uses the context C<forward> method to return the
+user to the book list.  The C<detach> method could have also been used.
+Whereas C<forward> I<returns> to the original action once it is
+completed, C<detach> does I<not> return.  Other than that, the two are
+equivalent.
 
-Another alternative to C<forward> would be to use C<$c-E<gt>response-E<gt>redirect($c-E<gt>uri_for('/books/list'))>.  The C<forward> and C<redirect> operations differ in several important respects that stem from the fact that redirects cause the client browser to issue an entirely new HTTP request.  In doing so, this results in a new URL showing in the browser window.  And, because the stash information is reset for every request, the "Book deleted" message would not be displayed.
+Another alternative to C<forward> would be to use
+C<$c-E<gt>response-E<gt>redirect($c-E<gt>uri_for('/books/list'))>.  The
+C<forward> and C<redirect> operations differ in several important
+respects that stem from the fact that redirects cause the client browser
+to issue an entirely new HTTP request.  In doing so, this results in a
+new URL showing in the browser window.  And, because the stash
+information is reset for every request, the "Book deleted" message would
+not be displayed.
 
 
 =head2 Try the Delete Feature
 
-If the application is still running from before, use C<Ctrl-C> to kill it.  Then restart the server:
+If the application is still running from before, use C<Ctrl-C> to kill
+it.  Then restart the server:
 
     $ script/myapp_server.pl
 
-Then point your browser to L<http://localhost:3000/books/list> and click the "Delete" link next to "TCPIP_Illustrated_Vol-2".  A green "Book deleted" status message should display at the top of the page, along with a list of the six remaining books.
-
+Then point your browser to L<http://localhost:3000/books/list> and click
+the "Delete" link next to "TCPIP_Illustrated_Vol-2".  A green "Book
+deleted" status message should display at the top of the page, along
+with a list of the six remaining books.
 
 
 =head1 AUTHOR
@@ -359,9 +433,8 @@ Kennedy Clark, C<hkclark@gmail.com>
 
 Please report any errors, issues or suggestions to the author.
 
-Copyright 2006, Kennedy Clark. All rights reserved.
-
-This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
+Copyright 2006, Kennedy Clark, under Creative Commons License
+(L<http://creativecommons.org/licenses/by-nc-sa/2.5/>).
 
 Version: .94
 
index f378f13..65fd1d6 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-Catalyst::Manual::Tutorial::CatalystBasics - Catalyst Tutorial – Part 2: Catalyst Application Development Basics
+Catalyst::Manual::Tutorial::CatalystBasics - Catalyst Tutorial - Part 2: Catalyst Application Development Basics
 
 
 
@@ -8,7 +8,7 @@ Catalyst::Manual::Tutorial::CatalystBasics - Catalyst Tutorial 
 
 This is B<Part 2 of 9> for the Catalyst tutorial.
 
-L<Totorial Overview|Catalyst::Manual::Tutorial>
+L<Tutorial Overview|Catalyst::Manual::Tutorial>
 
 =over 4
 
@@ -22,7 +22,7 @@ B<Catalyst Basics>
 
 =item 3
 
-L<Basic CRUD|Catalyst::Manual::Tutorial03_BasicCRUD>
+L<Basic CRUD|Catalyst::Manual::Tutorial_BasicCRUD>
 
 =item 4
 
@@ -54,41 +54,58 @@ L<Appendicies|Catalyst::Manual::Tutorial::Appendicies>
 
 =head1 DESCRIPTION
 
-In this part of the tutorial, we will create a very basic Catalyst web application.  Though simple in many respects, this section will already demonstrate a number of powerful capabilities such as:
+In this part of the tutorial, we will create a very basic Catalyst web
+application.  Though simple in many respects, this section will already
+demonstrate a number of powerful capabilities such as:
 
 =over 4
 
 =item * Helper Scripts
 
-Catalyst helper scripts that can be used to rapidly bootstrap the skeletal structure of an application.
+Catalyst helper scripts that can be used to rapidly bootstrap the
+skeletal structure of an application.
 
 =item * MVC
 
-Model/View/Controller (MVC) provides an architecture that facilitates a clean "separation of control" between the different portions of your application.  Given that many other documents cover this subject in detail, MVC will not be discussed in depth here (for an excellent introduction to MVC and general Catalyst concepts, please see L<Catalyst::Manual::About|Catalyst::Manual::About>.  In short:
+Model/View/Controller (MVC) provides an architecture that facilitates a
+clean "separation of control" between the different portions of your
+application.  Given that many other documents cover this subject in
+detail, MVC will not be discussed in depth here (for an excellent
+introduction to MVC and general Catalyst concepts, please see
+L<Catalyst::Manual::About|Catalyst::Manual::About>.  In short:
 
 =over 4
 
 =item * Model
 
-In most applications, the model equates to the objects that are created from and saved to your SQL database.
+In most applications, the model equates to the objects that are created
+from and saved to your SQL database.
 
 =item * View
 
-The view takes model objects and renders them into something for the end user to look at.  Normally this involves a template-generation tool that creates HTML for the user's web browser, but it could easily be code that generates other forms such as PDF documents or Excel spreadsheets.
+The view takes model objects and renders them into something for the end
+user to look at.  Normally this involves a template-generation tool that
+creates HTML for the user's web browser, but it could easily be code
+that generates other forms such as PDF documents or Excel spreadsheets.
 
 =item * Controller
 
-As suggested by its name, the controller takes user requests and routes them to the necessary model and view.
+As suggested by its name, the controller takes user requests and routes
+them to the necessary model and view.
 
 =back
 
 =item * ORM
 
-The use Object-Relational Mapping (ORM) technology for database access (specifically, ORM provides an automated means to persist and restore objects to/from a relational database).
+The use Object-Relational Mapping (ORM) technology for database access
+(specifically, ORM provides an automated means to persist and restore
+objects to/from a relational database).
 
 =back
 
-B<TIP>: Note that all of the code for this part of the tutorial can be pulled from the Catalyst Subversion repository in one step with the following command:
+B<TIP>: Note that all of the code for this part of the tutorial can be
+pulled from the Catalyst Subversion repository in one step with the
+following command:
 
     svn checkout http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/Tutorial@###
     IMPORTANT: Does not work yet.  Will be completed for final version.
@@ -97,26 +114,37 @@ B<TIP>: Note that all of the code for this part of the tutorial can be pulled fr
 
 =head1 CREATE A CATALYST PROJECT
 
-Catalyst provides a number of helper scripts that can be used to quickly flesh out the basic structure of your application.  All Catalyst projects begin with the C<catalyst.pl> helper.
+Catalyst provides a number of helper scripts that can be used to quickly
+flesh out the basic structure of your application.  All Catalyst
+projects begin with the C<catalyst.pl> helper.
 
-In the case of this tutorial, use the Catalyst C<catalyst.pl> script to initialize the framework for an application called C<MyApp>:
+In the case of this tutorial, use the Catalyst C<catalyst.pl> script to
+initialize the framework for an application called C<MyApp>:
 
     $ catalyst.pl MyApp
     $ cd MyApp
 
-The C<catalyst.pl> helper script will display the names of the directories and files it creates.
+The C<catalyst.pl> helper script will display the names of the
+directories and files it creates.
 
-Though it's obviously too early for any significant celebration, we already have a functioning application.  Run the following command to run this application with the built-in development web server:
+Though it's obviously too early for any significant celebration, we
+already have a functioning application.  Run the following command to
+run this application with the built-in development web server:
 
        $ script/myapp_server.pl
 
-Point your web browser to L<http://localhost:3000> (substituting a different hostname or IP address as appropriate) and you should be greeted by the Catalyst welcome screen.  Press Ctrl-C to break out of the development server.
+Point your web browser to L<http://localhost:3000> (substituting a
+different hostname or IP address as appropriate) and you should be
+greeted by the Catalyst welcome screen.  Press Ctrl-C to break out of
+the development server.
 
 
 
 =head1 CREATE A SQLITE DATABASE
 
-In this step, we make a text file with the required SQL commands to create a database table and load some sample data.  Open C<myapp01.sql> in your editor and enter:
+In this step, we make a text file with the required SQL commands to
+create a database table and load some sample data.  Open C<myapp01.sql>
+in your editor and enter:
 
     --
     -- Create a very simple database to hold book and author information
@@ -162,15 +190,20 @@ In this step, we make a text file with the required SQL commands to create a dat
     INSERT INTO book_authors VALUES (4, 7);
     INSERT INTO book_authors VALUES (5, 8);
 
-B<TIP>: See Appendix 1 for tips on removing the leading spaces when cutting and pasting example code from Pod documents.
+B<TIP>: See Appendix 1 for tips on removing the leading spaces when
+cutting and pasting example code from Pod documents.
 
 Then use the following command to build a C<myapp.db> SQLite database:
 
     $ sqlite3 myapp.db < myapp01.sql
 
-If you need to create the database more than once, you probably want to issue the C<rm myapp.db> command to delete the database before you use the C<sqlite3 myapp.db < myapp01.sql> command.
+If you need to create the database more than once, you probably want to
+issue the C<rm myapp.db> command to delete the database before you use
+the C<sqlite3 myapp.db < myapp01.sql> command.
 
-Once the C<myapp.db> database file has been created and initialized, you can use the SQLite command line environment to do a quick dump of the database contents:
+Once the C<myapp.db> database file has been created and initialized, you
+can use the SQLite command line environment to do a quick dump of the
+database contents:
 
     $ sqlite3 myapp.db
     SQLite version 3.2.2
@@ -193,13 +226,22 @@ Or:
     4|Perl Cookbook|5
     5|Designing with Web Standards|5
 
-As with most other SQL tools, if you are using the full "interactive" environment you need to terminate your SQL commands with a ";" (it's not required if you do a single SQL statement on the command line).  Use ".q" to exit from SQLite from the SQLite interactive mode and return to your OS command prompt.
+As with most other SQL tools, if you are using the full "interactive"
+environment you need to terminate your SQL commands with a ";" (it's not
+required if you do a single SQL statement on the command line).  Use
+".q" to exit from SQLite from the SQLite interactive mode and return to
+your OS command prompt.
 
 
 
 =head1 EDIT THE LIST OF CATALYST PLUGINS
 
-One of the greatest benefits of Catalyst is that it has such a large library of plugins available.  Plugins are used to seamlessly integrate existing Perl modules into the overall Catalyst framework.  In general, they do this by adding additional methods to the C<context> object (generally written as C<$c>) that Catalyst passes to every component throughout the framework.
+One of the greatest benefits of Catalyst is that it has such a large
+library of plugins available.  Plugins are used to seamlessly integrate
+existing Perl modules into the overall Catalyst framework.  In general,
+they do this by adding additional methods to the C<context> object
+(generally written as C<$c>) that Catalyst passes to every component
+throughout the framework.
 
 By default, Catalyst enables three plugins/flags:
 
@@ -209,28 +251,43 @@ By default, Catalyst enables three plugins/flags:
 
 C<-Debug> Flag
 
-Enables the Catalyst debug output you saw when we started the C<script/myapp_server.pl> development server earlier.  You can remove this plugin when you place your application into production.
+Enables the Catalyst debug output you saw when we started the
+C<script/myapp_server.pl> development server earlier.  You can remove
+this plugin when you place your application into production.
 
-As you may have noticed, C<-Debug> is not a plugin, but a I<flag>.  Although most of the items specified on the C<use Catalyst> line of your application class will be plugins, Catalyst supports a limited number of flag options (of these, C<-Debug> is the most common).  
+As you may have noticed, C<-Debug> is not a plugin, but a I<flag>.
+Although most of the items specified on the C<use Catalyst> line of your
+application class will be plugins, Catalyst supports a limited number of
+flag options (of these, C<-Debug> is the most common).
 
-If you prefer, you can use the C<$c-E<gt>debug> method to enable debug messages.
+If you prefer, you can use the C<$c-E<gt>debug> method to enable debug
+messages.
 
 =item *
 
 L<Catalyst::Plugin::ConfigLoader|Catalyst::Plugin::ConfigLoader>
 
-C<ConfigLoader> provides an automatic way to load your configurable parameters for your application from a central YAML file (versus having the values hard-coded inside your Perl modules).  If you have not been exposed to YAML before, it is a human-readable data serialization format that can be used to read (and write) values to/from text files.  We will see how to use this feature of Catalyst during the authentication and authorization sections (Part 4 and Part 5).
+C<ConfigLoader> provides an automatic way to load your configurable
+parameters for your application from a central YAML file (versus having
+the values hard-coded inside your Perl modules).  If you have not been
+exposed to YAML before, it is a human-readable data serialization format
+that can be used to read (and write) values to/from text files.  We will
+see how to use this feature of Catalyst during the authentication and
+authorization sections (Part 4 and Part 5).
 
 
 =item *
 
 L<Catalyst::Plugin::Static::Simple|Catalyst::Plugin::Static::Simple>
 
-C<Static::Simple> provides an easy method of serving static content such as images and CSS files under the development server.
+C<Static::Simple> provides an easy method of serving static content such
+as images and CSS files under the development server.
 
 =back
 
-To modify the list of plugins, edit C<lib/MyApp.pm> (this file is generally referred to as your I<application class>) and delete the line with:
+To modify the list of plugins, edit C<lib/MyApp.pm> (this file is
+generally referred to as your I<application class>) and delete the line
+with:
 
     use Catalyst qw/-Debug ConfigLoader Static::Simple/;
 
@@ -254,44 +311,78 @@ This tells Catalyst to start using three new plugins:
 
 L<Catalyst::Plugin::Dumper|Catalyst::Plugin::Dumper>
 
-Allows you to easily use L<Data::Dumper|Data::Dumper> to dump variables to the logs, for example:
+Allows you to easily use L<Data::Dumper|Data::Dumper> to dump variables
+to the logs, for example:
 
     $c->log->dumper($myvar);
 
-When running your application under the development server, the logs will be printed to your screen along with the other debug information generated by the C<-Debug> flag.
+When running your application under the development server, the logs
+will be printed to your screen along with the other debug information
+generated by the C<-Debug> flag.
 
 =item * 
 
 L<Catalyst::Plugin::StackTrace|Catalyst::Plugin::StackTrace>
 
-Adds a stack trace to the standard Catalyst "debug screen" (this is the screen Catalyst sends to your browser when an error occurs).
+Adds a stack trace to the standard Catalyst "debug screen" (this is the
+screen Catalyst sends to your browser when an error occurs).
 
-Note: L<Dumper|Catalyst::Plugin::Dumper> output appears on the console/telnet/SSH window where you issue the C<script/myapp_server.pl> command.  L<StackTrace|Catalyst::Plugin::StackTrace> output appears in your browser.
+Note: L<Dumper|Catalyst::Plugin::Dumper> output appears on the
+console/telnet/SSH window where you issue the C<script/myapp_server.pl>
+command.  L<StackTrace|Catalyst::Plugin::StackTrace> output appears in
+your browser.
 
 =item * 
 
 L<Catalyst::Plugin::DefaultEnd|Catalyst::Plugin::DefaultEnd>
 
-Automatically provides a Catalyst "end action" that invokes your view at the end of each request.  Also allows you to add "dump_info=1" (precede with "?" or "&" depending on where it is in the URL) to I<force> the debug screen at the end of the Catalyst request processing cycle.  
+Automatically provides a Catalyst "end action" that invokes your view at
+the end of each request.  Also allows you to add "dump_info=1" (precede
+with "?" or "&" depending on where it is in the URL) to I<force> the
+debug screen at the end of the Catalyst request processing cycle.
 
-TIP: Many Catalyst-related documents predate L<DefaultEnd|Catalyst::Plugin::DefaultEnd> and suggest that you add an C<end> action to your application class (C<MyApp.pm>) or Root.pm (C<MyApp/Controller/Root.pm>).  In most of these cases, you can convert to L<DefaultEnd|Catalyst::Plugin::DefaultEnd> by deleting the C<end> action and using the plugin instead.
+TIP: Many Catalyst-related documents predate
+L<DefaultEnd|Catalyst::Plugin::DefaultEnd> and suggest that you add an
+C<end> action to your application class (C<MyApp.pm>) or Root.pm
+(C<MyApp/Controller/Root.pm>).  In most of these cases, you can convert
+to L<DefaultEnd|Catalyst::Plugin::DefaultEnd> by deleting the C<end>
+action and using the plugin instead.
 
 =back
 
-Note that when specifying plugins on the C<use Catalyst> line, you can omit C<Catalyst::Plugin> from the name.  Additionally, you can spread the plugin names across multiple lines as shown here, or place them all on one (or more) lines as with the default configuration.
+Note that when specifying plugins on the C<use Catalyst> line, you can
+omit C<Catalyst::Plugin> from the name.  Additionally, you can spread
+the plugin names across multiple lines as shown here, or place them all
+on one (or more) lines as with the default configuration.
 
 
 
 =head1 DATABASE ACCESS WITH C<DBIx::Class>
 
-Catalyst can be used with virtually any form of persistent datastore available via Perl.  For example, L<Catalyst::Model::DBI|Catalyst::Model::DBI> can be used to easily access databases through the traditional Perl DBI interface.  However, most Catalyst applications use some form of ORM technology to automatically create and save model objects as they are used.  Although Tony Bowden's L<Class::DBI|Class::DBI> has been the traditional Perl ORM engine, Matt Trout's L<DBIx::Class|DBIx::Class> (abbreviated as "DBIC") has rapidly emerged as the Perl-based ORM technology of choice.  Most new Catalyst applications rely on DBIC, as will this tutorial.
+Catalyst can be used with virtually any form of persistent datastore
+available via Perl.  For example,
+L<Catalyst::Model::DBI|Catalyst::Model::DBI> can be used to easily
+access databases through the traditional Perl DBI interface.  However,
+most Catalyst applications use some form of ORM technology to
+automatically create and save model objects as they are used.  Although
+Tony Bowden's L<Class::DBI|Class::DBI> has been the traditional Perl ORM
+engine, Matt Trout's L<DBIx::Class|DBIx::Class> (abbreviated as "DBIC")
+has rapidly emerged as the Perl-based ORM technology of choice.  Most
+new Catalyst applications rely on DBIC, as will this tutorial.
 
-Note: See L<Catalyst::Model::CDBI| Catalyst:: Model::CDBI > for more information on using Catalyst with L<Class::DBI|Class::DBI>.  Catalyst can also be used with "plain old DBI"; see L<Catalyst::Model::DBI| Catalyst::Model::DBI>.
+Note: See L<Catalyst::Model::CDBI| Catalyst:: Model::CDBI > for more
+information on using Catalyst with L<Class::DBI|Class::DBI>.  Catalyst
+can also be used with "plain old DBI"; see L<Catalyst::Model::DBI|
+Catalyst::Model::DBI>.
 
 
 =head2 Create a DBIC Schema File
 
-DBIx::Class uses a schema file to load other classes that represent the tables in your database (DBIC refers to these "table objects" as "result sources," see L<DBIx::Class::ResultSource|DBIx::Class::ResultSource>).  In this case, we want to load the model object for the C<books>, C<book_authors>, and C<authors> tables created in the previous step.
+DBIx::Class uses a schema file to load other classes that represent the
+tables in your database (DBIC refers to these "table objects" as "result
+sources," see L<DBIx::Class::ResultSource|DBIx::Class::ResultSource>).
+In this case, we want to load the model object for the C<books>,
+C<book_authors>, and C<authors> tables created in the previous step.
 
 Open C<lib/MyAppDB.pm> in your editor and insert:
 
@@ -320,12 +411,16 @@ Open C<lib/MyAppDB.pm> in your editor and insert:
     
     1;
 
-B<Note:> C<__PACKAGE__> is just a shorthand way of referencing the name of the package where it is used.  Therefore, in C<MyAppDB.pm>, C<__PACKAGE> is equivalent to C<MyAppDB>
+B<Note:> C<__PACKAGE__> is just a shorthand way of referencing the name
+of the package where it is used.  Therefore, in C<MyAppDB.pm>,
+C<__PACKAGE> is equivalent to C<MyAppDB>
 
 
 =head2 Create the DBIC "Result Source" Files
 
-In this step, we create "table classes" (again, these are called a "result source" classes in DBIC) that acts as model objects for the C<books>, C<book_authors>, and C<authors> tables in our database.
+In this step, we create "table classes" (again, these are called a
+"result source" classes in DBIC) that acts as model objects for the
+C<books>, C<book_authors>, and C<authors> tables in our database.
 
 First, create a directory to hold the class:
 
@@ -382,7 +477,18 @@ Then open C<lib/MyAppDB/Book.pm> in your editor and enter:
     
     1;
 
-This defines both a C<has_many> and a C<many_to_many> relationship.  The C<many_to_many> relationship is optional, but it makes it easier to map a book to its collection of authors.  Without it, we would have to "walk" though the C<book_authors> table as in C<$book-E<gt>book_authors-E<gt>first-E<gt>author-E<gt>last_name> (we will see examples on how to use DBIC objects in your code soon, but note that because C<$book-E<gt>book_authors> can return multiple authors, we have to use C<first> to display a single author).  C<many_to_many> allows us to use the shorter C<$book-E<gt>authors-E<gt>first-E<gt>last_name>.  Note that you cannot define a C<many_to_many> relationship without also having the C<has_many> relationship in place.
+This defines both a C<has_many> and a C<many_to_many> relationship.  The
+C<many_to_many> relationship is optional, but it makes it easier to map
+a book to its collection of authors.  Without it, we would have to
+"walk" though the C<book_authors> table as in
+C<$book-E<gt>book_authors-E<gt>first-E<gt>author-E<gt>last_name> (we
+will see examples on how to use DBIC objects in your code soon, but note
+that because C<$book-E<gt>book_authors> can return multiple authors, we
+have to use C<first> to display a single author).  C<many_to_many>
+allows us to use the shorter
+C<$book-E<gt>authors-E<gt>first-E<gt>last_name>.  Note that you cannot
+define a C<many_to_many> relationship without also having the
+C<has_many> relationship in place.
 
 Next, open C<lib/MyAppDB/Author.pm> in your editor and enter:
 
@@ -490,20 +596,41 @@ Finally, open C<lib/MyAppDB/BookAuthor.pm> in your editor and enter:
     
     1;
 
-B<Note:> This sample application uses a plural form for the database tables (e.g., C<books> and C<authors>) and a singular form for the model objects (e.g., C<Book> and C<Author>); however, Catalyst places no restrictions on the naming conventions you wish to use.
+B<Note:> This sample application uses a plural form for the database
+tables (e.g., C<books> and C<authors>) and a singular form for the model
+objects (e.g., C<Book> and C<Author>); however, Catalyst places no
+restrictions on the naming conventions you wish to use.
 
 
 =head2 Use C<Catalyst::Model::DBIC::Schema> To Load The Model Class
 
-When L<Catalyst::Model::DBIC::Schema|Catalyst::Model::DBIC::Schema> is in use, Catalyst essentially reads an existing copy of your database model and creates a new set of objects under C<MyApp::Model> for use inside of Catalyst.
+When L<Catalyst::Model::DBIC::Schema|Catalyst::Model::DBIC::Schema> is
+in use, Catalyst essentially reads an existing copy of your database
+model and creates a new set of objects under C<MyApp::Model> for use
+inside of Catalyst.
 
-B<Note:> With L<Catalyst::Model::DBIC::Schema|Catalyst::Model::DBIC::Schema> you essentially end up with two sets of model classes (only one of which you write... the other set is created automatically in memory when your Catalyst application initializes).  For this tutorial application, the important points to remember are: you write the I<result source> files in C<MyAppDB>, but I<within Catalyst> you use the I<automatically created model classes> in C<MyApp::Model>.
+B<Note:> With
+L<Catalyst::Model::DBIC::Schema|Catalyst::Model::DBIC::Schema> you
+essentially end up with two sets of model classes (only one of which you
+write... the other set is created automatically in memory when your
+Catalyst application initializes).  For this tutorial application, the
+important points to remember are: you write the I<result source> files
+in C<MyAppDB>, but I<within Catalyst> you use the I<automatically
+created model classes> in C<MyApp::Model>.
 
-Use the L<Catalyst::Helper::Model::DBIC::Schema| Catalyst::Helper::Model::DBIC::Schema > helper script to create the model class that loads up the model we created in the previous step:
+Use the L<Catalyst::Helper::Model::DBIC::Schema|
+Catalyst::Helper::Model::DBIC::Schema > helper script to create the
+model class that loads up the model we created in the previous step:
 
     $ script/myapp_create.pl model MyAppDB DBIC::Schema MyAppDB dbi:SQLite:myapp.db '' '' '{ AutoCommit => 1 }'
 
-Where the first C<MyAppDB> is the name of the class to be created by the helper in C<lib/MyApp/Model> and the second C<MyAppDB> is the name of existing schema file we created (in C<lib/MyAppDB.pm>).  You can see that the helper creates a model file under C<lib/MyApp/Model> (Catalyst has a separate directory under C<lib/MyApp> for each of the three parts of MVC: C<Model>, C<View>, and C<Controller> [although older Catalyst applications often use the directories C<M>, C<V>, and C<C>]).
+Where the first C<MyAppDB> is the name of the class to be created by the
+helper in C<lib/MyApp/Model> and the second C<MyAppDB> is the name of
+existing schema file we created (in C<lib/MyAppDB.pm>).  You can see
+that the helper creates a model file under C<lib/MyApp/Model> (Catalyst
+has a separate directory under C<lib/MyApp> for each of the three parts
+of MVC: C<Model>, C<View>, and C<Controller> [although older Catalyst
+applications often use the directories C<M>, C<V>, and C<C>]).
 
 
 
@@ -515,7 +642,8 @@ Use the Catalyst C<create> script to add a controller for book-related actions:
 
     $ script/myapp_create.pl controller Books
 
-Then edit C<lib/MyApp/Controller/Books.pm> and add the following method to the controller:
+Then edit C<lib/MyApp/Controller/Books.pm> and add the following method
+to the controller:
 
     =head2 list
     
@@ -538,16 +666,34 @@ Then edit C<lib/MyApp/Controller/Books.pm> and add the following method to the c
         $c->stash->{template} = 'books/list.tt2';
     }
 
-B<Note:> Programmers experienced with object-oriented Perl should recognize C<$self> as a reference to the object where this method was called.  On the other hand, C<$c> will be new to many Perl programmers who have not used Catalyst before (it's sometimes written as C<$context>).  The Context object is automatically passed to all Catalyst components.  It is used to pass information between components and provide access to Catalyst and plugin functionality.
+B<Note:> Programmers experienced with object-oriented Perl should
+recognize C<$self> as a reference to the object where this method was
+called.  On the other hand, C<$c> will be new to many Perl programmers
+who have not used Catalyst before (it's sometimes written as
+C<$context>).  The Context object is automatically passed to all
+Catalyst components.  It is used to pass information between components
+and provide access to Catalyst and plugin functionality.
 
-B<TIP>: You may see the C<$c-E<gt>model('MyAppDB::Book')> used above written as C<$c-E<gt>model('MyAppDB')-E<gt>resultset('Book)>.  The two are equivalent.
+B<TIP>: You may see the C<$c-E<gt>model('MyAppDB::Book')> used above
+written as C<$c-E<gt>model('MyAppDB')-E<gt>resultset('Book)>.  The two
+are equivalent.
 
-B<Note:> Catalyst actions are regular Perl methods, but they make use of Nicholas Clark's C<attributes> module to provide additional information to the Catalyst dispatcher logic.
+B<Note:> Catalyst actions are regular Perl methods, but they make use of
+Nicholas Clark's C<attributes> module to provide additional information
+to the Catalyst dispatcher logic.
 
 
 =head1 CATALYST VIEWS
 
-Views are where you render output for display in the user's web browser (or possibly using other display technology).  As with virtually every aspect of Catalyst, options abound when it comes to the specific view technology you adopt inside your application.  However, most Catalyst applications use the Template Toolkit, known as TT (for more information on TT, see L<http://www.template-toolkit.org>).  Other popular View technologies include Mason (L<http://www.masonhq.com> and L<http://www.masonbook.com>) and L<HTML::Template|HTML::Template> (L<http://html-template.sourceforge.net>).
+Views are where you render output for display in the user's web browser
+(or possibly using other display technology).  As with virtually every
+aspect of Catalyst, options abound when it comes to the specific view
+technology you adopt inside your application.  However, most Catalyst
+applications use the Template Toolkit, known as TT (for more information
+on TT, see L<http://www.template-toolkit.org>).  Other popular View
+technologies include Mason (L<http://www.masonhq.com> and
+L<http://www.masonbook.com>) and L<HTML::Template|HTML::Template>
+(L<http://html-template.sourceforge.net>).
 
 
 =head2 Create a Catalyst View Using C<TTSITE>
@@ -566,21 +712,49 @@ L<Catalyst::Helper::View::TTSite|Catalyst::Helper::View::TTSite>
 
 =back
 
-Both are similar, but C<TT> merely creates the C<lib/MyApp/View/TT.pm> file and leaves the creation of any hierarchical template organization entirely up to you (it also creates a C<t/view_TT.t> file for testing; test cases will be discussed in Part 7).  Conversely, the C<TTSite> helper creates a modular and hierarchical view layout with separate Template Toolkit (TT) files for common header and footer information, configuration values, a CSS stylesheet, etc.
+Both are similar, but C<TT> merely creates the C<lib/MyApp/View/TT.pm>
+file and leaves the creation of any hierarchical template organization
+entirely up to you (it also creates a C<t/view_TT.t> file for testing;
+test cases will be discussed in Part 7).  Conversely, the C<TTSite>
+helper creates a modular and hierarchical view layout with separate
+Template Toolkit (TT) files for common header and footer information,
+configuration values, a CSS stylesheet, etc.
 
-Enter the following command to enable the C<TTSite> style of view rendering for the tutorial:
+Enter the following command to enable the C<TTSite> style of view
+rendering for the tutorial:
 
     $ script/myapp_create.pl view TT TTSite
 
-This puts a number of files in the C<root/lib> and C<root/src> directories that can be used to customize the look and feel of your application.  Also take a look at C<lib/MyApp/View/TT.pm> for config values set by the C<TTSite> helper.
-
-B<TIP>: Note that TTSite does one thing that could confuse people who are used to the normal C<TT> Catalyst View: it redefines the Catalyst context object in templates from its usual C<c> to C<Catalyst>.  Also keep this in mind when looking at other Catalyst examples (they almost always use C<c>).  Note that Catalyst and TT I<do not complain> when you use the wrong name to access the context... it simply outputs blanks for that bogus logic.  Finally, be aware that this change in name I<only> applies to how the context object is accessed inside your TT templates, your controllers will continue to use C<$c> (or whatever name you use when fetching the reference from C<@_> inside your methods).  (You can change back to the "default" behavior be removing the C<CATALYST_VAR> line from C<lib/MyApp/View/TT.pm>, but you will also have to edit C<root/lib/config/main> and C<root/lib/config/url>.  If you do this, be careful not to have a collision between your own C<c> variable and the Catalyst C<c> variable.)
+This puts a number of files in the C<root/lib> and C<root/src>
+directories that can be used to customize the look and feel of your
+application.  Also take a look at C<lib/MyApp/View/TT.pm> for config
+values set by the C<TTSite> helper.
+
+B<TIP>: Note that TTSite does one thing that could confuse people who
+are used to the normal C<TT> Catalyst View: it redefines the Catalyst
+context object in templates from its usual C<c> to C<Catalyst>.  Also
+keep this in mind when looking at other Catalyst examples (they almost
+always use C<c>).  Note that Catalyst and TT I<do not complain> when you
+use the wrong name to access the context... it simply outputs blanks for
+that bogus logic.  Finally, be aware that this change in name I<only>
+applies to how the context object is accessed inside your TT templates,
+your controllers will continue to use C<$c> (or whatever name you use
+when fetching the reference from C<@_> inside your methods).  (You can
+change back to the "default" behavior be removing the C<CATALYST_VAR>
+line from C<lib/MyApp/View/TT.pm>, but you will also have to edit
+C<root/lib/config/main> and C<root/lib/config/url>.  If you do this, be
+careful not to have a collision between your own C<c> variable and the
+Catalyst C<c> variable.)
 
 
 
 =head2 Globally Customize Every View
 
-When using TTSite, files in the subdirectories of C<root/lib> can be used to make changes that will appear in every view.  For example, to display optional status and error messages in every view, edit C<root/lib/site/layout> update it to match the following (the two HTML C<span> elements are new):
+When using TTSite, files in the subdirectories of C<root/lib> can be
+used to make changes that will appear in every view.  For example, to
+display optional status and error messages in every view, edit
+C<root/lib/site/layout> update it to match the following (the two HTML
+C<span> elements are new):
 
     <div id="header">[% PROCESS site/header %]</div>
     
@@ -592,14 +766,24 @@ When using TTSite, files in the subdirectories of C<root/lib> can be used to mak
     
     <div id="footer">[% PROCESS site/footer %]</div>
 
-If we set either message in the Catalyst stash (e.g., C<$c-E<gt>stash-E<gt>{status_msg} = 'Hello world'>) it will be displayed whenever any view used by that request is rendered.  The C<message> and C<error> CSS styles are automatically defined in C<root/src/ttsite.css> and can be customized to suit your needs.
+If we set either message in the Catalyst stash (e.g.,
+C<$c-E<gt>stash-E<gt>{status_msg} = 'Hello world'>) it will be displayed
+whenever any view used by that request is rendered.  The C<message> and
+C<error> CSS styles are automatically defined in C<root/src/ttsite.css>
+and can be customized to suit your needs.
 
-B<Note:> The Catalyst stash only lasts for a single HTTP request.  If you need to retain information across requests you can use L<Catalyst::Plugin::Session|Catalyst::Plugin::Session> (we will use Catalyst sessions in the Authentication part).
+B<Note:> The Catalyst stash only lasts for a single HTTP request.  If
+you need to retain information across requests you can use
+L<Catalyst::Plugin::Session|Catalyst::Plugin::Session> (we will use
+Catalyst sessions in the Authentication part).
 
 
 =head2 Create a TT Template Page
 
-To add a new page of content to the TTSite view hierarchy, just create a new C<.tt2> file in C<root/src>.  Only include HTML markup that goes inside the HTML <body> and </body> tags, TTSite will use the contents of C<root/lib/site> to add the top and bottom.
+To add a new page of content to the TTSite view hierarchy, just create a
+new C<.tt2> file in C<root/src>.  Only include HTML markup that goes
+inside the HTML <body> and </body> tags, TTSite will use the contents of
+C<root/lib/site> to add the top and bottom.
 
 First create a directory for book-related TT templates:
 
@@ -638,21 +822,48 @@ Then open C<root/src/books/list.tt2> in your editor and enter:
     [% END -%]
     </table>
 
-As indicated by the inline comments above, the C<META title> line uses TT's META feature to provide a title to C<root/lib/site/header>.  Meanwhile, the outer C<FOREACH> loop iterates through each C<book> model object and prints the C<title> and C<rating> fields.  An inner C<FOREACH> loop prints the last name of each author in a single table cell (a simple space is used between the names; in reality you would probably want to modify the code to use a comma as a separator).  
-
-If you are new to TT, the [% and %] tags are used to delimit "variable text".  TT supports a wide variety of directives for "calling" other files, looping, conditional logic, etc.  In general, TT simplifies the usual range of Perl operators down to the single dot (C<.>) operator.  This applies to operations as diverse as method calls, hash lookups, and list index values (see L<http://www.template-toolkit.org/docs/default/Manual/Variables.html> for details and examples).  In addition to the usual C<Template> module Pod documentation, you can access the TT manual at L<http://www.template-toolkit.org/docs/default/>.
-
-B<NOTE>: The C<TTSite> helper creates several TT files using an extension of C<.tt2>. Most other Catalyst and TT examples use an extension of C<.tt>.  You can use either extension (or no extension at all) with TTSite and TT, just be sure to use the appropriate extension for both the file itself I<and> the C<$c-E<gt>stash-E<gt>{template} = ...> line in your controller.  This document will use C<.tt2> for consistency with the files already created by the C<TTSite> helper.
+As indicated by the inline comments above, the C<META title> line uses
+TT's META feature to provide a title to C<root/lib/site/header>.
+Meanwhile, the outer C<FOREACH> loop iterates through each C<book> model
+object and prints the C<title> and C<rating> fields.  An inner
+C<FOREACH> loop prints the last name of each author in a single table
+cell (a simple space is used between the names; in reality you would
+probably want to modify the code to use a comma as a separator).
+
+If you are new to TT, the [% and %] tags are used to delimit "variable
+text".  TT supports a wide variety of directives for "calling" other
+files, looping, conditional logic, etc.  In general, TT simplifies the
+usual range of Perl operators down to the single dot (C<.>) operator.
+This applies to operations as diverse as method calls, hash lookups, and
+list index values (see
+L<http://www.template-toolkit.org/docs/default/Manual/Variables.html>
+for details and examples).  In addition to the usual C<Template> module
+Pod documentation, you can access the TT manual at
+L<http://www.template-toolkit.org/docs/default/>.
+
+B<NOTE>: The C<TTSite> helper creates several TT files using an
+extension of C<.tt2>. Most other Catalyst and TT examples use an
+extension of C<.tt>.  You can use either extension (or no extension at
+all) with TTSite and TT, just be sure to use the appropriate extension
+for both the file itself I<and> the C<$c-E<gt>stash-E<gt>{template} =
+...> line in your controller.  This document will use C<.tt2> for
+consistency with the files already created by the C<TTSite> helper.
 
 
 
 =head1 RUN THE APPLICATION
 
-First, let's enable an environment variable option that causes DBIx::Class to dump the SQL statements it's using to access the database (this option can provide extremely helpful troubleshooting information):
+First, let's enable an environment variable option that causes
+DBIx::Class to dump the SQL statements it's using to access the database
+(this option can provide extremely helpful troubleshooting information):
 
     $ export DBIX_CLASS_STORAGE_DBI_DEBUG=1
 
-B<NOTE>: You can also set this in your code using C<$class-E<gt>storage-E<gt>debug(1);>.  See L<DBIx::Class::Manual::Troubleshooting|DBIx::Class::Manual::Troubleshooting> for details (including options to log to file vs. the Catalyst development server log.
+B<NOTE>: You can also set this in your code using
+C<$class-E<gt>storage-E<gt>debug(1);>.  See
+L<DBIx::Class::Manual::Troubleshooting|DBIx::Class::Manual::Troubleshooting>
+for details (including options to log to file vs. the Catalyst
+development server log.
 
 Then run the Catalyst "demo server" script:    
 
@@ -712,32 +923,45 @@ Some things you should note in the output above:
 
 =item * 
 
-Catalyst::Model::DBIC::Schema took our C<MyAppDB::Book> and made it C<MyApp::Model::MyAppDB::Book> (and similar actions were performed on C<MyAppDB::Author> and C<MyAppDB::BookAuthor>).
+Catalyst::Model::DBIC::Schema took our C<MyAppDB::Book> and made it
+C<MyApp::Model::MyAppDB::Book> (and similar actions were performed on
+C<MyAppDB::Author> and C<MyAppDB::BookAuthor>).
 
 =item * 
 
-The "list" action in our Books controller showed up with a path of C</books/list>.
+The "list" action in our Books controller showed up with a path of
+C</books/list>.
 
 =back
 
 
-Point your browser to L<http://localhost:3000> and you should still get the Catalyst welcome page.
+Point your browser to L<http://localhost:3000> and you should still get
+the Catalyst welcome page.
 
-Next, to view the book list, change the URL in your browser to L<http://localhost:3000/books/list>. You should get a list of the five books loaded by the C<myapp01.sql> script above, with TTSite providing the formatting for the very simple output we generated in our template.  The count and space-separated list of author last names appear on the end of each row.
+Next, to view the book list, change the URL in your browser to
+L<http://localhost:3000/books/list>. You should get a list of the five
+books loaded by the C<myapp01.sql> script above, with TTSite providing
+the formatting for the very simple output we generated in our template.
+The count and space-separated list of author last names appear on the
+end of each row.
 
-Also notice in the output of the C<script/myapp_server.pl> that DBIC used the following SQL to retrieve the data:
+Also notice in the output of the C<script/myapp_server.pl> that DBIC
+used the following SQL to retrieve the data:
 
     SELECT me.id, me.title, me.rating FROM books me
 
-Along with a list of the following commands to retrieve the authors for each book (the lines have been "word wrapped" here to improve legibility):
+Along with a list of the following commands to retrieve the authors for
+each book (the lines have been "word wrapped" here to improve
+legibility):
 
     SELECT author.id, author.first_name, author.last_name 
         FROM book_authors me  
         JOIN authors author ON ( author.id = me.author_id ) 
         WHERE ( me.book_id = ? ): `1'
 
-You should see 10 such lines of debug output, two for each of the five author_id values (it pulls the data once for the count logic and another time to actually display the list).
-
+You should see 10 such lines of debug output, two for each of the five
+author_id values (it pulls the data once for the count logic and another
+time to actually display the list).
 
 
 =head1 AUTHOR
index 59791b4..d65f842 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-Catalyst::Manual::Tutorial::Debugging - Catalyst Tutorial – Part 6: Debugging
+Catalyst::Manual::Tutorial::Debugging - Catalyst Tutorial - Part 6: Debugging
 
 
 
@@ -8,7 +8,7 @@ Catalyst::Manual::Tutorial::Debugging - Catalyst Tutorial 
 
 This is B<Part 6 of 9> for the Catalyst tutorial.
 
-L<Totorial Overview|Catalyst::Manual::Tutorial>
+L<Tutorial Overview|Catalyst::Manual::Tutorial>
 
 =over 4
 
@@ -22,7 +22,7 @@ L<Catalyst Basics|Catalyst::Manual::Tutorial::CatalystBasics>
 
 =item 3
 
-L<Basic CRUD|Catalyst::Manual::Tutorial03_BasicCRUD>
+L<Basic CRUD|Catalyst::Manual::Tutorial_BasicCRUD>
 
 =item 4
 
@@ -54,7 +54,8 @@ L<Appendicies|Catalyst::Manual::Tutorial::Appendicies>
 
 =head1 DESCRIPTION
 
-This part of the tutorial takes a brief look at the primary options available for troubleshooting Catalyst applications.
+This part of the tutorial takes a brief look at the primary options
+available for troubleshooting Catalyst applications.
 
 Note that when it comes to debugging and troubleshooting, there are two camps:
 
@@ -76,22 +77,33 @@ Catalyst is able to easily accommodate both styles of debugging.
 
 =head1 LOG STATEMENTS
 
-Folks in the former group can use Catalyst's C<$c-E<gt>log> facility.  For example, if you add the following code to a controller action method:
+Folks in the former group can use Catalyst's C<$c-E<gt>log> facility.
+For example, if you add the following code to a controller action
+method:
 
     $c->log->debug("This is a test log message");
 
-Then the Catalyst development server will display your message along with the other debug output.  To accomplish the same thing in a TTSite view use:
+Then the Catalyst development server will display your message along
+with the other debug output.  To accomplish the same thing in a TTSite
+view use:
 
     [% Catalyst.log.debug("This is a test log message") %]
 
-You can also use L<Data::Dumper|Data::Dumper> in both Catalyst code 
-(C<$c-E<gt>log-E<gt>dumper($myvar)>) and TT templates (C<[% Dumper.dump(book) %]> as discussed in earlier parts of the tutorial.
+You can also use L<Data::Dumper|Data::Dumper> in both Catalyst code
+(C<$c-E<gt>log-E<gt>dumper($myvar)>) and TT templates (C<[%
+Dumper.dump(book) %]> as discussed in earlier parts of the tutorial.
 
 
 
 =head1 RUNNING CATALYST UNDER THE PERL DEBUGGER
 
-Members of the interactive debuggers fan club will also be at home with Catalyst applications.  One approach to this style of Perl debugging is to embed breakpoints in your code.  For example, open C<lib/MyApp/Controller/Books.pm> in your editor and add the C<DB::single=1> line as follows inside the C<list> method (I like to "left-justify" my debug statements so I don't forget to remove them, but you can obviously indent them if you prefer):
+Members of the interactive debuggers fan club will also be at home with
+Catalyst applications.  One approach to this style of Perl debugging is
+to embed breakpoints in your code.  For example, open
+C<lib/MyApp/Controller/Books.pm> in your editor and add the
+C<DB::single=1> line as follows inside the C<list> method (I like to
+"left-justify" my debug statements so I don't forget to remove them, but
+you can obviously indent them if you prefer):
 
     sub list : Local {
         # Retrieve the usual perl OO '$self' for this object. $c is the Catalyst
@@ -131,16 +143,25 @@ This will start the interactive debugger and produce output similar to:
     
       DB<1> 
 
-Press the C<c> key and hit C<Enter> to continue executing the Catalyst development server under the debugger.  Although execution speed will be slightly slower than normal, you should soon see the usual Catalyst startup debug information.
+Press the C<c> key and hit C<Enter> to continue executing the Catalyst
+development server under the debugger.  Although execution speed will be
+slightly slower than normal, you should soon see the usual Catalyst
+startup debug information.
 
-Now point your browser to L<http://localhost:3000/books/list> and log in.  Once the breakpoint is encountered in the C<MyApp::Controller::list> method, the console session running the development server will drop to the Perl debugger prompt:
+Now point your browser to L<http://localhost:3000/books/list> and log
+in.  Once the breakpoint is encountered in the
+C<MyApp::Controller::list> method, the console session running the
+development server will drop to the Perl debugger prompt:
 
     MyApp::Controller::Books::list(/home/me/MyApp/script/../lib/MyApp/Controller/Books.pm:40):
     40:         $c->stash->{books} = [$c->model('MyAppDB::Book')->all];
     
       DB<1>
 
-You now have the full Perl debugger at your disposal.  First use the C<next> feature by typing C<n> to execute the C<all> method on the Book model (C<n> jumps over method/subroutine calls; you can also use C<s> to C<single-step> into methods/subroutines):
+You now have the full Perl debugger at your disposal.  First use the
+C<next> feature by typing C<n> to execute the C<all> method on the Book
+model (C<n> jumps over method/subroutine calls; you can also use C<s> to
+C<single-step> into methods/subroutines):
 
       DB<1> n
     SELECT me.id, me.authors, me.title, me.rating FROM books me:
@@ -149,7 +170,10 @@ You now have the full Perl debugger at your disposal.  First use the C<next> fea
     
       DB<1>
 
-This takes you to the next line of code where the template name is set.  Notice that because we enabled C<DBIX_CLASS_STORAGE_DBI_DEBUG=1> earlier, SQL debug output also shows up in the development server debug output.
+This takes you to the next line of code where the template name is set.
+Notice that because we enabled C<DBIX_CLASS_STORAGE_DBI_DEBUG=1>
+earlier, SQL debug output also shows up in the development server debug
+output.
 
 Next, list the methods available on our C<Book> model:
 
@@ -178,7 +202,8 @@ We can also play with the model directly:
 
 This uses the Perl debugger C<x> command to display the title of a book.
 
-Next we inspect the C<books> element of the Catalyst C<stash> (the C<4> argument to the C<x> command limits the depth of the dump to 4 levels):
+Next we inspect the C<books> element of the Catalyst C<stash> (the C<4>
+argument to the C<x> command limits the depth of the dump to 4 levels):
 
       DB<3> x 4 $c->stash->{books}
     0  ARRAY(0xa8f3b7c)
@@ -190,17 +215,23 @@ Next we inspect the C<books> element of the Catalyst C<stash> (the C<4> argument
           '_in_storage' => 1
     <lines removed for brevity>
 
-Then enter the C<c> command to continue processing until the next breakpoint is hit (or the application exits):
+Then enter the C<c> command to continue processing until the next
+breakpoint is hit (or the application exits):
 
       DB<4> c
     SELECT author.id, author.first_name, author.last_name FROM ...
 
-Finally, press C<Ctrl+C> to break out of the development server.  Because we are running inside the Perl debugger, you will drop to the debugger prompt.  Press C<q> to exit the debugger and return to your OS shell prompt:
+Finally, press C<Ctrl+C> to break out of the development server.
+Because we are running inside the Perl debugger, you will drop to the
+debugger prompt.  Press C<q> to exit the debugger and return to your OS
+shell prompt:
 
       DB<4> q
     $
 
-For more information on using the Perl debugger, please see C<perldebug> and C<perldebtut>.  You can also type C<h> or C<h h> at the debugger prompt to view the built-in help screens.
+For more information on using the Perl debugger, please see C<perldebug>
+and C<perldebtut>.  You can also type C<h> or C<h h> at the debugger
+prompt to view the built-in help screens.
 
 
 
@@ -210,9 +241,7 @@ Kennedy Clark, C<hkclark@gmail.com>
 
 Please report any errors, issues or suggestions to the author.
 
-Copyright 2006, Kennedy Clark. All rights reserved.
-
-This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
+Copyright 2006, Kennedy Clark, under Creative Commons License (L<http://creativecommons.org/licenses/by-nc-sa/2.5/>).
 
 Version: .94
 
index 881a017..aace01d 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-Catalyst::Manual::Tutorial::Intro - Catalyst Tutorial – Part 1: Introduction
+Catalyst::Manual::Tutorial::Intro - Catalyst Tutorial - Part 1: Introduction
 
 
 
@@ -8,7 +8,7 @@ Catalyst::Manual::Tutorial::Intro - Catalyst Tutorial 
 
 This is B<Part 1 of 9> for the Catalyst tutorial.
 
-L<Totorial Overview|Catalyst::Manual::Tutorial>
+L<Tutorial Overview|Catalyst::Manual::Tutorial>
 
 =over 4
 
@@ -22,7 +22,7 @@ L<Catalyst Basics|Catalyst::Manual::Tutorial::CatalystBasics>
 
 =item 3
 
-L<Basic CRUD|Catalyst::Manual::Tutorial03_BasicCRUD>
+L<Basic CRUD|Catalyst::Manual::Tutorial_BasicCRUD>
 
 =item 4
 
@@ -54,9 +54,15 @@ L<Appendicies|Catalyst::Manual::Tutorial::Appendicies>
 
 =head1 DESCRIPTION
 
-This tutorial provides a nine-part introduction to the Catalyst web framework.  It seeks to provide a rapid overview of many of its most commonly used features.  The focus is on the real-world best practices required in the construction of nearly all Catalyst applications.
+This tutorial provides a nine-part introduction to the Catalyst web
+framework.  It seeks to provide a rapid overview of many of its most
+commonly used features.  The focus is on the real-world best practices
+required in the construction of nearly all Catalyst applications.
 
-Although the primary target of the tutorial is users new to the Catalyst framework, experienced users may wish to review specific sections (for example, how to use DBIC for their model classes or how to add authentication and authorization to an existing application).
+Although the primary target of the tutorial is users new to the Catalyst
+framework, experienced users may wish to review specific sections (for
+example, how to use DBIC for their model classes or how to add
+authentication and authorization to an existing application).
 
 Subjects covered include:
 
@@ -84,7 +90,10 @@ Role-based authorization ("authz").
 
 =item * 
 
-Attempts to provide an example showing current Catalyst 5.70 practices. For example, the use of C<Catalyst::Plugin::DefaultEnd>, DBIC, C<Catalyst::Plugin::ConfigLoader> with myapp.yml, the use of C<lib/MyApp/Controller/Root.pm> vs. C<lib/MyApp.pm>, etc.
+Attempts to provide an example showing current Catalyst 5.70
+practices. For example, the use of C<Catalyst::Plugin::DefaultEnd>,
+DBIC, C<Catalyst::Plugin::ConfigLoader> with myapp.yml, the use of
+C<lib/MyApp/Controller/Root.pm> vs. C<lib/MyApp.pm>, etc.
 
 =item * 
 
@@ -104,17 +113,35 @@ How to use HTML::Widget for automated form processing and validation.
 
 =back
 
-This tutorial intentionally seeks to make the learning process its main priority.  For example, the level of comments in the code found here would like be considered excessive in a "normal project".  Because of their contextual value, this tutorial will generally favor inline comments over a separate discussion in the text.  It also deliberately tries to demonstrate multiple approaches to various features (in general, you should try to be as consistent as possible with your own production code).
+This tutorial intentionally seeks to make the learning process its main
+priority.  For example, the level of comments in the code found here
+would like be considered excessive in a "normal project".  Because of
+their contextual value, this tutorial will generally favor inline
+comments over a separate discussion in the text.  It also deliberately
+tries to demonstrate multiple approaches to various features (in
+general, you should try to be as consistent as possible with your own
+production code).
 
-Furthermore, this tutorial tries to minimize the number of controllers, models, TT templates, and database tables.  Although this does result in things being a bit contrived at times, the concepts should be applicable to more complex environments.  More complete and complicated example applications can be found in the C<examples> area of the Catalyst Subversion repository at L<http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/>.
+Furthermore, this tutorial tries to minimize the number of controllers,
+models, TT templates, and database tables.  Although this does result in
+things being a bit contrived at times, the concepts should be applicable
+to more complex environments.  More complete and complicated example
+applications can be found in the C<examples> area of the Catalyst
+Subversion repository at
+L<http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/>.
 
-B<Note:> There are a variety of other introductory materials available through the Catalyst web site and at L<http://dev.catalyst.perl.org/wiki/UserIntroductions> and L<http://dev.catalyst.perl.org/>.
+B<Note:> There are a variety of other introductory materials available
+through the Catalyst web site and at
+L<http://dev.catalyst.perl.org/wiki/UserIntroductions> and
+L<http://dev.catalyst.perl.org/>.
 
 
 
 =head1 VERSIONS AND CONVENTIONS USED IN THIS TUTORIAL
 
-This tutorial was built using the following resources.  Please note that you will need to make adjustments for different environments and versions:
+This tutorial was built using the following resources.  Please note that
+you will need to make adjustments for different environments and
+versions:
 
 =over 4
 
@@ -134,7 +161,9 @@ DBIx::Class v0.06002
 
 Catalyst Plugins
 
-You shouldn't be overly concerned about plugin version numbers, but there could be cases where the tutorial is impacted by what version plugins you use.  The plugins used in this tutorial are:
+You shouldn't be overly concerned about plugin version numbers, but
+there could be cases where the tutorial is impacted by what version
+plugins you use.  The plugins used in this tutorial are:
 
 =over 4
 
@@ -202,11 +231,21 @@ Catalyst::Plugin::Static::Simple -- 0.14
 
 =item * 
 
-Since the web browser is being used on the same box where Perl and the Catalyst development server is running, the URL of C<http://localhost:3000> will be used (the Catalyst development server defaults to port 3000).  If you are running Perl on a different box than where your web browser is located (or using a different port number via the C<-p> I<port_number> option to the development server), then you will need to update the URL you use accordingly.
+Since the web browser is being used on the same box where Perl and the
+Catalyst development server is running, the URL of
+C<http://localhost:3000> will be used (the Catalyst development server
+defaults to port 3000).  If you are running Perl on a different box than
+where your web browser is located (or using a different port number via
+the C<-p> I<port_number> option to the development server), then you
+will need to update the URL you use accordingly.
 
 =item * 
 
-Depending on the web browser you are using, you might need to hit C<Shift+Reload> to pull a fresh page when testing your application at various points.  Also, the C<-k> keepalive option to the development server can be necessary with some browsers (especially Internet Explorer).
+Depending on the web browser you are using, you might need to hit
+C<Shift+Reload> to pull a fresh page when testing your application at
+various points.  Also, the C<-k> keepalive option to the development
+server can be necessary with some browsers (especially Internet
+Explorer).
 
 =back
 
@@ -214,48 +253,81 @@ Depending on the web browser you are using, you might need to hit C<Shift+Reload
 
 =head1 CATALYST INSTALLATION
 
-Unfortunately, one of the most daunting tasks faced by newcomers to Catalyst is getting it installed.  Although a compelling strength of Catalyst is that it can easily make full use of CPAN, a vast repository of Perl modules, this can result in initial installations that are both time consuming and frustrating.  However, there are a growing number of methods that can dramatically ease this undertaking.  Of these, the following are likely to be applicable to the largest number of potential new users:
+Unfortunately, one of the most daunting tasks faced by newcomers to
+Catalyst is getting it installed.  Although a compelling strength of
+Catalyst is that it can easily make full use of CPAN, a vast repository
+of Perl modules, this can result in initial installations that are both
+time consuming and frustrating.  However, there are a growing number of
+methods that can dramatically ease this undertaking.  Of these, the
+following are likely to be applicable to the largest number of potential
+new users:
 
 =over 4
 
 =item * 
 
-Matt Trout’s C<cat-install>
+Matt Trout's C<cat-install>
 
-Available at L<http://www.shadowcatsystems.co.uk/static/cat-install>, C<cat-install> can be a quick and painless way to get Catalyst up and running.  Just download the script from the link above and type C<perl cat-install>.
+Available at L<http://www.shadowcatsystems.co.uk/static/cat-install>,
+C<cat-install> can be a quick and painless way to get Catalyst up and
+running.  Just download the script from the link above and type C<perl
+cat-install>.
 
 =item * 
 
 Chris Laco's CatInABox
 
-Download the tarball from L<http://handelframework.com/downloads/CatInABox.tar.gz> and unpack it on your machine.  Depending on your OS platform, either run C<start.bat> or C<start.sh>.
+Download the tarball from
+L<http://handelframework.com/downloads/CatInABox.tar.gz> and unpack it
+on your machine.  Depending on your OS platform, either run C<start.bat>
+or C<start.sh>.
 
 =item * 
 
 Pre-Built VMWare Images
 
-Under the VMWare community program, work is ongoing to develop a number of VMWare images where an entire Catalyst development environment has already been installed, complete with database engines and a full complement of Catalyst plugins.
+Under the VMWare community program, work is ongoing to develop a number
+of VMWare images where an entire Catalyst development environment has
+already been installed, complete with database engines and a full
+complement of Catalyst plugins.
 
 =back
 
-B<IMPORTANT:> For additional information and recommendations on Catalyst installation, please refer to L<Catalyst::Manual::Installation|Catalyst::Manual::Installation>.
+B<IMPORTANT:> For additional information and recommendations on Catalyst
+installation, please refer to
+L<Catalyst::Manual::Installation|Catalyst::Manual::Installation>.
 
-B<IMPORTANT:> Step-by-step instructions to replicate the environment on which this tutorial was developed can be found at L<Catalyst::Manual::Installation::CentOSTuorial|Catalyst::Manual::Installation::CentOSTuorial>.  Using these instructions, you should be able to build a complete CentOS 4.X server with Catalyst and all the plugins required to run this tutorial.
+B<IMPORTANT:> Step-by-step instructions to replicate the environment on
+which this tutorial was developed can be found at
+L<Catalyst::Manual::Installation::CentOSTuorial|Catalyst::Manual::Installation::CentOSTuorial>.
+
+Using these instructions, you should be able to build a complete CentOS
+4.X server with Catalyst and all the plugins required to run this
+tutorial.
 
 
 
 =head1 DATABASES
 
-This tutorial will primarily focus on SQLite because of its simplicity; however, modifications in the script required to support MySQL and PostgreSQL will be presented in Appendix 2.
+This tutorial will primarily focus on SQLite because of its simplicity;
+however, modifications in the script required to support MySQL and
+PostgreSQL will be presented in Appendix 2.
 
-B<Note:> One of the advantages of the MVC design patterns is that applications become much more database independent.  As such, you will notice that only the C<.sql> files used to initialize the database change between database systems... the Catalyst code generally remains the same.
+B<Note:> One of the advantages of the MVC design patterns is that
+applications become much more database independent.  As such, you will
+notice that only the C<.sql> files used to initialize the database
+change between database systems... the Catalyst code generally remains
+the same.
 
 
 
 =head1 WHERE TO GET WORKING CODE
 
-Each part of the tutorial has complete code available in the main Catalyst Subversion repository (see the note at the beginning of each part for the appropriate svn command to use).  Additionally, the final code is available as a ready-to-run tarball at TO_BE_ADDED_TO_FINAL_VERSION.
-
+Each part of the tutorial has complete code available in the main
+Catalyst Subversion repository (see the note at the beginning of each
+part for the appropriate svn command to use).  Additionally, the final
+code is available as a ready-to-run tarball at
+TO_BE_ADDED_TO_FINAL_VERSION.
 
 
 =head1 AUTHOR
@@ -264,7 +336,8 @@ Kennedy Clark, C<hkclark@gmail.com>
 
 Please report any errors, issues or suggestions to the author.
 
-Copyright 2006, Kennedy Clark, under Creative Commons License (L<http://creativecommons.org/licenses/by-nc-sa/2.5/>).
+Copyright 2006, Kennedy Clark, under Creative Commons License
+(L<http://creativecommons.org/licenses/by-nc-sa/2.5/>).
 
 Version: .94
 
index 0e81fdb..c8ea930 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-Catalyst::Manual::Tutorial::Testing - Catalyst Tutorial – Part 7: Testing
+Catalyst::Manual::Tutorial::Testing - Catalyst Tutorial - Part 7: Testing
 
 
 
@@ -8,7 +8,7 @@ Catalyst::Manual::Tutorial::Testing - Catalyst Tutorial 
 
 This is B<Part 7 of 9> for the Catalyst tutorial.
 
-L<Totorial Overview|Catalyst::Manual::Tutorial>
+L<Tutorial Overview|Catalyst::Manual::Tutorial>
 
 =over 4
 
@@ -22,7 +22,7 @@ L<Catalyst Basics|Catalyst::Manual::Tutorial::CatalystBasics>
 
 =item 3
 
-L<Basic CRUD|Catalyst::Manual::Tutorial03_BasicCRUD>
+L<Basic CRUD|Catalyst::Manual::Tutorial_BasicCRUD>
 
 =item 4
 
@@ -55,9 +55,16 @@ L<Appendicies|Catalyst::Manual::Tutorial::Appendicies>
 =head1 DESCRIPTION
 
 
-You may have noticed that the Catalyst Helper scripts automatically create C<.t> test scripts under the C<t> directory.  This part of the tutorial briefly looks at how these tests can be used to not only ensure that your application is working correctly at the present time, but also provide automated regression testing as you upgrade various pieces of your application over time.
+You may have noticed that the Catalyst Helper scripts automatically
+create C<.t> test scripts under the C<t> directory.  This part of the
+tutorial briefly looks at how these tests can be used to not only ensure
+that your application is working correctly at the present time, but also
+provide automated regression testing as you upgrade various pieces of
+your application over time.
 
-B<TIP>: Note that all of the code for this part of the tutorial can be pulled from the Catalyst Subversion repository in one step with the following command:
+B<TIP>: Note that all of the code for this part of the tutorial can be
+pulled from the Catalyst Subversion repository in one step with the
+following command:
 
     svn checkout http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/Tutorial@###
     IMPORTANT: Does not work yet.  Will be completed for final version.
@@ -66,11 +73,16 @@ B<TIP>: Note that all of the code for this part of the tutorial can be pulled fr
 
 =head1 RUNNING THE "CANNED" CATALYST TESTS
 
-There are a variety of ways to run Catalyst and Perl tests (for example, C<perl Makefile.PL> and C<make test>, but one of the easiest is with the C<prove> command.  For example, to run all of the tests in the C<t> directory, enter:
+There are a variety of ways to run Catalyst and Perl tests (for example,
+C<perl Makefile.PL> and C<make test>, but one of the easiest is with the
+C<prove> command.  For example, to run all of the tests in the C<t>
+directory, enter:
 
     $ prove --lib lib t
 
-The redirection used by the Authentication plugins will cause the default C<t/01app.t> to fail.  You can fix this by changing the line in C<t/01app.t> that read:
+The redirection used by the Authentication plugins will cause the
+default C<t/01app.t> to fail.  You can fix this by changing the line in
+C<t/01app.t> that read:
 
     ok( request('/')->is_success, 'Request should succeed' );
 
@@ -78,22 +90,37 @@ to:
 
     ok( request('/login')->is_success, 'Request should succeed' );
 
-So that a redirect is not necessary.  Also, the C<t/controller_Books.t> and C<t/controller_Logout.t> default test cases will fail because of the authorization.  You can delete these two files to prevent false error messages:
+So that a redirect is not necessary.  Also, the C<t/controller_Books.t>
+and C<t/controller_Logout.t> default test cases will fail because of the
+authorization.  You can delete these two files to prevent false error
+messages:
 
     $ rm t/controller_Books.t
     $ rm t/controller_Logout.t
 
-As you can see in the C<prove> command line above, the C<--lib> option is used to set the location of the Catalyst C<lib> directory.  With this command, you will get all of the usual development server debug output, something most people prefer to disable while running tests cases.  Although you can edit the C<lib/MyApp.pm> to comment out the C<-Debug> plugin, it's generally easier to simply set the C<CATALYST_DEBUG=0> environment variable.  For example:
+As you can see in the C<prove> command line above, the C<--lib> option
+is used to set the location of the Catalyst C<lib> directory.  With this
+command, you will get all of the usual development server debug output,
+something most people prefer to disable while running tests cases.
+Although you can edit the C<lib/MyApp.pm> to comment out the C<-Debug>
+plugin, it's generally easier to simply set the C<CATALYST_DEBUG=0>
+environment variable.  For example:
 
     CATALYST_DEBUG=0 prove --lib lib t
 
-During the C<t/02pod> and C<t/03podcoverage> tests, you might notice the C<all skipped: set TEST_POD to enable this test> warning message.  To execute the Pod-related tests, add C<TEST_POD=1> to the C<prove> command:
+During the C<t/02pod> and C<t/03podcoverage> tests, you might notice the
+C<all skipped: set TEST_POD to enable this test> warning message.  To
+execute the Pod-related tests, add C<TEST_POD=1> to the C<prove>
+command:
 
     $ CATALYST_DEBUG=0 TEST_POD=1 prove --lib lib t
 
-If you omitted the Pod comments from any of the methods that were inserted, you might have to go back and fix them to get these tests to pass. :-)
+If you omitted the Pod comments from any of the methods that were
+inserted, you might have to go back and fix them to get these tests to
+pass. :-)
 
-Another useful option is the C<verbose> (C<-v>) option to C<prove>.  It prints the name of each test case as it is being run:
+Another useful option is the C<verbose> (C<-v>) option to C<prove>.  It
+prints the name of each test case as it is being run:
 
     $ CATALYST_DEBUG=0 TEST_POD=1 prove --lib lib -v t
 
@@ -101,20 +128,32 @@ Another useful option is the C<verbose> (C<-v>) option to C<prove>.  It prints t
 
 =head1 RUNNING A SINGLE TEST
 
-You can also run a single script by appending its name to the C<prove> command. For example:
+You can also run a single script by appending its name to the C<prove>
+command. For example:
 
     $ CATALYST_DEBUG=0 prove --lib lib t/01app.t
 
-Note that you can also run tests directly from Perl without C<prove>.  For example:
+Note that you can also run tests directly from Perl without C<prove>.
+For example:
 
     $ CATALYST_DEBUG=0 perl -Ilib t/01app.t
 
 
 =head1 ADDING YOUR OWN TEST SCRIPT
 
-Although the Catalyst helper scripts provide a basic level of checks "for free," testing can become significantly more helpful when you write your own script to exercise the various parts of your application.  The L<Test::WWW::Mechanize::Catalyst|Test::WWW::Mechanize::Catalyst> module is very popular for writing these sorts of test cases.  This module extends L<Test::WWW::Mechanize|Test::WWW::Mechanize> (and therefore L<WWW::Mechanize|WWW::Mechanize>) to allow you to automate the action of a user "clicking around" inside your application.  It gives you all the benefits of testing on a live system without the messiness of having to use an actual web server.
+Although the Catalyst helper scripts provide a basic level of checks
+"for free," testing can become significantly more helpful when you write
+your own script to exercise the various parts of your application.  The
+L<Test::WWW::Mechanize::Catalyst|Test::WWW::Mechanize::Catalyst> module
+is very popular for writing these sorts of test cases.  This module
+extends L<Test::WWW::Mechanize|Test::WWW::Mechanize> (and therefore
+L<WWW::Mechanize|WWW::Mechanize>) to allow you to automate the action of
+a user "clicking around" inside your application.  It gives you all the
+benefits of testing on a live system without the messiness of having to
+use an actual web server.
 
-To create a sample test case, open the C<t/live_app01.t> file in your editor and enter the following:
+To create a sample test case, open the C<t/live_app01.t> file in your
+editor and enter the following:
 
     #!/usr/bin/perl
     
@@ -208,11 +247,21 @@ To create a sample test case, open the C<t/live_app01.t> file in your editor and
     $ua2->get_ok("http://localhost/books/url_create/TestTitle2/2/5", "'test02' add");
     $ua2->content_contains("Unauthorized!", "Check 'test02' cannot add");
 
-The C<live_app.t> test cases uses copious comments to explain each step of the process.  In addition to the techniques shown here, there are a variety of other methods available in L<Test::WWW::Mechanize::Catalyst|Test::WWW::Mechanize::Catalyst> (for example, regex-based matching).  Consult the documentation for more detail.
+The C<live_app.t> test cases uses copious comments to explain each step
+of the process.  In addition to the techniques shown here, there are a
+variety of other methods available in
+L<Test::WWW::Mechanize::Catalyst|Test::WWW::Mechanize::Catalyst> (for
+example, regex-based matching).  Consult the documentation for more
+detail.
 
-B<TIP>: For I<unit tests> vs. the "full application tests" approach used by L<Test::WWW::Mechanize::Catalyst|Test::WWW::Mechanize::Catalyst>, see L<Catalyst::Test|Catalyst::Test>.
+B<TIP>: For I<unit tests> vs. the "full application tests" approach used
+by L<Test::WWW::Mechanize::Catalyst|Test::WWW::Mechanize::Catalyst>, see
+L<Catalyst::Test|Catalyst::Test>.
 
-B<Note:> The test script does not test the C<form_create> and C<form_create_do> actions.  That is left as an exercise for the reader (you should be able to complete that logic using the existing code as a template).
+B<Note:> The test script does not test the C<form_create> and
+C<form_create_do> actions.  That is left as an exercise for the reader
+(you should be able to complete that logic using the existing code as a
+template).
 
 To run the new test script, use a command such as:
 
@@ -222,19 +271,33 @@ or
 
     $ DBIX_CLASS_STORAGE_DBI_DEBUG=0 CATALYST_DEBUG=0 prove --lib lib -v t/live_app01.t
 
-Experiment with the C<DBIX_CLASS_STORAGE_DBI_DEBUG>, C<CATALYST_DEBUG> and C<-v> settings.  If you find that there are errors, use the techniques discussed in the "Catalyst Debugging" section (Part 6) to isolate and fix the problem.
+Experiment with the C<DBIX_CLASS_STORAGE_DBI_DEBUG>, C<CATALYST_DEBUG>
+and C<-v> settings.  If you find that there are errors, use the
+techniques discussed in the "Catalyst Debugging" section (Part 6) to
+isolate and fix the problem.
 
-If you want to run the test case under the Perl interactive debugger, try a command such as:
+If you want to run the test case under the Perl interactive debugger,
+try a command such as:
 
     $ DBIX_CLASS_STORAGE_DBI_DEBUG=0 CATALYST_DEBUG=0 perl -d -Ilib t/live_app01.t
 
-Note that although the tutorial uses a single custom test case for simplicity, you may wish to break your tests into different files for better organization.
+Note that although the tutorial uses a single custom test case for
+simplicity, you may wish to break your tests into different files for
+better organization.
 
 
 
 =head1 SUPPORTING BOTH PRODUCTION AND TEST DATABASES
 
-You may wish to leverage the techniques discussed in this tutorial to maintain both a "production database" for your live application and a "testing database" for your test cases.  One advantage to L<Test::WWW::Mechanize::Catalyst|Test::WWW::Mechanize::Catalyst> is that it runs your full application; however, this can complicate things when you want to support multiple databases.  One solution is to allow the database specification to be overridden with an environment variable.  For example, open C<lib/MyApp/Model/MyAppDB.pm> in your editor and change the C<__PACKAGE__-E<gt>config(...> declaration to resemble:
+You may wish to leverage the techniques discussed in this tutorial to
+maintain both a "production database" for your live application and a
+"testing database" for your test cases.  One advantage to
+L<Test::WWW::Mechanize::Catalyst|Test::WWW::Mechanize::Catalyst> is that
+it runs your full application; however, this can complicate things when
+you want to support multiple databases.  One solution is to allow the
+database specification to be overridden with an environment variable.
+For example, open C<lib/MyApp/Model/MyAppDB.pm> in your editor and
+change the C<__PACKAGE__-E<gt>config(...> declaration to resemble:
 
     my $dsn = $ENV{MYAPP_DSN} ||= 'dbi:SQLite:myapp.db';
     __PACKAGE__->config(
@@ -253,7 +316,10 @@ Then, when you run your test case, you can use commands such as:
     $ cp myapp.db myappTEST.db
     $ CATALYST_DEBUG=0 MYAPP_DSN="dbi:SQLite:myappTEST.db" prove --lib lib -v t/live_app01.t
 
-This will modify the DSN only while the test case is running.  If you launch your normal application without the C<MYAPP_DSN> environment variable defined, it will default to the same C<dbi:SQLite:myapp.db> as before.
+This will modify the DSN only while the test case is running.  If you
+launch your normal application without the C<MYAPP_DSN> environment
+variable defined, it will default to the same C<dbi:SQLite:myapp.db> as
+before.
 
 
 
@@ -263,9 +329,8 @@ Kennedy Clark, C<hkclark@gmail.com>
 
 Please report any errors, issues or suggestions to the author.
 
-Copyright 2006, Kennedy Clark. All rights reserved.
-
-This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
+Copyright 2006, Kennedy Clark, under Creative Commons License
+(L<http://creativecommons.org/licenses/by-nc-sa/2.5/>).
 
 Version: .94