Add numbers back to names of chapters
[catagits/Catalyst-Manual.git] / lib / Catalyst / Manual / Tutorial / MoreCatalystBasics.pod
diff --git a/lib/Catalyst/Manual/Tutorial/MoreCatalystBasics.pod b/lib/Catalyst/Manual/Tutorial/MoreCatalystBasics.pod
deleted file mode 100644 (file)
index 7e54dcb..0000000
+++ /dev/null
@@ -1,1498 +0,0 @@
-=head1 NAME
-
-Catalyst::Manual::Tutorial::MoreCatalystBasics - Catalyst Tutorial - Chapter 3: More Catalyst Application Development Basics
-
-
-=head1 OVERVIEW
-
-This is B<Chapter 3 of 10> for the Catalyst tutorial.
-
-L<Tutorial Overview|Catalyst::Manual::Tutorial>
-
-=over 4
-
-=item 1
-
-L<Introduction|Catalyst::Manual::Tutorial::Intro>
-
-=item 2
-
-L<Catalyst Basics|Catalyst::Manual::Tutorial::CatalystBasics>
-
-=item 3
-
-B<More Catalyst Basics>
-
-=item 4
-
-L<Basic CRUD|Catalyst::Manual::Tutorial::BasicCRUD>
-
-=item 5
-
-L<Authentication|Catalyst::Manual::Tutorial::Authentication>
-
-=item 6
-
-L<Authorization|Catalyst::Manual::Tutorial::Authorization>
-
-=item 7
-
-L<Debugging|Catalyst::Manual::Tutorial::Debugging>
-
-=item 8
-
-L<Testing|Catalyst::Manual::Tutorial::Testing>
-
-=item 9
-
-L<Advanced CRUD|Catalyst::Manual::Tutorial::AdvancedCRUD>
-
-=item 10
-
-L<Appendices|Catalyst::Manual::Tutorial::Appendices>
-
-=back
-
-
-=head1 DESCRIPTION
-
-This chapter of the tutorial builds on the work done in Chapter 2 to 
-explore some features that are more typical of "real world" web 
-applications. From this chapter of the tutorial onward, we will be 
-building a simple book database application.  Although the application 
-will be too limited to be of use to anyone, it should provide a basic 
-environment where we can explore a variety of features used in 
-virtually all web applications.
-
-You can check out the source code for this example from the Catalyst
-Subversion repository as per the instructions in
-L<Catalyst::Manual::Tutorial::Intro|Catalyst::Manual::Tutorial::Intro>.
-
-Please take a look at 
-L<Catalyst::Manual::Tutorial::Intro/CATALYST INSTALLATION> before 
-doing the rest of this tutorial.  Although the tutorial should work 
-correctly under most any recent version of Perl running on any 
-operating system, the tutorial has been written using Debian 5 and 
-tested to be sure it runs correctly in this environment.  
-
-
-=head1 CREATE A NEW APPLICATION
-
-The remainder of the tutorial will build an application called C<MyApp>.
-First use the Catalyst C<catalyst.pl> script to initialize the framework
-for the C<MyApp> application (make sure you aren't still inside the
-directory of the C<Hello> application from the previous chapter of the
-tutorial or in a directory that already has a "MyApp" subdirectory):
-
-    $ catalyst.pl MyApp
-    created "MyApp"
-    created "MyApp/script"
-    created "MyApp/lib"
-    created "MyApp/root"
-    ...
-    created "MyApp/script/myapp_create.pl"
-    $ cd MyApp
-
-This creates a similar skeletal structure to what we saw in Chapter 2 of
-the tutorial, except with C<MyApp> and C<myapp> substituted for
-C<Hello> and C<hello>.
-
-
-=head1 EDIT THE LIST OF CATALYST PLUGINS
-
-One of the greatest benefits of Catalyst is that it has such a large
-library of plugins and base classes 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:
-
-=over 4
-
-=item *
-
-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 item 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<__PACKAGE__-E<gt>setup> 
-line of your application class will be plugins, Catalyst supports a 
-limited number of flag options (of these, C<-Debug> is the most 
-common).  See the documentation for C<Catalyst.pm> to get details on 
-other flags (currently C<-Engine>, C<-Home>, and C<-Log>).
-
-If you prefer, you can use the C<$c-E<gt>debug> method to enable debug
-messages.
-
-B<TIP>: Depending on your needs, it can be helpful to permanently
-remove C<-Debug> from C<lib/MyApp.pm> and then use the C<-d> option
-to C<script/myapp_server.pl> to re-enable it just for the development
-server.  We will not be using that approach in the tutorial, but feel
-free to make use of it in your own projects.
-
-=item *
-
-L<Catalyst::Plugin::ConfigLoader|Catalyst::Plugin::ConfigLoader>
-
-C<ConfigLoader> provides an automatic way to load configurable
-parameters for your application from a central
-L<Config::General|Config::General> file (versus having the values
-hard-coded inside your Perl modules).  Config::General uses syntax
-very similar to Apache configuration files.  We will see how to use
-this feature of Catalyst during the authentication and authorization
-sections (Chapter 5 and Chapter 6).
-
-B<IMPORTANT NOTE:> If you are using a version of 
-L<Catalyst::Devel|Catalyst::Devel> prior to version 1.06, be aware 
-that Catalyst changed the default format from YAML to the more 
-straightforward C<Config::General> style.  This tutorial uses the 
-newer C<myapp.conf> file for C<Config::General>. However, Catalyst 
-supports both formats and will automatically use either C<myapp.conf> 
-or C<myapp.yml> (or any other format supported by 
-L<Catalyst::Plugin::ConfigLoader|Catalyst::Plugin::ConfigLoader> and 
-L<Config::Any|Config::Any>).  If you are using a version of 
-Catalyst::Devel prior to 1.06, you can convert to the newer format by 
-simply creating the C<myapp.conf> file manually and deleting 
-C<myapp.yml>.  The default contents of the C<myapp.conf> you create 
-should only consist of one line: 
-
-    name MyApp
-
-B<TIP>: This script can be useful for converting between configuration
-formats:
-
-    perl -Ilib -e 'use MyApp; use Config::General;
-        Config::General->new->save_file("myapp.conf", MyApp->config);'
-
-=item *
-
-L<Catalyst::Plugin::Static::Simple|Catalyst::Plugin::Static::Simple>
-
-C<Static::Simple> provides an easy way to serve static content, such
-as images and CSS files, from the development server.
-
-=back
-
-For our application, we want to add one new plugin into the mix.  To 
-do this, edit C<lib/MyApp.pm> (this file is generally referred to as 
-your I<application class>) and delete the lines with:
-
-    use Catalyst qw/-Debug
-                    ConfigLoader
-                    Static::Simple/;
-
-Then replace it with:
-
-    # Load plugins
-    use Catalyst qw/-Debug
-                    ConfigLoader
-                    Static::Simple
-                
-                    StackTrace
-                    /;
-
-B<Note:> Recent versions of C<Catalyst::Devel> have used a variety of 
-techniques to load these plugins/flags.  For example, you might see
-the following:
-
-    __PACKAGE__->setup(qw/-Debug ConfigLoader Static::Simple/);
-
-Don't let these variations confuse you -- they all accomplish the same 
-result.
-
-This tells Catalyst to start using one new plugin, 
-L<Catalyst::Plugin::StackTrace|Catalyst::Plugin::StackTrace>, to add a 
-stack trace to the standard Catalyst "debug screen" (the screen 
-Catalyst sends to your browser when an error occurs). Be aware that 
-L<StackTrace|Catalyst::Plugin::StackTrace> output appears in your 
-browser, not in the console window from which you're running your 
-application, which is where logging output usually goes.
-
-Make sure that when adding new plugins that you include them as a new
-dependancies within the Makefile.PL file. For example, after adding
-the StackTrace plugin the Makefile.PL should include the following
-line:
-
-    requires 'Catalyst::Plugin::StackTrace';
-
-
-B<Notes:> 
-
-=over 4
-
-=item *
-
-C<__PACKAGE__> is just a shorthand way of referencing the name of the 
-package where it is used.  Therefore, in C<MyApp.pm>, C<__PACKAGE__> 
-is equivalent to C<MyApp>.
-
-=item *
-
-You will want to disable L<StackTrace|Catalyst::Plugin::StackTrace> 
-before you put your application into production, but it can be helpful 
-during development.
-
-=item *
-
-When specifying plugins on the C<__PACKAGE__-E<gt>setup> 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.
-
-=back
-
-
-=head1 CREATE A CATALYST CONTROLLER
-
-As discussed earlier, controllers are where you write methods that
-interact with user input.  Typically, controller methods respond to
-C<GET> and C<POST> requests from the user's web browser.
-
-Use the Catalyst C<create> script to add a controller for book-related
-actions:
-
-    $ script/myapp_create.pl controller Books
-     exists "/home/me/MyApp/script/../lib/MyApp/Controller"
-     exists "/home/me/MyApp/script/../t"
-    created "/home/me/MyApp/script/../lib/MyApp/Controller/Books.pm"
-    created "/home/me/MyApp/script/../t/controller_Books.t"
-
-Then edit C<lib/MyApp/Controller/Books.pm> (as discussed in Chapter 2 of
-the Tutorial, Catalyst has a separate directory under C<lib/MyApp> for
-each of the three parts of MVC: C<Model>, C<View>, and C<Controller>)
-and add the following method to the controller:
-
-    =head2 list
-    
-    Fetch all book objects and pass to books/list.tt2 in stash to be displayed
-    
-    =cut
-    
-    sub list : Local {
-        # Retrieve the usual Perl OO '$self' for this object. $c is the Catalyst
-        # 'Context' that's used to 'glue together' the various components
-        # that make up the application
-        my ($self, $c) = @_;
-    
-        # Retrieve all of the book records as book model objects and store in the
-        # stash where they can be accessed by the TT template
-        # $c->stash->{books} = [$c->model('DB::Book')->all];
-        # But, for now, use this code until we create the model later
-        $c->stash->{books} = '';
-    
-        # Set the TT template to use.  You will almost always want to do this
-        # in your action methods (action methods respond to user input in
-        # your controllers).
-        $c->stash->{template} = 'books/list.tt2';
-    }
-
-B<TIP>: See Appendix 1 for tips on removing the leading spaces when
-cutting and pasting example code from POD-based documents.
-
-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.
-
-Catalyst actions are regular Perl methods, but they make use of 
-attributes (the "C<: Local>" next to the "C<sub list>" in the code 
-above) to provide additional information to the Catalyst dispatcher 
-logic (note that the space between the colon and the attribute name is 
-optional; you will see attributes written both ways).  Most Catalyst 
-Controllers use one of five action types:
-
-=over 4
-
-=item *
-
-B<:Private> -- Use C<:Private> for methods that you want to make into 
-an action, but you do not want Catalyst to directly expose  
-to your users.  Catalyst will not map C<:Private> methods to a URI. 
-Use them for various sorts of "special" methods (the C<begin>, 
-C<auto>, etc. discussed below) or for methods you want to be able to 
-C<forward> or C<detach> to.  (If the method is a plain old "helper 
-method" that you don't want to be an action at all, then just define 
-the method without any attribute -- you can call it in your code, but 
-the Catalyst dispatcher will ignore it.)
-
-There are five types of "special" build-in C<:Private> actions: 
-C<begin>, C<end>, C<default>, C<index>, and C<auto>.
-
-=over 4
-
-=item *
-
-With C<begin>, C<end>, C<default>, C<index> private actions, only the
-most specific action of each type will be called.  For example, if you
-define a C<begin> action in your controller it will I<override> a
-C<begin> action in your application/root controller -- I<only> the
-action in your controller will be called.
-
-=item *
-
-Unlike the other actions where only a single method is called for each
-request, I<every> auto action along the chain of namespaces will be
-called.  Each C<auto> action will be called I<from the application/root
-controller down through the most specific class>.
-
-=back
-
-=item *
-
-B<:Path> -- C<:Path> actions let you map a method to an explicit URI 
-path.  For example, "C<:Path('list')>" in 
-C<lib/MyApp/Controller/Books.pm> would match on the URL 
-C<http://localhost:3000/books/list> but "C<:Path('/list')>" would match 
-on C<http://localhost:3000/list>.  You can use C<:Args()> to specify 
-how many arguments an action should accept.  See 
-L<Catalyst::Manual::Intro/Action_types> for more information and a few 
-examples.
-
-=item *
-
-B<:Local> -- C<:Local> is merely a shorthand for 
-"C<:Path('_name_of_method_')>".  For example, these are equivalent:
-"C<sub create_book :Local {...}>" and 
-"C<sub create_book :Path('create_book') {...}>".
-
-=item *
-
-B<:Global> -- C<:Global> is merely a shorthand for 
-"C<:Path('/_name_of_method_')>".  For example, these are equivalent:
-"C<sub create_book :Global {...}>" and 
-"C<sub create_book :Path('/create_book') {...}>".
-
-=item *
-
-B<:Chained> -- Newer Catalyst applications tend to use the Chained 
-dispatch form of action types because of its power and flexibility.  
-It allows a series of controller methods to be automatically dispatched
-to service a single user request.  See 
-L<Catalyst::Manual::Tutorial::BasicCRUD|Catalyst::Manual::Tutorial::BasicCRUD> 
-and L<Catalyst::DispatchType::Chained|Catalyst::DispatchType::Chained> 
-for more information on chained actions.
-
-=back
-
-You should refer to L<Catalyst::Manual::Intro/Action_types> for 
-additional information and for coverage of some lesser-used action 
-types not discussed here (C<Regex> and C<LocalRegex>).
-
-
-=head1 CATALYST VIEWS
-
-As mentioned in Chapter 2 of the tutorial, views are where you render
-output, typically for display in the user's web browser (but also
-possibly using into output-generation systems, such as PDF or JSON).
-The code in C<lib/MyApp/View> selects the I<type> of view to use, with
-the actual rendering template found in the C<root> directory.  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
-somewhat popular view technologies include Mason
-(L<http://www.masonhq.com> and L<http://www.masonbook.com>) and
-L<HTML::Template> (L<http://html-template.sourceforge.net>).
-
-
-=head2 Create a Catalyst View
-
-When using TT for the Catalyst view, there are two main helper scripts:
-
-=over 4
-
-=item *
-
-L<Catalyst::Helper::View::TT|Catalyst::Helper::View::TT>
-
-=item *
-
-L<Catalyst::Helper::View::TTSite|Catalyst::Helper::View::TTSite>
-
-=back
-
-Both helpers are similar. C<TT> 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 Chapter 8.) C<TTSite>, on the other hand, 
-creates a modular and hierarchical view layout with
-separate Template Toolkit (TT) files for common header and footer
-information, configuration values, a CSS stylesheet, and more.
-
-While C<TTSite> was useful to bootstrap a project, its use is now
-deprecated and it should be considered historical.  For most Catalyst
-applications it adds redundant functionality and structure; many in the
-Catalyst community recommend that it's easier to learn both Catalyst and
-Template Toolkit if you use the more basic C<TT> approach.
-Consequently, this tutorial will use "plain old TT."
-
-Enter the following command to enable the C<TT> style of view
-rendering for this tutorial:
-
-    $ script/myapp_create.pl view TT TT
-     exists "/home/me/MyApp/script/../lib/MyApp/View"
-     exists "/home/me/MyApp/script/../t"
-     created "/home/me/MyApp/script/../lib/MyApp/View/TT.pm"
-     created "/home/me/MyApp/script/../t/view_TT.t"
-
-This simply creates a view called C<TT> (the second 'TT' argument) in 
-a file called C<TT.pm> (the first 'TT' argument). It is now up to you 
-to decide how you want to structure your view layout.  For the 
-tutorial, we will start with a very simple TT template to initially 
-demonstrate the concepts, but quickly migrate to a more typical 
-"wrapper page" type of configuration (where the "wrapper" controls the 
-overall "look and feel" of your site from a single file or set of 
-files).
-
-Edit C<lib/MyApp/View/TT.pm> and you should see that the default
-contents contains something similar to the following:
-
-    __PACKAGE__->config(TEMPLATE_EXTENSION => '.tt');
-
-And update it to match:
-
-    __PACKAGE__->config(
-        # Change default TT extension
-        TEMPLATE_EXTENSION => '.tt2',
-        # Set the location for TT files
-        INCLUDE_PATH => [
-                MyApp->path_to( 'root', 'src' ),
-            ],
-    );
-
-B<NOTE:> Make sure to add a comma after '.tt2' outside the single
-quote.
-
-This changes the default extension for Template Toolkit from '.tt' to
-'.tt2' and changes the base directory for your template files from
-C<root> to C<root/src>.  These changes from the default are done mostly
-to facilitate the application we're developing in this tutorial; as with
-most things Perl, there's more than one way to do it...
-
-B<Note:> We will use C<root/src> as the base directory for our 
-template files, which a full naming convention of 
-C<root/src/_controller_name_/_action_name_.tt2>.  Another popular option is to
-use C<root/> as the base (with a full filename pattern of 
-C<root/_controller_name_/_action_name_.tt2>).
-
-
-=head2 Create a TT Template Page
-
-First create a directory for book-related TT templates:
-
-    $ mkdir -p root/src/books
-
-Then create C<root/src/books/list.tt2> in your editor and enter:
-
-    [% # 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  -%]
-    [% # it WILL eliminate a blank line if you view the HTML source.  It's purely   -%]
-    [%- # optional, but both the beginning and the ending TT tags support chomping. -%]
-    
-    [% # Provide a title -%]
-    [% META title = 'Book List' -%]
-    
-    <table>
-    <tr><th>Title</th><th>Rating</th><th>Author(s)</th></tr>
-    [% # Display each book in a table row %]
-    [% FOREACH book IN books -%]
-      <tr>
-        <td>[% book.title %]</td>
-        <td>[% book.rating %]</td>
-        <td></td>
-      </tr>
-    [% END -%]
-    </table>
-
-As indicated by the inline comments above, the C<META title> line uses
-TT's META feature to provide a title to the "wrapper" that we will
-create later. Meanwhile, the C<FOREACH> loop iterates through each
-C<book> model object and prints the C<title> and C<rating> fields.
-
-The C<[%> and C<%]> tags are used to delimit Template Toolkit code.  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://search.cpan.org/perldoc?Template::Manual::Variables> for
-details and examples).  In addition to the usual C<Template> module Pod
-documentation, you can access the TT manual at
-L<http://search.cpan.org/perldoc?Template::Manual>.
-
-B<TIP:> While you can build all sorts of complex logic into your TT
-templates, you should in general keep the "code" part of your templates
-as simple as possible.  If you need more complex logic, create helper
-methods in your model that abstract out a set of code into a single call
-from your TT template.  (Note that the same is true of your controller
-logic as well -- complex sections of code in your controllers should
-often be pulled out and placed into your model objects.)
-
-
-=head2 Test Run The Application
-
-To test your work so far, first start the development server:
-
-    $ script/myapp_server.pl
-
-Then point your browser to L<http://localhost:3000> and you should
-still get the Catalyst welcome page.  Next, change the URL in your
-browser to L<http://localhost:3000/books/list>.  If you have
-everything working so far, you should see a web page that displays
-nothing other than our column headers for "Title", "Rating", and
-"Author(s)" -- we will not see any books until we get the database and
-model working below.
-
-If you run into problems getting your application to run correctly, it
-might be helpful to refer to some of the debugging techniques covered in
-the L<Debugging|Catalyst::Manual::Tutorial::Debugging> part of the
-tutorial.
-
-
-=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.  We will use SQLite,
-a popular database that is lightweight and easy to use.  Open
-C<myapp01.sql> in your editor and enter:
-
-    --
-    -- Create a very simple database to hold book and author information
-    --
-    CREATE TABLE book (
-            id          INTEGER PRIMARY KEY,
-            title       TEXT ,
-            rating      INTEGER
-    );
-    -- 'book_author' is a many-to-many join table between books & authors
-    CREATE TABLE book_author (
-            book_id     INTEGER,
-            author_id   INTEGER,
-            PRIMARY KEY (book_id, author_id)
-    );
-    CREATE TABLE author (
-            id          INTEGER PRIMARY KEY,
-            first_name  TEXT,
-            last_name   TEXT
-    );
-    ---
-    --- Load some sample data
-    ---
-    INSERT INTO book VALUES (1, 'CCSP SNRS Exam Certification Guide', 5);
-    INSERT INTO book VALUES (2, 'TCP/IP Illustrated, Volume 1', 5);
-    INSERT INTO book VALUES (3, 'Internetworking with TCP/IP Vol.1', 4);
-    INSERT INTO book VALUES (4, 'Perl Cookbook', 5);
-    INSERT INTO book VALUES (5, 'Designing with Web Standards', 5);
-    INSERT INTO author VALUES (1, 'Greg', 'Bastien');
-    INSERT INTO author VALUES (2, 'Sara', 'Nasseh');
-    INSERT INTO author VALUES (3, 'Christian', 'Degu');
-    INSERT INTO author VALUES (4, 'Richard', 'Stevens');
-    INSERT INTO author VALUES (5, 'Douglas', 'Comer');
-    INSERT INTO author VALUES (6, 'Tom', 'Christiansen');
-    INSERT INTO author VALUES (7, 'Nathan', 'Torkington');
-    INSERT INTO author VALUES (8, 'Jeffrey', 'Zeldman');
-    INSERT INTO book_author VALUES (1, 1);
-    INSERT INTO book_author VALUES (1, 2);
-    INSERT INTO book_author VALUES (1, 3);
-    INSERT INTO book_author VALUES (2, 4);
-    INSERT INTO book_author VALUES (3, 5);
-    INSERT INTO book_author VALUES (4, 6);
-    INSERT INTO book_author VALUES (4, 7);
-    INSERT INTO book_author VALUES (5, 8);
-
-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 E<lt> 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:
-
-    $ sqlite3 myapp.db
-    SQLite version 3.5.9
-    Enter ".help" for instructions
-    sqlite> select * from book;
-    1|CCSP SNRS Exam Certification Guide|5
-    2|TCP/IP Illustrated, Volume 1|5
-    3|Internetworking with TCP/IP Vol.1|4
-    4|Perl Cookbook|5
-    5|Designing with Web Standards|5
-    sqlite> .q
-    $
-
-Or:
-
-    $ sqlite3 myapp.db "select * from book"
-    1|CCSP SNRS Exam Certification Guide|5
-    2|TCP/IP Illustrated, Volume 1|5
-    3|Internetworking with TCP/IP Vol.1|4
-    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.
-
-Please note that here we have chosen to use 'singular' table names. This
-is because the default inflection code for L<DBIx::Class:Schema::Loader>
-does NOT handle plurals. There has been much philosophical discussion
-on whether table names should be plural or singular. There is no one
-correct answer, as long as one makes a choice and remains consistent
-with it. If you prefer plural table names (e.g. they are easier and
-more natural to read) then you will need to pass it an inflect_map 
-option. See L<DBIx::Class:Schema::Loader> for more information.
-
-For using other databases, such as PostgreSQL or MySQL, see 
-L<Appendix 2|Catalyst::Manual::Tutorial::Appendices>.
-
-
-=head1 DATABASE ACCESS WITH DBIx::Class
-
-Catalyst can be used with virtually any form of datastore available 
-via Perl.  For example, L<Catalyst::Model::DBI|Catalyst::Model::DBI> 
-can be used to access databases through the traditional Perl C<DBI> 
-interface or you can use a model to access files of any type on the 
-filesystem.  However, most Catalyst applications use some form of 
-object-relational mapping (ORM) technology to create objects 
-associated with tables in a relational database.  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 DBIx::Class, as will this tutorial.
-
-Although DBIx::Class has included support for a C<create=dynamic> mode 
-to automatically read the database structure every time the 
-application starts, it's use is no longer recommended.  While it can 
-make for "flashy" demos, the use of the C<create=static> mode we use 
-below can be implemented just as quickly and provides many advantages 
-(such as the ability to add your own methods to the overall DBIC 
-framework, a technique that we see in Chapter 4).
-
-
-=head2 Make Sure You Have a Recent Version of the DBIx::Class Model
-
-First, let's be sure we have a recent version of the DBIC helper,
-L<Catalyst::Model::DBIC::Schema|Catalyst::Model::DBIC::Schema>, by
-running this command:
-
-    $ perl -MCatalyst::Model::DBIC::Schema -e \
-        'print "$Catalyst::Model::DBIC::Schema::VERSION\n"'
-    0.23
-
-(please note that the '\' above is a line continuation marker and
-should NOT be included as part of the command)
-
-If you don't have version 0.23 or higher, please run this command
-to install it directly from CPAN:
-
-    $ sudo cpan Catalyst::Model::DBIC::Schema
-
-And re-run the version print command to verify that you are now at 
-0.23 or higher.
-
-
-=head2 Create Static DBIx::Class Schema Files
-
-Before you continue, make sure your C<myapp.db> database file is in 
-the application's topmost directory. Now use the model helper with 
-the C<create=static> option to read the database with 
-L<DBIx::Class::Schema::Loader|DBIx::Class::Schema::Loader> and 
-automatically build the required files for us:
-
-    $ script/myapp_create.pl model DB DBIC::Schema MyApp::Schema \
-        create=static components=TimeStamp dbi:SQLite:myapp.db
-     exists "/home/me/MyApp/script/../lib/MyApp/Model"
-     exists "/home/me/MyApp/script/../t"
-    Dumping manual schema for MyApp::Schema to directory /home/me/MyApp/script/../lib ...
-    Schema dump completed.
-    created "/home/me/MyApp/script/../lib/MyApp/Model/DB.pm"
-    created "/home/me/MyApp/script/../t/model_DB.t"
-
-(please note that the '\' above is a line continuation marker and
-should NOT be included as part of the command)
-
-The C<script/myapp_create.pl> command breaks down like this:
-
-=over 4
-
-=item *
-
-C<DB> is the name of the model class to be created by the helper in 
-C<lib/MyApp/Model>.
-
-=item *
-
-C<DBIC::Schema> is the type of the model to create.
-
-=item *
-
-C<MyApp::Schema> is the name of the DBIC schema file written to
-C<lib/MyApp/Schema.pm>.
-
-=item *
-
-C<create=static> causes 
-L<DBIx::Class::Schema::Loader|DBIx::Class::Schema::Loader> to 
-load the schema as it runs and then write that information out
-into files.
-
-=item *
-
-C<components=TimeStamp> causes the help to include the 
-L<DBIx::Class::TimeStamp|DBIx::Class::TimeStamp> DBIC component.
-
-=item *
-
-And finally, C<dbi:SQLite:myapp.db> is the standard DBI connect string 
-for use with SQLite.
-
-=back
-
-If you look in the C<lib/MyApp/Schema.pm> file, you will find that it 
-only contains a call to the C<load_namespaces> method.  You will also 
-find that C<lib/MyApp> contains a C<Schema> subdirectory, which then 
-has a subdirectory called "Result".  This "Result" subdirectory then 
-has files named according to each of the tables in our simple database 
-(C<Author.pm>, C<BookAuthor.pm>, and C<Book.pm>).  These three 
-files are called "Result Classes" in DBIx::Class nomenclature. Although the 
-Result Class files are named after tables in our database, the classes 
-correspond to the I<row-level data> that is returned by DBIC (more on 
-this later, especially in 
-L<Catalyst::Manual::Tutorial::BasicCRUD/EXPLORING THE POWER OF DBIC>).
-
-The idea with the Result Source files created under 
-C<lib/MyApp/Schema/Result> by the C<create=static> option is to only 
-edit the files below the C<# DO NOT MODIFY THIS OR ANYTHING ABOVE!> 
-warning. If you place all of your changes below that point in the 
-file, you can regenerate the automatically created information at the 
-top of each file should your database structure get updated.
-
-Also note the "flow" of the model information across the various files 
-and directories.  Catalyst will initially load the model from 
-C<lib/MyApp/Model/DB.pm>.  This file contains a reference to 
-C<lib/MyApp/Schema.pm>, so that file is loaded next.  Finally, the 
-call to C<load_namespaces> in C<Schema.pm> will load each of the 
-"Result Class" files from the C<lib/MyApp/Schema/Result> subdirectory. 
-The final outcome is that Catalyst will dynamically create three 
-table-specific Catalyst models every time the application starts (you 
-can see these three model files listed in the debug output generated 
-when you launch the application).
-
-B<NOTE:> Older versions of 
-L<Catalyst::Model::DBIC::Schema|Catalyst::Model::DBIC::Schema> use the 
-deprecated DBIx::Class C<load_classes> technique instead of the newer 
-C<load_namspaces>.  For new applications, please try to use 
-C<load_namespaces> since it more easily supports a very useful DBIC 
-technique called "ResultSet Classes."  If you need to convert an 
-existing application from "load_classes" to "load_namespaces," you can 
-use this process to automate the migration (but first make sure you 
-have v0.23 C<Catalyst::Model::DBIC::Schema> as discussed above):
-
-    $ # First delete the existing schema file to disable "compatibility" mode
-    $ rm lib/MyApp/Schema.pm
-    $
-    $ # Then re-run the helper to build the files for "load_namespaces"
-    $ script/myapp_create.pl model DB DBIC::Schema MyApp::Schema \
-        create=static components=TimeStamp dbi:SQLite:myapp.db
-    $
-    $ # Note that the '\' above is a line continuation marker and
-    $ # should NOT be included as part of the command
-
-    $
-    $ # Now convert the existing files over
-    $ cd lib/MyApp/Schema
-    $ perl -MIO::All -e 'for (@ARGV) { my $s < io($_); $s =~ s/.*\n\# You can replace.*?\n//s;
-          $s =~ s/'MyApp::Schema::/'MyApp::Schema::Result::/g; my $d < io("Result/$_");
-          $d =~ s/1;\n?//; "$d$s" > io("Result/$_"); }' *.pm
-    $ cd ../../..
-    $
-    $ # And finally delete the old files
-    $ rm lib/MyApp/Schema/*.pm
-
-The "C<perl -MIO::ALL ...>" script will copy all the customized 
-relationship (and other) information below "C<# DO NOT MODIFY>" line 
-from the old files in C<lib/MyApp/Schema> to the new files in 
-C<lib/MyApp/Schema/Result> (we will be starting to add some 
-"customized relationship information in the section below).
-
-
-=head1 ENABLE THE MODEL IN THE CONTROLLER
-
-Open C<lib/MyApp/Controller/Books.pm> and un-comment the model code we 
-left disabled earlier so that your version matches the following (un-
-comment the line containing C<[$c-E<gt>model('DB::Book')-E<gt>all]> 
-and delete the next 2 lines):
-
-    =head2 list
-    
-    Fetch all book objects and pass to books/list.tt2 in stash to be displayed
-    
-    =cut
-    
-    sub list : Local {
-        # Retrieve the usual Perl OO '$self' for this object. $c is the Catalyst
-        # 'Context' that's used to 'glue together' the various components
-        # that make up the application
-        my ($self, $c) = @_;
-    
-        # Retrieve all of the book records as book model objects and store in the
-        # stash where they can be accessed by the TT template
-        $c->stash->{books} = [$c->model('DB::Book')->all];
-    
-        # Set the TT template to use.  You will almost always want to do this
-        # in your action methods (action methods respond to user input in
-        # your controllers).
-        $c->stash->{template} = 'books/list.tt2';
-    }
-
-B<TIP>: You may see the C<$c-E<gt>model('DB::Book')> un-commented 
-above written as C<$c-E<gt>model('DB')-E<gt>resultset('Book')>.  The 
-two are equivalent.  Either way, C<$c-E<gt>model> returns a 
-L<DBIx::Class::ResultSet|DBIx::Class::ResultSet> which handles queries 
-against the database and iterating over the set of results that is 
-returned.
-
-We are using the C<-E<gt>all> to fetch all of the books.  DBIC 
-supports a wide variety of more advanced operations to easily do 
-things like filtering and sorting the results.  For example, the 
-following could be used to sort the results by descending title:
-
-    $c->model('DB::Book')->search({}, {order_by => 'title DESC'});
-
-Some other examples are provided in 
-L<DBIx::Class::Manual::Cookbook/Complex WHERE clauses>, with 
-additional information found at L<DBIx::Class::ResultSet/search>, 
-L<DBIx::Class::Manual::FAQ/Searching>, 
-L<DBIx::Class::Manual::Intro|DBIx::Class::Manual::Intro> 
-and L<Catalyst::Model::DBIC::Schema|Catalyst::Model::DBIC::Schema>.
-
-
-=head2 Test Run The Application
-
-First, let's enable an environment variable that causes DBIx::Class to 
-dump the SQL statements used to access the database.  This is a 
-helpful trick when you are trying to debug your database-oriented 
-code:
-
-    $ export DBIC_TRACE=1
-
-This assumes you are using bash as your shell -- adjust accordingly if
-you are using a different shell (for example, under tcsh, use
-C<setenv DBIC_TRACE 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> for details (including options
-to log to a file instead of displaying to the Catalyst development server
-log).
-
-Then launch the Catalyst development server.  The log output should
-display something like:
-
-    $ script/myapp_server.pl
-    [debug] Debug messages enabled
-    [debug] Statistics enabled
-    [debug] Loaded plugins:
-    .----------------------------------------------------------------------------.
-    | Catalyst::Plugin::ConfigLoader  0.23                                       |
-    | Catalyst::Plugin::StackTrace  0.10                                         |
-    | Catalyst::Plugin::Static::Simple  0.21                                     |
-    '----------------------------------------------------------------------------'
-    
-    [debug] Loaded dispatcher "Catalyst::Dispatcher"
-    [debug] Loaded engine "Catalyst::Engine::HTTP"
-    [debug] Found home "/home/me/MyApp"
-    [debug] Loaded Config "/home/me/MyApp/myapp.conf"
-    [debug] Loaded components:
-    .-----------------------------------------------------------------+----------.
-    | Class                                                           | Type     |
-    +-----------------------------------------------------------------+----------+
-    | MyApp::Controller::Books                                        | instance |
-    | MyApp::Controller::Root                                         | instance |
-    | MyApp::Model::DB                                                | instance |
-    | MyApp::Model::DB::Author                                        | class    |
-    | MyApp::Model::DB::Book                                          | class    |
-    | MyApp::Model::DB::BookAuthor                                    | class    |
-    | MyApp::View::TT                                                 | instance |
-    '-----------------------------------------------------------------+----------'
-    
-    [debug] Loaded Private actions:
-    .----------------------+--------------------------------------+--------------.
-    | Private              | Class                                | Method       |
-    +----------------------+--------------------------------------+--------------+
-    | /default             | MyApp::Controller::Root              | default      |
-    | /end                 | MyApp::Controller::Root              | end          |
-    | /index               | MyApp::Controller::Root              | index        |
-    | /books/index         | MyApp::Controller::Books             | index        |
-    | /books/list          | MyApp::Controller::Books             | list         |
-    '----------------------+--------------------------------------+--------------'
-    
-    [debug] Loaded Path actions:
-    .-------------------------------------+--------------------------------------.
-    | Path                                | Private                              |
-    +-------------------------------------+--------------------------------------+
-    | /                                   | /default                             |
-    | /                                   | /index                               |
-    | /books                              | /books/index                         |
-    | /books/list                         | /books/list                          |
-    '-------------------------------------+--------------------------------------'
-    
-    [info] MyApp powered by Catalyst 5.80003
-    You can connect to your server at http://debian:3000
-
-B<NOTE:> Be sure you run the C<script/myapp_server.pl> command from
-the 'base' directory of your application, not inside the C<script>
-directory itself or it will not be able to locate the C<myapp.db>
-database file.  You can use a fully qualified or a relative path to
-locate the database file, but we did not specify that when we ran the
-model helper earlier.
-
-Some things you should note in the output above:
-
-=over 4
-
-=item *
-
-Catalyst::Model::DBIC::Schema dynamically created three model classes,
-one to represent each of the three tables in our database
-(C<MyApp::Model::DB::Author>, C<MyApp::Model::DB::BookAuthor>,
-and C<MyApp::Model::DB::Book>).
-
-=item *
-
-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.
-
-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 without any formatting.
-The rating for each book should appear on each row, but the "Author(s)"
-column will still be blank (we will fill that in later).
-
-Also notice in the output of the C<script/myapp_server.pl> that 
-DBIx::Class used the following SQL to retrieve the data:
-
-    SELECT me.id, me.title, me.rating FROM books me
-
-because we enabled DBIC_TRACE.
-
-You now have the beginnings of a simple but workable web application.
-Continue on to future sections and we will develop the application
-more fully.
-
-
-=head1 CREATE A WRAPPER FOR THE VIEW
-
-When using TT, you can (and should) create a wrapper that will
-literally wrap content around each of your templates.  This is
-certainly useful as you have one main source for changing things that
-will appear across your entire site/application instead of having to
-edit many individual files.
-
-
-=head2 Configure TT.pm For The Wrapper
-
-In order to create a wrapper, you must first edit your TT view and
-tell it where to find your wrapper file. Your TT view is located in
-C<lib/MyApp/View/TT.pm>.
-
-Edit C<lib/MyApp/View/TT.pm> and change it to match the following:
-
-    __PACKAGE__->config(
-        # Change default TT extension
-        TEMPLATE_EXTENSION => '.tt2',
-        # Set the location for TT files
-        INCLUDE_PATH => [
-                MyApp->path_to( 'root', 'src' ),
-            ],
-        # Set to 1 for detailed timer stats in your HTML as comments
-        TIMER              => 0,
-        # This is your wrapper template located in the 'root/src'
-        WRAPPER => 'wrapper.tt2',
-    );
-
-
-=head2 Create the Wrapper Template File and Stylesheet
-
-Next you need to set up your wrapper template.  Basically, you'll want
-to take the overall layout of your site and put it into this file.
-For the tutorial, open C<root/src/wrapper.tt2> and input the following:
-
-    <?xml version="1.0" encoding="UTF-8"?>
-    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-    <head>
-    <title>[% template.title or "My Catalyst App!" %]</title>
-    <link rel="stylesheet" href="[% c.uri_for('/static/css/main.css') %]" />
-    </head>
-    
-    <body>
-    <div id="outer">
-    <div id="header">
-        [%# Your logo could go here -%]
-        <img src="[% c.uri_for('/static/images/btn_88x31_powered.png') %]" />
-        [%# Insert the page title -%]
-        <h1>[% template.title or site.title %]</h1>
-    </div>
-    
-    <div id="bodyblock">
-    <div id="menu">
-        Navigation:
-        <ul>
-            <li><a href="[% c.uri_for('/books/list') %]">Home</a></li>
-            <li><a href="[% c.uri_for('/') %]" title="Catalyst Welcome Page">Welcome</a></li>
-        </ul>
-    </div><!-- end menu -->
-    
-    <div id="content">
-        [%# Status and error messages %]
-        <span class="message">[% status_msg %]</span>
-        <span class="error">[% error_msg %]</span>
-        [%# This is where TT will stick all of your template's contents. -%]
-        [% content %]
-    </div><!-- end content -->
-    </div><!-- end bodyblock -->
-    
-    <div id="footer">Copyright (c) your name goes here</div>
-    </div><!-- end outer -->
-    
-    </body>
-    </html>
-
-Notice the status and error message sections in the code above:
-
-    <span class="status">[% status_msg %]</span>
-    <span class="error">[% error_msg %]</span>
-
-If we set either message in the Catalyst stash (e.g.,
-C<$c-E<gt>stash-E<gt>{status_msg} = 'Request was successful!'>) it
-will be displayed whenever any view used by that request is rendered.
-The C<message> and C<error> CSS styles can be customized to suit your
-needs in the C<root/static/css/main.css> file we create below.
-
-B<Notes:> 
-
-=over 4
-
-=item *
-
-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 chapter of the tutorial).
-
-=item *
-
-Although it is beyond the scope of this tutorial, you may wish to use
-a JavaScript or AJAX tool such as jQuery (L<http://www.jquery.com>) or
-Dojo (L<http://www.dojotoolkit.org>).
-
-=back
-
-
-=head3 Create A Basic Stylesheet
-
-First create a central location for stylesheets under the static
-directory:
-
-    $ mkdir root/static/css
-
-Then open the file C<root/static/css/main.css> (the file referenced in
-the stylesheet href link of our wrapper above) and add the following
-content:
-
-    #header {
-        text-align: center;
-    }
-    #header h1 {
-        margin: 0;
-    }
-    #header img {
-        float: right;
-    }
-    #footer {
-        text-align: center;
-        font-style: italic;
-        padding-top: 20px;
-    }
-    #menu {
-        font-weight: bold;
-        background-color: #ddd;
-    }
-    #menu ul {
-        list-style: none;
-        float: left;
-        margin: 0;
-        padding: 0 0 50% 5px;
-        font-weight: normal;
-        background-color: #ddd;
-        width: 100px;
-    }
-    #content {
-        margin-left: 120px;
-    }
-    .message {
-        color: #390;
-    }
-    .error {
-        color: #f00;
-    }
-
-You may wish to check out a "CSS Framework" like Emastic
-(L<http://code.google.com/p/emastic/>) as a way to quickly
-provide lots of high-quality CSS functionality.
-
-
-=head2 Test Run The Application
-
-Restart the development server and hit "Reload" in your web browser
-and you should now see a formatted version of our basic book list.
-Although our wrapper and stylesheet are obviously very simple, you
-should see how it allows us to control the overall look of an entire
-website from two central files.  To add new pages to the site, just
-provide a template that fills in the C<content> section of our wrapper
-template -- the wrapper will provide the overall feel of the page.
-
-
-=head2 Updating the Generated DBIx::Class Result Class Files
-
-Let's manually add some relationship information to the auto-generated 
-Result Class files. (Note: if you are using a database other than 
-SQLite, such as PostgreSQL, then the relationship could have been 
-automatically placed in the Result Class files.  If so, you can skip 
-this step.)  First edit C<lib/MyApp/Schema/Result/Book.pm> and add the 
-following text below the C<# You can replace this text...> comment:
-
-    #
-    # Set relationships:
-    #
-    
-    # has_many():
-    #   args:
-    #     1) Name of relationship, DBIC will create accessor with this name
-    #     2) Name of the model class referenced by this relationship
-    #     3) Column name in *foreign* table (aka, foreign key in peer table)
-    __PACKAGE__->has_many(book_author => 'MyApp::Schema::Result::BookAuthor', 'book_id');
-    
-    # many_to_many():
-    #   args:
-    #     1) Name of relationship, DBIC will create accessor with this name
-    #     2) Name of has_many() relationship this many_to_many() is shortcut for
-    #     3) Name of belongs_to() relationship in model class of has_many() above
-    #   You must already have the has_many() defined to use a many_to_many().
-    __PACKAGE__->many_to_many(author => 'book_author', 'author');
-
-
-B<Note:> Be careful to put this code I<above> the C<1;> at the end of the
-file.  As with any Perl package, we need to end the last line with
-a statement that evaluates to C<true>.  This is customarily done with
-C<1;> on a line by itself.
-
-This code 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_author> table as in 
-C<$book-E<gt>book_author-E<gt>first-E<gt>author-E<gt>last_name> (we 
-will see examples on how to use DBIx::Class objects in your code soon, 
-but note that because C<$book-E<gt>book_author> 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>author-
-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.
-
-Then edit C<lib/MyApp/Schema/Result/Author.pm> and add relationship
-information as follows (again, be careful to put in above the C<1;> but
-below the C<# DO NOT MODIFY THIS OR ANYTHING ABOVE!> comment):
-
-    #
-    # Set relationships:
-    #
-    
-    # has_many():
-    #   args:
-    #     1) Name of relationship, DBIC will create an accessor with this name
-    #     2) Name of the model class referenced by this relationship
-    #     3) Column name in *foreign* table (aka, foreign key in peer table)
-    __PACKAGE__->has_many(book_author => 'MyApp::Schema::Result::BookAuthor', 'author_id');
-    
-    # many_to_many():
-    #   args:
-    #     1) Name of relationship, DBIC will create accessor with this name
-    #     2) Name of has_many() relationship this many_to_many() is shortcut for
-    #     3) Name of belongs_to() relationship in model class of has_many() above
-    #   You must already have the has_many() defined to use a many_to_many().
-    __PACKAGE__->many_to_many(book => 'book_author', 'book');
-
-Finally, do the same for the "join table,"
-C<lib/MyApp/Schema/Result/BookAuthor.pm>:
-
-    #
-    # Set relationships:
-    #
-    
-    # belongs_to():
-    #   args:
-    #     1) Name of relationship, DBIC will create accessor with this name
-    #     2) Name of the model class referenced by this relationship
-    #     3) Column name in *this* table
-    __PACKAGE__->belongs_to(book => 'MyApp::Schema::Result::Book', 'book_id');
-    
-    # belongs_to():
-    #   args:
-    #     1) Name of relationship, DBIC will create accessor with this name
-    #     2) Name of the model class referenced by this relationship
-    #     3) Column name in *this* table
-    __PACKAGE__->belongs_to(author => 'MyApp::Schema::Result::Author', 'author_id');
-
-
-=head2 Run The Application
-
-Run the Catalyst development server script with the C<DBIC_TRACE> option
-(it might still be enabled from earlier in the tutorial, but here is an
-alternate way to specify the option just in case):
-
-    $ DBIC_TRACE=1 script/myapp_server.pl
-
-Make sure that the application loads correctly and that you see the
-three dynamically created model class (one for each of the
-Result Classes we created).
-
-Then hit the URL L<http://localhost:3000/books/list> with your browser 
-and be sure that the book list is displayed via the relationships 
-established above. You can leave the development server running for 
-the next step if you wish.
-
-B<Note:> You will not see the authors yet because the view does not yet 
-use the new relations. Read on to the next section where we update the 
-template to do that.
-
-
-=head1 UPDATING THE VIEW
-
-Let's add a new column to our book list page that takes advantage of 
-the relationship information we manually added to our schema files in 
-the previous section.  Edit C<root/src/books/list.tt2> and replace
-the "empty" table cell "<td></td>" with the following:
-
-    ...
-    <td>
-      [% # First initialize a TT variable to hold a list.  Then use a TT FOREACH -%]
-      [% # loop in 'side effect notation' to load just the last names of the     -%]
-      [% # authors into the list. Note that the 'push' TT vmethod does not print -%]
-      [% # a value, so nothing will be printed here.  But, if you have something -%]
-      [% # in TT that does return a method and you don't want it printed, you    -%]
-      [% # can: 1) assign it to a bogus value, or 2) use the CALL keyword to     -%]
-      [% # call it and discard the return value.                                 -%]
-      [% tt_authors = [ ];
-         tt_authors.push(author.last_name) FOREACH author = book.authors %]
-      [% # Now use a TT 'virtual method' to display the author count in parens   -%]
-      [% # Note the use of the TT filter "| html" to escape dangerous characters -%]
-      ([% tt_authors.size | html %])
-      [% # Use another TT vmethod to join & print the names & comma separators   -%]
-      [% tt_authors.join(', ') | html %]
-    </td>
-    ...
-
-Then hit "Reload" in your browser (note that you don't need to reload 
-the development server or use the C<-r> option when updating TT 
-templates) and you should now see the number of authors each book has 
-along with a comma-separated list of the authors' last names.  (If you 
-didn't leave the development server running from the previous step, 
-you will obviously need to start it before you can refresh your 
-browser window.)
-
-If you are still running the development server with C<DBIC_TRACE>
-enabled, you should also now see five more C<SELECT> statements in the
-debug output (one for each book as the authors are being retrieved by
-DBIx::Class):
-
-    SELECT me.id, me.title, me.rating FROM books me:
-    SELECT author.id, author.first_name, author.last_name FROM book_author me  
-    JOIN author author ON ( author.id = me.author_id ) WHERE ( me.book_id = ? ): '1'
-    SELECT author.id, author.first_name, author.last_name FROM book_author me  
-    JOIN author author ON ( author.id = me.author_id ) WHERE ( me.book_id = ? ): '2'
-    SELECT author.id, author.first_name, author.last_name FROM book_author me  
-    JOIN author author ON ( author.id = me.author_id ) WHERE ( me.book_id = ? ): '3'
-    SELECT author.id, author.first_name, author.last_name FROM book_author me  
-    JOIN author author ON ( author.id = me.author_id ) WHERE ( me.book_id = ? ): '4'
-    SELECT author.id, author.first_name, author.last_name FROM book_author me  
-    JOIN author author ON ( author.id = me.author_id ) WHERE ( me.book_id = ? ): '5'
-
-Also note in C<root/src/books/list.tt2> that we are using "| html", a 
-type of TT filter, to escape characters such as E<lt> and E<gt> to &lt; 
-and &gt; and avoid various types of dangerous hacks against your 
-application.  In a real application, you would probably want to put 
-"| html" at the end of every field where a user has control over the 
-information that can appear in that field (and can therefore inject 
-markup or code if you don't "neutralize" those fields).  In addition to 
-"| html", Template Toolkit has a variety of other useful filters that 
-can found in the documentation for 
-L<Template::Filters|Template::Filters>.
-
-
-=head1 RUNNING THE APPLICATION FROM THE COMMAND LINE
-
-In some situations, it can be useful to run your application and
-display a page without using a browser.  Catalyst lets you do this
-using the C<scripts/myapp_test.pl> script.  Just supply the URL you
-wish to display and it will run that request through the normal
-controller dispatch logic and use the appropriate view to render the
-output (obviously, complex pages may dump a lot of text to your
-terminal window).  For example, if you type:
-
-    $ script/myapp_test.pl "/books/list"
-
-You should get the same text as if you visited
-L<http://localhost:3000/books/list> with the normal development server
-and asked your browser to view the page source.
-
-
-=head1 OPTIONAL INFORMATION
-
-B<NOTE: The rest of this chapter of the tutorial is optional.  You can
-skip to Chapter 4, L<Basic CRUD|Catalyst::Manual::Tutorial::BasicCRUD>,
-if you wish.>
-
-
-=head2 Using 'RenderView' for the Default View
-
-Once your controller logic has processed the request from a user, it
-forwards processing to your view in order to generate the appropriate
-response output.  Catalyst uses
-L<Catalyst::Action::RenderView|Catalyst::Action::RenderView> by
-default to automatically perform this operation.  If you look in
-C<lib/MyApp/Controller/Root.pm>, you should see the empty
-definition for the C<sub end> method:
-
-    sub end : ActionClass('RenderView') {}
-
-The following bullet points provide a quick overview of the
-C<RenderView> process:
-
-=over 4
-
-=item *
-
-C<Root.pm> is designed to hold application-wide logic.
-
-=item *
-
-At the end of a given user request, Catalyst will call the most specific
-C<end> method that's appropriate.  For example, if the controller for a
-request has an C<end> method defined, it will be called.  However, if
-the controller does not define a controller-specific C<end> method, the
-"global" C<end> method in C<Root.pm> will be called.
-
-=item *
-
-Because the definition includes an C<ActionClass> attribute, the
-L<Catalyst::Action::RenderView|Catalyst::Action::RenderView> logic
-will be executed B<after> any code inside the definition of C<sub end>
-is run.  See L<Catalyst::Manual::Actions|Catalyst::Manual::Actions>
-for more information on C<ActionClass>.
-
-=item *
-
-Because C<sub end> is empty, this effectively just runs the default
-logic in C<RenderView>.  However, you can easily extend the
-C<RenderView> logic by adding your own code inside the empty method body
-(C<{}>) created by the Catalyst Helpers when we first ran the
-C<catalyst.pl> to initialize our application.  See
-L<Catalyst::Action::RenderView|Catalyst::Action::RenderView> for more
-detailed information on how to extend C<RenderView> in C<sub end>.
-
-=back
-
-
-=head2 Using The Default Template Name
-
-By default, C<Catalyst::View::TT> will look for a template that uses the
-same name as your controller action, allowing you to save the step of
-manually specifying the template name in each action.  For example, this
-would allow us to remove the
-C<$c-E<gt>stash-E<gt>{template} = 'books/list.tt2';> line of our
-C<list> action in the Books controller.  Open
-C<lib/MyApp/Controller/Books.pm> in your editor and comment out this line
-to match the following (only the C<$c-E<gt>stash-E<gt>{template}> line
-has changed):
-
-    =head2 list
-    
-    Fetch all book objects and pass to books/list.tt2 in stash to be displayed
-    
-    =cut
-    
-    sub list : Local {
-        # Retrieve the usual Perl OO '$self' for this object. $c is the Catalyst
-        # 'Context' that's used to 'glue together' the various components
-        # that make up the application
-        my ($self, $c) = @_;
-    
-        # Retrieve all of the book records as book model objects and store in the
-        # stash where they can be accessed by the TT template
-        $c->stash->{books} = [$c->model('DB::Book')->all];
-    
-        # Set the TT template to use.  You will almost always want to do this
-        # in your action methods (actions methods respond to user input in
-        # your controllers).
-        #$c->stash->{template} = 'books/list.tt2';
-    }
-
-
-You should now be able to restart the development server as per the
-previous section and access the L<http://localhost:3000/books/list>
-as before.
-
-B<NOTE:> Please note that if you use the default template technique,
-you will B<not> be able to use either the C<$c-E<gt>forward> or
-the C<$c-E<gt>detach> mechanisms (these are discussed in Chapter 2 and
-Chapter 9 of the Tutorial).
-
-B<IMPORTANT:> Make sure that you do NOT skip the following section
-before continuing to the next chapter 4 Basic CRUD.
-
-=head2 Return To A Manually Specified Template
-
-In order to be able to use C<$c-E<gt>forward> and C<$c-E<gt>detach>
-later in the tutorial, you should remove the comment from the
-statement in C<sub list> in C<lib/MyApp/Controller/Books.pm>:
-
-    $c->stash->{template} = 'books/list.tt2';
-
-Then delete the C<TEMPLATE_EXTENSION> line in
-C<lib/MyApp/View/TT.pm>.
-
-You should then be able to restart the development server and
-access L<http://localhost:3000/books/list> in the same manner as
-with earlier sections.
-
-
-=head1 AUTHOR
-
-Kennedy Clark, C<hkclark@gmail.com>
-
-Please report any errors, issues or suggestions to the author.  The
-most recent version of the Catalyst Tutorial can be found at
-L<http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Manual/5.70/trunk/lib/Catalyst/Manual/Tutorial/>.
-
-Copyright 2006-2008, Kennedy Clark, under Creative Commons License
-(L<http://creativecommons.org/licenses/by-sa/3.0/us/>).