From: Graham Knop Date: Tue, 22 Jan 2019 17:59:52 +0000 (+0100) Subject: remove trailing whitespace X-Git-Tag: v5.9010~22 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Manual.git;a=commitdiff_plain;h=7ce05098c9b1df9078e709e5a724e821a3b3b00d remove trailing whitespace --- diff --git a/lib/Catalyst/Manual.pm b/lib/Catalyst/Manual.pm index f969cd3..1c4bb33 100644 --- a/lib/Catalyst/Manual.pm +++ b/lib/Catalyst/Manual.pm @@ -1,4 +1,4 @@ -# Manual.pm +# Manual.pm # Copyright (c) 2006 Jonathan Rockway package Catalyst::Manual; @@ -22,7 +22,7 @@ Catalyst::Manual - The Catalyst developer's manual Install L to install all the dependencies you need to follow along with the -Tutorial. You can also refer to +Tutorial. You can also refer to L for more information on installation options. @@ -72,10 +72,10 @@ For additional information on Catalyst, there are currently two books available: =item * -The Definitive Guide to Catalyst: Writing Extendable, Scalable and +The Definitive Guide to Catalyst: Writing Extendable, Scalable and Maintainable Perl-Based Web Applications -By: Kieren Diment, Matt Trout +By: Kieren Diment, Matt Trout Available July 12, 2009 ISBN 10: 1-4302-2365-0 ISBN 13: 978-1-4302-2365-8 diff --git a/lib/Catalyst/Manual/Actions.pod b/lib/Catalyst/Manual/Actions.pod index 41247c8..0e0bb19 100644 --- a/lib/Catalyst/Manual/Actions.pod +++ b/lib/Catalyst/Manual/Actions.pod @@ -1,6 +1,6 @@ =head1 NAME -Catalyst::Manual::Actions - Catalyst Reusable Actions +Catalyst::Manual::Actions - Catalyst Reusable Actions =head1 DESCRIPTION @@ -17,7 +17,7 @@ them. This is pretty simple. Actions work just like the normal dispatch attributes you are used to, like Local or Private: - sub Hello :Local :ActionClass('SayBefore') { + sub Hello :Local :ActionClass('SayBefore') { $c->res->output( 'Hello '.$c->stash->{what} ); } @@ -38,7 +38,7 @@ the Action class: package Catalyst::Action::MyAction; use Moose; use namespace::autoclean; - + extends 'Catalyst::Action'; before 'execute' => sub { @@ -75,7 +75,7 @@ would make the example above look like this: my ( $self, $controller, $c, $test ) = @_; $c->stash->{foo} = 'bar'; }; - + 1; and this would be used in a controller like this: @@ -95,7 +95,7 @@ and this would be used in a controller like this: =head2 Catalyst::Action::RenderView -This is meant to decorate end actions. It's similar in operation to +This is meant to decorate end actions. It's similar in operation to L, but allows you to decide on an action level rather than on an application level where it should be run. diff --git a/lib/Catalyst/Manual/CatalystAndMoose.pod b/lib/Catalyst/Manual/CatalystAndMoose.pod index 3d0b957..a228c16 100644 --- a/lib/Catalyst/Manual/CatalystAndMoose.pod +++ b/lib/Catalyst/Manual/CatalystAndMoose.pod @@ -73,7 +73,7 @@ slightly limits the gains that could be had by wielding the full power of L attributes. Most of the accessors to information gathered during compile time (such -as configuration) are managed by C, which is a +as configuration) are managed by C, which is a L-aware version of L but not compatible with L. @@ -115,7 +115,7 @@ the actions themselves are declared: use namespace::autoclean; BEGIN { extends 'Catalyst::Controller'; } - + =head2 Controller Roles It is possible to use roles to apply method modifiers on controller actions @@ -126,8 +126,8 @@ themselves. For example use Moose; use namespace::autoclean; BEGIN { extends 'Catalyst::Controller' }; - - sub foo : Local { + + sub foo : Local { my ($self, $c) = @_; $c->res->body('Hello '); } @@ -135,24 +135,24 @@ themselves. For example my ($self, $c) = @_; $c->res->body($c->res->body . 'World'); }; - + It is possible to have action methods with attributes inside Moose roles, using L, example: package MyApp::ControllerRole; use MooseX::MethodAttributes::Role; use namespace::autoclean; - + sub foo : Local { my ($self, $c) = @_; ... } - + package MyApp::Controller::Foo; use Moose; use namespace::autoclean; BEGIN { extends 'Catalyst::Controller' }; - + with 'MyApp::ControllerRole'; =head1 AUTHORS diff --git a/lib/Catalyst/Manual/Components.pod b/lib/Catalyst/Manual/Components.pod index 8acd2c4..ff33214 100644 --- a/lib/Catalyst/Manual/Components.pod +++ b/lib/Catalyst/Manual/Components.pod @@ -143,7 +143,7 @@ This module implements the Catalyst::Authentication API for L. =head4 L -Allows you to use a plain L database connection to identify users. +Allows you to use a plain L database connection to identify users. =head4 L diff --git a/lib/Catalyst/Manual/Deployment/Apache/mod_perl.pod b/lib/Catalyst/Manual/Deployment/Apache/mod_perl.pod index 7296890..22da178 100644 --- a/lib/Catalyst/Manual/Deployment/Apache/mod_perl.pod +++ b/lib/Catalyst/Manual/Deployment/Apache/mod_perl.pod @@ -99,7 +99,7 @@ this has not been confirmed): use lib '/var/www/MyApp/lib'; use MyApp; - + SetHandler modperl PerlResponseHandler MyApp diff --git a/lib/Catalyst/Manual/Deployment/DevelopmentServer.pod b/lib/Catalyst/Manual/Deployment/DevelopmentServer.pod index 23de797..ca4f32a 100644 --- a/lib/Catalyst/Manual/Deployment/DevelopmentServer.pod +++ b/lib/Catalyst/Manual/Deployment/DevelopmentServer.pod @@ -47,7 +47,7 @@ different apps served on the same host. =head2 Other web servers The proxy configuration above can also be replicated with a different -frontend server or proxy, such as varnish, nginx, or lighttpd. +frontend server or proxy, such as varnish, nginx, or lighttpd. =head1 AUTHORS diff --git a/lib/Catalyst/Manual/Deployment/SharedHosting.pod b/lib/Catalyst/Manual/Deployment/SharedHosting.pod index fa3b2b6..fe91770 100644 --- a/lib/Catalyst/Manual/Deployment/SharedHosting.pod +++ b/lib/Catalyst/Manual/Deployment/SharedHosting.pod @@ -36,7 +36,7 @@ myapp_fastcgi.fcgi and/or use a SetHandler directive): RewriteRule ^(.*)$ script/myapp_fastcgi.pl/$1 [PT,L] Now C should now Just Work. Congratulations, now -you can tell your friends about your new website. +you can tell your friends about your new website. =head1 AUTHORS diff --git a/lib/Catalyst/Manual/ExtendingCatalyst.pod b/lib/Catalyst/Manual/ExtendingCatalyst.pod index 3cc5967..97c31b6 100644 --- a/lib/Catalyst/Manual/ExtendingCatalyst.pod +++ b/lib/Catalyst/Manual/ExtendingCatalyst.pod @@ -312,10 +312,10 @@ method. The execute method of the action will naturally call the methods code. You can surround this by overriding the method in a subclass: - package Catalyst::Action::MyFoo; + package Catalyst::Action::MyFoo; use Moose; use namespace::autoclean; - use MRO::Compat; + use MRO::Compat; extends 'Catalyst::Action'; sub execute { @@ -329,12 +329,12 @@ subclass: 1; We are using L to ensure that you have the next::method -call, from L (in older perls), or natively (if you are using -perl 5.10) to re-dispatch to the original C method in the +call, from L (in older perls), or natively (if you are using +perl 5.10) to re-dispatch to the original C method in the L class. The Catalyst dispatcher handles an incoming request and, depending -upon the dispatch type, will call the appropriate target or chain. +upon the dispatch type, will call the appropriate target or chain. From time to time it asks the actions themselves, or through the controller, if they would match the current request. That's what the C method does. So by overriding this, you can change on what @@ -343,7 +343,7 @@ the action will match and add new matching criteria. For example, the action class below will make the action only match on Mondays: - package Catalyst::Action::OnlyMondays; + package Catalyst::Action::OnlyMondays; use Moose; use namespace::autoclean; use MRO::Compat; @@ -466,7 +466,7 @@ with some custom actions by sub-classing it: package MyApp::Controller::Foo; use Moose; use namespace::autoclean; - + BEGIN { extends 'MyApp::Base::Controller::ModelBase'; } __PACKAGE__->config( model_name => 'DB::Foo', @@ -537,7 +537,7 @@ Here is some example code for a fictional view: package Catalyst::View::MyView; use Moose; use namespace::autoclean; - + extends 'Catalyst::View'; sub process { @@ -637,7 +637,7 @@ A simple example like this is actually better as a L role, for example: if (!blessed($_[0]) || !$_[0]->isa('Catalyst::Action')); return $uri; }; - + Note that Catalyst will load any Moose Roles in the plugin list, and apply them to your application class. @@ -660,13 +660,13 @@ Here is a stub C method: package CatalystX::Component::Foo; use Moose; use namespace::autoclean; - + extends 'Catalyst::Component'; sub COMPONENT { my $class = shift; # Note: $app is like $c, but since the application isn't fully - # initialized, we don't want to call it $c yet. $config + # initialized, we don't want to call it $c yet. $config # is a hashref of config options possibly set on this component. my ($app, $config) = @_; diff --git a/lib/Catalyst/Manual/Intro.pod b/lib/Catalyst/Manual/Intro.pod index da1d8db..7bff03f 100644 --- a/lib/Catalyst/Manual/Intro.pod +++ b/lib/Catalyst/Manual/Intro.pod @@ -1333,7 +1333,7 @@ If you don't want or need these features then it's perfectly acceptable $c->stash->{message} = 'Hello World!'; $self->check_message( $c, 'test1' ); } - + sub check_message { my ( $self, $c, $first_argument ) = @_; # do something... diff --git a/lib/Catalyst/Manual/Tutorial.pod b/lib/Catalyst/Manual/Tutorial.pod index 12d343b..31eec39 100644 --- a/lib/Catalyst/Manual/Tutorial.pod +++ b/lib/Catalyst/Manual/Tutorial.pod @@ -65,7 +65,7 @@ L =back -Final code tarballs for each chapter of the tutorial are available at +Final code tarballs for each chapter of the tutorial are available at L. @@ -74,7 +74,7 @@ L. =head2 L -Note: Click on the heading in the previous line to jump to the actual +Note: Click on the heading in the previous line to jump to the actual chapter. Below is a "table of contents" for this chapter. =over 4 @@ -100,7 +100,7 @@ WHERE TO GET WORKING CODE =head2 L -Note: Click on the heading in the previous line to jump to the actual +Note: Click on the heading in the previous line to jump to the actual chapter. Below is a "table of contents" for this chapter. =over 4 @@ -134,7 +134,7 @@ CREATE A SIMPLE CONTROLLER AND AN ACTION =head2 L -Note: Click on the heading in the previous line to jump to the actual +Note: Click on the heading in the previous line to jump to the actual chapter. Below is a "table of contents" for this chapter. =over 4 @@ -273,7 +273,7 @@ Return To A Manually-Specified Template =head2 L -Note: Click on the heading in the previous line to jump to the actual +Note: Click on the heading in the previous line to jump to the actual chapter. Below is a "table of contents" for this chapter. =over 4 @@ -411,7 +411,7 @@ Adding Methods to Result Classes =head2 L -Note: Click on the heading in the previous line to jump to the actual +Note: Click on the heading in the previous line to jump to the actual chapter. Below is a "table of contents" for this chapter. =over 4 @@ -509,7 +509,7 @@ Switch To Flash-To-Stash =head2 L -Note: Click on the heading in the previous line to jump to the actual +Note: Click on the heading in the previous line to jump to the actual chapter. Below is a "table of contents" for this chapter. =over 4 @@ -551,7 +551,7 @@ ENABLE MODEL-BASED AUTHORIZATION =head2 L -Note: Click on the heading in the previous line to jump to the actual +Note: Click on the heading in the previous line to jump to the actual chapter. Below is a "table of contents" for this chapter. =over 4 @@ -577,7 +577,7 @@ TT DEBUGGING =head2 L -Note: Click on the heading in the previous line to jump to the actual +Note: Click on the heading in the previous line to jump to the actual chapter. Below is a "table of contents" for this chapter. =over 4 @@ -603,7 +603,7 @@ SUPPORTING BOTH PRODUCTION AND TEST DATABASES =head2 L -Note: Click on the heading in the previous line to jump to the actual +Note: Click on the heading in the previous line to jump to the actual chapter. Below is a "table of contents" for this chapter. =over 4 @@ -617,7 +617,7 @@ ADVANCED CRUD OPTIONS =head2 L -Note: Click on the heading in the previous line to jump to the actual +Note: Click on the heading in the previous line to jump to the actual chapter. Below is a "table of contents" for this chapter. =over 4 @@ -663,8 +663,8 @@ APPENDIX 3: IMPROVED HASHING SCRIPT =head1 THANKS -This tutorial would not have been possible without the input of many -different people in the Catalyst community. In particular, the +This tutorial would not have been possible without the input of many +different people in the Catalyst community. In particular, the primary author would like to thank: =over 4 @@ -690,7 +690,7 @@ key Catalyst modules. Other Catalyst documentation folks like Kieren Diment, Gavin Henry, and Jess Robinson (including their work on the original Catalyst -tutorial). +tutorial). =item * @@ -707,18 +707,18 @@ PostgreSQL content in the Appendix. =item * -People who have emailed me with corrections and suggestions on the -tutorial. As of the most recent release, this include: Florian Ragwitz, -Mauro Andreolini, Jim Howard, Giovanni Gigante, William Moreno, Bryan -Roach, Ashley Berlin, David Kamholz, Kevin Old, Henning Sprang, Jeremy -Jones, David Kurtz, Ingo Wichmann, Shlomi Fish, Murray Walker, Adam -Witney and xenoterracide (Caleb Cushing). Thanks to Devin Austin for -coming up with an initial version of a non-TTSite wrapper page. Also, a -huge thank you to Kiffin Gish for all the hard work on the "database -depluralization" effort and Rafael Kitover for the work on updating the -tutorial to include foreign key support for SQLite. I'm sure I am -missing some names here... apologies for that (please let me know if you -name should be here). +People who have emailed me with corrections and suggestions on the +tutorial. As of the most recent release, this include: Florian Ragwitz, +Mauro Andreolini, Jim Howard, Giovanni Gigante, William Moreno, Bryan +Roach, Ashley Berlin, David Kamholz, Kevin Old, Henning Sprang, Jeremy +Jones, David Kurtz, Ingo Wichmann, Shlomi Fish, Murray Walker, Adam +Witney and xenoterracide (Caleb Cushing). Thanks to Devin Austin for +coming up with an initial version of a non-TTSite wrapper page. Also, a +huge thank you to Kiffin Gish for all the hard work on the "database +depluralization" effort and Rafael Kitover for the work on updating the +tutorial to include foreign key support for SQLite. I'm sure I am +missing some names here... apologies for that (please let me know if you +name should be here). =back diff --git a/lib/Catalyst/Manual/Tutorial/01_Intro.pod b/lib/Catalyst/Manual/Tutorial/01_Intro.pod index bb2a56e..42e53e4 100644 --- a/lib/Catalyst/Manual/Tutorial/01_Intro.pod +++ b/lib/Catalyst/Manual/Tutorial/01_Intro.pod @@ -115,7 +115,7 @@ Subjects covered by the tutorial include: =over 4 -=item * +=item * A simple application that lists and adds books. @@ -125,7 +125,7 @@ The use of L (DBIC) for the model (including some of the more advanced techniques you will probably want to use in your applications). -=item * +=item * How to write CRUD (Create, Read, Update, and Delete) operations in Catalyst. @@ -134,25 +134,25 @@ Catalyst. Authentication ("auth"). -=item * +=item * Role-based authorization ("authz"). -=item * +=item * Attempts to provide an example showing current (5.9) Catalyst practices. -=item * +=item * The use of Template Toolkit (TT). -=item * +=item * Useful techniques for troubleshooting and debugging Catalyst applications. -=item * +=item * The use of SQLite as a database (with code also provided for MySQL and PostgreSQL). (Note: Because we make use of the DBIx::Class Object @@ -160,7 +160,7 @@ Relational Mapping [ORM] layer, out our application will be database agnostic and can easily be used by any of the databases supported by DBIx::Class.) -=item * +=item * The use of L or L for automated form processing and validation. @@ -203,7 +203,7 @@ current directory), but we will keep it short and just use "C<$>". =over 4 -=item 1 +=item 1 Download a Tutorial Virtual Machine image from L @@ -481,11 +481,11 @@ v5.80020 might show up as 5.8002): =over 4 -=item * +=item * Debian 6 (Squeeze) -=item * +=item * Catalyst v5.90002 @@ -493,7 +493,7 @@ Catalyst v5.90002 Catalyst::Devel v1.34 -=item * +=item * DBIx::Class v0.08195 @@ -510,7 +510,7 @@ Template Toolkit v2.22 HTML::FormFu -- v0.09004 -=item * +=item * B You can check the versions you have installed with the following command (note the slash before the space): @@ -529,7 +529,7 @@ or: perl -MCatalyst::Devel -e 'print "$Catalyst::Devel::VERSION\n";' -=item * +=item * This tutorial will show URLs in the format of C, but if you are running your web browser from outside the Tutorial diff --git a/lib/Catalyst/Manual/Tutorial/02_CatalystBasics.pod b/lib/Catalyst/Manual/Tutorial/02_CatalystBasics.pod index 2319bea..c4524ec 100644 --- a/lib/Catalyst/Manual/Tutorial/02_CatalystBasics.pod +++ b/lib/Catalyst/Manual/Tutorial/02_CatalystBasics.pod @@ -146,7 +146,7 @@ directories and files it creates: Changes # Record of application changes lib # Lib directory for your app's Perl modules Hello # Application main code directory - Controller # Directory for Controller modules + Controller # Directory for Controller modules Model # Directory for Models View # Directory for Views Hello.pm # Base application module @@ -164,9 +164,9 @@ directories and files it creates: hello_server.pl # The normal development server hello_test.pl # Test your app from the command line t # Directory for tests - 01app.t # Test scaffold - 02pod.t - 03podcoverage.t + 01app.t # Test scaffold + 02pod.t + 03podcoverage.t Catalyst will "auto-discover" modules in the Controller, Model, and View @@ -202,7 +202,7 @@ C to breakout of the dev server) if you prefer. .----------------------------------------------------------------------------. | Catalyst::Plugin::ConfigLoader 0.30 | '----------------------------------------------------------------------------' - + [debug] Loaded dispatcher "Catalyst::Dispatcher" [debug] Loaded engine "Catalyst::Engine" [debug] Found home "/home/catalyst/Hello" @@ -213,7 +213,7 @@ C to breakout of the dev server) if you prefer. +-----------------------------------------------------------------+----------+ | Hello::Controller::Root | instance | '-----------------------------------------------------------------+----------' - + [debug] Loaded Private actions: .----------------------+--------------------------------------+--------------. | Private | Class | Method | @@ -222,7 +222,7 @@ C to breakout of the dev server) if you prefer. | /end | Hello::Controller::Root | end | | /index | Hello::Controller::Root | index | '----------------------+--------------------------------------+--------------' - + [debug] Loaded Path actions: .-------------------------------------+--------------------------------------. | Path | Private | @@ -230,7 +230,7 @@ C to breakout of the dev server) if you prefer. | / | /index | | / | /default | '-------------------------------------+--------------------------------------' - + [info] Hello powered by Catalyst 5.90002 HTTP::Server::PSGI: Accepting connections at http://0:3000/ @@ -271,7 +271,7 @@ browser. sub index :Path :Args(0) { my ( $self, $c ) = @_; - + # Hello World $c->response->body( $c->welcome_message ); } @@ -318,7 +318,7 @@ C file: sub hello :Global { my ( $self, $c ) = @_; - + $c->response->body("Hello, World!"); } @@ -330,7 +330,7 @@ get output similar to the following: Saw changes to the following files: - /home/catalyst/Hello/lib/Hello/Controller/Root.pm (modify) - + Attempting to restart the server ... [debug] Loaded Private actions: @@ -420,7 +420,7 @@ following: sub hello :Global { my ( $self, $c ) = @_; - + $c->stash(template => 'hello.tt'); } @@ -454,12 +454,12 @@ Although this style is still relatively common, the approach we used previous is becoming more common because it allows you to set multiple stash variables in one line. For example: - $c->stash(template => 'hello.tt', foo => 'bar', + $c->stash(template => 'hello.tt', foo => 'bar', another_thing => 1); You can also set multiple stash values with a hashref: - $c->stash({template => 'hello.tt', foo => 'bar', + $c->stash({template => 'hello.tt', foo => 'bar', another_thing => 1}); Any of these formats work, but the C<$c-Estash(name =E value);> @@ -481,7 +481,7 @@ In C, add the following method: sub test :Local { my ( $self, $c ) = @_; - + $c->stash(username => 'John', template => 'site/test.tt'); } diff --git a/lib/Catalyst/Manual/Tutorial/03_MoreCatalystBasics.pod b/lib/Catalyst/Manual/Tutorial/03_MoreCatalystBasics.pod index 39b818a..9bf0ce3 100644 --- a/lib/Catalyst/Manual/Tutorial/03_MoreCatalystBasics.pod +++ b/lib/Catalyst/Manual/Tutorial/03_MoreCatalystBasics.pod @@ -223,7 +223,7 @@ Then replace it with: -Debug ConfigLoader Static::Simple - + StackTrace /; @@ -311,23 +311,23 @@ each of the three parts of MVC: C, C and C) 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). @@ -549,14 +549,14 @@ First create a directory for book-related TT templates: Then create C in your editor and enter: [% # This is a TT comment. -%] - + [%- # Provide a title -%] [% META title = 'Book List' -%] - + [% # Note That the '-' at the beginning or end of TT code -%] [% # "chomps" the whitespace/newline at that end of the -%] [% # output (use View Source in browser to see the effect) -%] - + [% # Some basic HTML with a loop to display books -%] @@ -886,21 +886,21 @@ left disabled earlier so that your version matches the following 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). @@ -959,7 +959,7 @@ display something like: | Catalyst::Plugin::ConfigLoader 0.30 | | Catalyst::Plugin::StackTrace 0.11 | '----------------------------------------------------------------------------' - + [debug] Loaded dispatcher "Catalyst::Dispatcher" [debug] Loaded engine "Catalyst::Engine" [debug] Found home "/home/catalyst/MyApp" @@ -976,7 +976,7 @@ display something like: | MyApp::Model::DB::BookAuthor | class | | MyApp::View::HTML | instance | '-----------------------------------------------------------------+----------' - + [debug] Loaded Private actions: .----------------------+--------------------------------------+--------------. | Private | Class | Method | @@ -987,7 +987,7 @@ display something like: | /books/index | MyApp::Controller::Books | index | | /books/list | MyApp::Controller::Books | list | '----------------------+--------------------------------------+--------------' - + [debug] Loaded Path actions: .-------------------------------------+--------------------------------------. | Path | Private | @@ -997,7 +997,7 @@ display something like: | /books | /books/index | | /books/list | /books/list | '-------------------------------------+--------------------------------------' - + [info] MyApp powered by Catalyst 5.80020 HTTP::Server::PSGI: Accepting connections at http://0:3000 @@ -1091,7 +1091,7 @@ the tutorial, open C and input the following: [% template.title or "My Catalyst App!" %] - +
- +
- +
[%# Status and error messages %] [% status_msg %] @@ -1119,10 +1119,10 @@ the tutorial, open C and input the following: [% content %]
- +
- + @@ -1237,15 +1237,15 @@ keys. For example, take a look at C and notice the following code: =head1 RELATIONS - + =head2 book_authors - + Type: has_many - + Related object: L - + =cut - + __PACKAGE__->has_many( "book_authors", "MyApp::Schema::Result::BookAuthor", @@ -1306,15 +1306,15 @@ there is a C relationship defined that acts as the "mirror image" to the C relationship we just looked at above: =head1 RELATIONS - + =head2 book - + Type: belongs_to - + Related object: L - + =cut - + __PACKAGE__->belongs_to( "book", "MyApp::Schema::Result::Book", @@ -1442,15 +1442,15 @@ debug output (one for each book as the authors are being retrieved by DBIx::Class): SELECT me.id, me.title, me.rating FROM book me: - SELECT author.id, author.first_name, author.last_name FROM book_author 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 + 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 + 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 + 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 + 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 that we are using "| html", a @@ -1564,7 +1564,7 @@ this URL: You should get a page with the following message at the top: - Caught exception in MyApp::Controller::Root->end "Forced debug - + Caught exception in MyApp::Controller::Root->end "Forced debug - Scrubbed output at /usr/share/perl5/Catalyst/Action/RenderView.pm line 46." Along with a summary of your application's state at the end of the @@ -1594,21 +1594,21 @@ this line to match the following (only the C<$c-Estash-E{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). diff --git a/lib/Catalyst/Manual/Tutorial/04_BasicCRUD.pod b/lib/Catalyst/Manual/Tutorial/04_BasicCRUD.pod index f84c3d7..0df6ab2 100644 --- a/lib/Catalyst/Manual/Tutorial/04_BasicCRUD.pod +++ b/lib/Catalyst/Manual/Tutorial/04_BasicCRUD.pod @@ -93,35 +93,35 @@ submission in the sections that follow). Edit C and enter the following method: =head2 url_create - + Create a book with the supplied title, rating, and author - + =cut - + sub url_create :Local { # In addition to self & context, get the title, rating, & # author_id args from the URL. Note that Catalyst automatically # puts extra information after the "//model('DB::Book')->create({ title => $title, rating => $rating }); - + # Add a record to the join table for this book, mapping to # appropriate author $book->add_to_book_authors({author_id => $author_id}); # Note: Above is a shortcut for this: # $book->create_related('book_authors', {author_id => $author_id}); - + # Assign the Book object to the stash for display and set template $c->stash(book => $book, template => 'books/create_done.tt2'); - + # Disable caching for this page $c->response->header('Cache-Control' => 'no-cache'); } @@ -152,7 +152,7 @@ Edit C and then enter: [% # Not a good idea for production use, though. :-) 'Indent=1' is -%] [% # optional, but prevents "massive indenting" of deeply nested objects -%] [% USE Dumper(Indent=1) -%] - + [% # Set the page title. META can 'go back' and set values in templates -%] [% # that have been processed 'before' this template (here it's updating -%] [% # the title in the root/src/wrapper.tt2 wrapper template). Note that -%] @@ -160,20 +160,20 @@ Edit C and then enter: [% # interpolation -- if you need dynamic/interpolated content in your -%] [% # title, set "$c->stash(title => $something)" in the controller). -%] [% META title = 'Book Created' %] - + [% # Output information about the record that was added. First title. -%]

Added book '[% book.title %]' - + [% # Then, output the last name of the first author -%] by '[% book.authors.first.last_name %]' - + [% # Then, output the rating for the book that was added -%] with a rating of [% book.rating %].

- + [% # Provide a link back to the list page. 'c.uri_for' builds -%] [% # a full URI; e.g., 'http://localhost:3000/books/list' -%]

Return to list

- + [% # Try out the TT Dumper (for development only!) -%]
     Dump of the 'book' variable:
@@ -220,8 +220,8 @@ are now six books shown (if necessary, Shift+Reload or Ctrl+Reload your
 browser at the C page).  You should now see the six DBIC
 debug messages similar to the following (where N=1-6):
 
-    SELECT author.id, author.first_name, author.last_name 
-        FROM book_author me  JOIN author author 
+    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 = ? ): 'N'
 
 
@@ -237,11 +237,11 @@ to match the following:
     sub url_create :Chained('/') :PathPart('books/url_create') :Args(3) {
         # In addition to self & context, get the title, rating, &
         # author_id args from the URL.  Note that Catalyst automatically
-        # puts the first 3 arguments worth of extra information after the 
+        # puts the first 3 arguments worth of extra information after the
         # "// in your editor and add the following
 method:
 
     =head2 base
-    
+
     Can place common logic to start chained dispatch here
-    
+
     =cut
-    
+
     sub base :Chained('/') :PathPart('books') :CaptureArgs(0) {
         my ($self, $c) = @_;
-    
+
         # Store the ResultSet in stash so it's available for other methods
         $c->stash(resultset => $c->model('DB::Book'));
-    
+
         # Print a message to the debug log
         $c->log->debug('*** INSIDE BASE METHOD ***');
     }
@@ -484,14 +484,14 @@ for better options for handling web-based forms).
 Edit C and add the following method:
 
     =head2 form_create
-    
+
     Display form to collect information for book to create
-    
+
     =cut
-    
+
     sub form_create :Chained('base') :PathPart('form_create') :Args(0) {
         my ($self, $c) = @_;
-    
+
         # Set the TT template to use
         $c->stash(template => 'books/form_create.tt2');
     }
@@ -504,7 +504,7 @@ This action simply invokes a view containing a form to create a book.
 Open C in your editor and enter:
 
     [% META title = 'Manual Form Book Create' -%]
-    
+
     
TitleRatingAuthor(s)
@@ -524,19 +524,19 @@ Edit C and add the following method to save the form information to the database: =head2 form_create_do - + Take information from form and add to database - + =cut - + sub form_create_do :Chained('base') :PathPart('form_create_do') :Args(0) { my ($self, $c) = @_; - + # Retrieve the values from the form my $title = $c->request->params->{title} || 'N/A'; my $rating = $c->request->params->{rating} || 'N/A'; my $author_id = $c->request->params->{author_id} || '1'; - + # Create the book my $book = $c->model('DB::Book')->create({ title => $title, @@ -546,7 +546,7 @@ save the form information to the database: $book->add_to_book_authors({author_id => $author_id}); # Note: Above is a shortcut for this: # $book->create_related('book_authors', {author_id => $author_id}); - + # Store new model object in stash and set template $c->stash(book => $book, template => 'books/create_done.tt2'); @@ -596,14 +596,14 @@ Edit C and update it to match the following header, and 2) the five lines for the Delete link near the bottom): [% # This is a TT comment. -%] - + [%- # Provide a title -%] [% META title = 'Book List' -%] - + [% # Note That the '-' at the beginning or end of TT code -%] [% # "chomps" the whitespace/newline at that end of the -%] [% # output (use View Source in browser to see the effect) -%] - + [% # Some basic HTML with a loop to display books -%]
Title:
@@ -693,24 +693,24 @@ To add the C method, edit C and add the following code: =head2 object - + Fetch the specified book object based on the book ID and store it in the stash - + =cut - + sub object :Chained('base') :PathPart('id') :CaptureArgs(1) { # $id = primary key of book to delete my ($self, $c, $id) = @_; - + # Find the book object and store it in the stash $c->stash(object => $c->stash->{resultset}->find($id)); - + # Make sure the lookup was successful. You would probably # want to do something like this in a real app: # $c->detach('/error_404') if !$c->stash->{object}; die "Book $id not found!" if !$c->stash->{object}; - + # Print a message to the debug log $c->log->debug("*** INSIDE OBJECT METHOD for obj id=$id ***"); } @@ -725,21 +725,21 @@ Open C in your editor and add the following method: =head2 delete - + Delete a book - + =cut - + sub delete :Chained('object') :PathPart('delete') :Args(0) { my ($self, $c) = @_; - + # Use the book object saved by 'object' and delete it along # with related 'book_author' entries $c->stash->{object}->delete; - + # Set a status message to be displayed at the top of the view $c->stash->{status_msg} = "Book deleted."; - + # Forward to the list action/method in this controller $c->forward('list'); } @@ -818,21 +818,21 @@ C and edit the existing C method to match: =head2 delete - + Delete a book - + =cut - + sub delete :Chained('object') :PathPart('delete') :Args(0) { my ($self, $c) = @_; - + # Use the book object saved by 'object' and delete it along # with related 'book_author' entries $c->stash->{object}->delete; - + # Set a status message to be displayed at the top of the view $c->stash->{status_msg} = "Book deleted."; - + # Redirect the user back to the list page. Note the use # of $self->action_for as earlier in this section (BasicCRUD) $c->response->redirect($c->uri_for($self->action_for('list'))); @@ -863,18 +863,18 @@ C and update the existing C method to match the following: =head2 delete - + Delete a book - + =cut - + sub delete :Chained('object') :PathPart('delete') :Args(0) { my ($self, $c) = @_; - + # Use the book object saved by 'object' and delete it along # with related 'book_author' entries $c->stash->{object}->delete; - + # Redirect the user back to the list page with status msg as an arg $c->response->redirect($c->uri_for($self->action_for('list'), {status_msg => "Book deleted."})); @@ -1036,7 +1036,7 @@ entered for it (see the last line in the listing below): Notice in the debug log that the SQL DBIC generated has changed to incorporate the datetime logic: - INSERT INTO book ( created, rating, title, updated ) VALUES ( ?, ?, ?, ? ): + INSERT INTO book ( created, rating, title, updated ) VALUES ( ?, ?, ?, ? ): '2010-02-16 04:18:42', '5', 'TCPIP_Illustrated_Vol-2', '2010-02-16 04:18:42' INSERT INTO book_author ( author_id, book_id ) VALUES ( ?, ? ): '4', '10' @@ -1060,47 +1060,47 @@ a directory where DBIx::Class will look for our ResultSet Class: Then open C and enter the following: package MyApp::Schema::ResultSet::Book; - + use strict; use warnings; use base 'DBIx::Class::ResultSet'; - + =head2 created_after - + A predefined search for recently added books - + =cut - + sub created_after { my ($self, $datetime) = @_; - + my $date_str = $self->result_source->schema->storage ->datetime_parser->format_datetime($datetime); - + return $self->search({ created => { '>' => $date_str } }); } - + 1; Then add the following method to the C: =head2 list_recent - + List recently created books - + =cut - + sub list_recent :Chained('base') :PathPart('list_recent') :Args(1) { my ($self, $c, $mins) = @_; - + # Retrieve all of the book records as book model objects and store in the # stash where they can be accessed by the TT template, but only # retrieve books created within the last $min number of minutes $c->stash(books => [$c->model('DB::Book') ->created_after(DateTime->now->subtract(minutes => $mins))]); - + # 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). @@ -1136,14 +1136,14 @@ C controller that lists books that are both recent I have the following method: =head2 list_recent_tcp - + List recently created books - + =cut - + sub list_recent_tcp :Chained('base') :PathPart('list_recent_tcp') :Args(1) { my ($self, $c, $mins) = @_; - + # Retrieve all of the book records as book model objects and store in the # stash where they can be accessed by the TT template, but only # retrieve books created within the last $min number of minutes @@ -1153,7 +1153,7 @@ the following method: ->created_after(DateTime->now->subtract(minutes => $mins)) ->search({title => {'like', '%TCP%'}}) ]); - + # 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). @@ -1175,7 +1175,7 @@ you added books to your database): Take a look at the DBIC_TRACE output in the development server log for the first URL and you should see something similar to the following: - SELECT me.id, me.title, me.rating, me.created, me.updated FROM book me + SELECT me.id, me.title, me.rating, me.created, me.updated FROM book me WHERE ( ( title LIKE ? AND created > ? ) ): '%TCP%', '2010-02-16 02:49:32' However, let's not pollute our controller code with this raw "TCP" query @@ -1184,14 +1184,14 @@ ResultSet Class. To do this, open C and add the following method: =head2 title_like - + A predefined search for books with a 'LIKE' search in the string - + =cut - + sub title_like { my ($self, $title_str) = @_; - + return $self->search({ title => { 'like' => "%$title_str%" } }); @@ -1204,14 +1204,14 @@ replaced the C<-Esearch> line with the C<-Etitle_like> line shown here -- the rest of the method should be the same): =head2 list_recent_tcp - + List recently created books - + =cut - + sub list_recent_tcp :Chained('base') :PathPart('list_recent_tcp') :Args(1) { my ($self, $c, $mins) = @_; - + # Retrieve all of the book records as book model objects and store in the # stash where they can be accessed by the TT template, but only # retrieve books created within the last $min number of minutes @@ -1221,7 +1221,7 @@ shown here -- the rest of the method should be the same): ->created_after(DateTime->now->subtract(minutes => $mins)) ->title_like('TCP') ]); - + # 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). @@ -1251,7 +1251,7 @@ always, it must be above the closing "C<1;>"): # sub full_name { my ($self) = @_; - + return $self->first_name . ' ' . $self->last_name; } @@ -1320,14 +1320,14 @@ return the number of authors for a book. Open C and add the following method: =head2 author_count - + Return the number of authors for the current book - + =cut - + sub author_count { my ($self) = @_; - + # Use the 'many_to_many' relationship to fetch all of the authors for the current # and the 'count' method in DBIx::Class::ResultSet to get a SQL COUNT return $self->authors->count; @@ -1337,21 +1337,21 @@ Next, let's add a method to return a list of authors for a book to the same C file: =head2 author_list - + Return a comma-separated list of authors for the current book - + =cut - + sub author_list { my ($self) = @_; - - # Loop through all authors for the current book, calling all the 'full_name' + + # Loop through all authors for the current book, calling all the 'full_name' # Result Class method for each my @names; foreach my $author ($self->authors) { push(@names, $author->full_name); } - + return join(', ', @names); } diff --git a/lib/Catalyst/Manual/Tutorial/05_Authentication.pod b/lib/Catalyst/Manual/Tutorial/05_Authentication.pod index 21ce7e0..adf66fc 100644 --- a/lib/Catalyst/Manual/Tutorial/05_Authentication.pod +++ b/lib/Catalyst/Manual/Tutorial/05_Authentication.pod @@ -225,11 +225,11 @@ C is new): -Debug ConfigLoader Static::Simple - + StackTrace - + Authentication - + Session Session::Store::File Session::State::Cookie @@ -349,18 +349,18 @@ Then open C, and update the definition of C to match: =head2 index - + Login logic - + =cut - + sub index :Path :Args(0) { my ($self, $c) = @_; - + # Get the username and password from form my $username = $c->request->params->{username}; my $password = $c->request->params->{password}; - + # If the username and password values were found in form if ($username && $password) { # Attempt to log the user in @@ -379,7 +379,7 @@ C to match: $c->stash(error_msg => "Empty username or password.") unless ($c->user_exists); } - + # If either of above don't work out, send to the login page $c->stash(template => 'login.tt2'); } @@ -411,17 +411,17 @@ Next, update the corresponding method in C to match: =head2 index - + Logout logic - + =cut - + sub index :Path :Args(0) { my ($self, $c) = @_; - + # Clear the user's state $c->logout; - + # Send the user to the starting point $c->response->redirect($c->uri_for('/')); } @@ -432,7 +432,7 @@ C to match: Create a login form by opening C and inserting: [% META title = 'Login' %] - +
TitleRatingAuthor(s)Links
@@ -463,17 +463,17 @@ Edit the existing C class file and insert the following method: =head2 auto - + Check if there is a user and, if not, forward to login page - + =cut - + # Note that 'auto' runs after 'begin' but before your actions and that # 'auto's "chain" (all from application path to most specific class are run) # See the 'Actions' section of 'Catalyst::Manual::Intro' for more info. sub auto :Private { my ($self, $c) = @_; - + # Allow unauthenticated users to reach the login page. This # allows unauthenticated users to reach any action in the Login # controller. To lock it down to a single action, we could use: @@ -483,7 +483,7 @@ the following method: if ($c->controller eq $c->controller('Login')) { return 1; } - + # If a user doesn't exist, force login if (!$c->user_exists) { # Dump a log message to the development server debug output @@ -493,7 +493,7 @@ the following method: # Return 0 to cancel 'post-auto' processing and prevent use of application return 0; } - + # User found, so return 1 to continue with processing after this 'auto' return 1; } @@ -671,16 +671,16 @@ file C in your editor and enter the following text: #!/usr/bin/perl - + use strict; use warnings; - + use MyApp::Schema; - + my $schema = MyApp::Schema->connect('dbi:SQLite:myapp.db'); - + my @users = $schema->resultset('User')->all; - + foreach my $user (@users) { $user->password('mypass'); $user->update; @@ -772,21 +772,21 @@ match the following (everything after the model search line of code has changed): =head2 delete - + Delete a book - + =cut - + sub delete :Chained('object') :PathPart('delete') :Args(0) { my ($self, $c) = @_; - + # Use the book object saved by 'object' and delete it along # with related 'book_authors' entries $c->stash->{object}->delete; - + # Use 'flash' to save information across requests until it's read $c->flash->{status_msg} = "Book deleted"; - + # Redirect the user back to the list page $c->response->redirect($c->uri_for($self->action_for('list'))); } @@ -833,7 +833,7 @@ we used above. Consult L for additional information. -=head2 Switch To Catalyst::Plugin::StatusMessages +=head2 Switch To Catalyst::Plugin::StatusMessages Although the query parameter technique we used in L and the C @@ -863,15 +863,15 @@ C to the list of plugins: -Debug ConfigLoader Static::Simple - + StackTrace - + Authentication - + Session Session::Store::File Session::State::Cookie - + StatusMessage /; @@ -880,14 +880,14 @@ action to match the following: sub delete :Chained('object') :PathPart('delete') :Args(0) { my ($self, $c) = @_; - + # Saved the PK id for status_msg below my $id = $c->stash->{object}->id; - + # Use the book object saved by 'object' and delete it along # with related 'book_authors' entries $c->stash->{object}->delete; - + # Redirect the user back to the list page $c->response->redirect($c->uri_for($self->action_for('list'), {mid => $c->set_status_msg("Deleted book $id")})); @@ -909,13 +909,13 @@ match: sub base :Chained('/') :PathPart('books') :CaptureArgs(0) { my ($self, $c) = @_; - + # Store the ResultSet in stash so it's available for other methods $c->stash(resultset => $c->model('DB::Book')); - + # Print a message to the debug log $c->log->debug('*** INSIDE BASE METHOD ***'); - + # Load status messages $c->load_status_msgs; } diff --git a/lib/Catalyst/Manual/Tutorial/06_Authorization.pod b/lib/Catalyst/Manual/Tutorial/06_Authorization.pod index 5ef7ac4..35f028c 100644 --- a/lib/Catalyst/Manual/Tutorial/06_Authorization.pod +++ b/lib/Catalyst/Manual/Tutorial/06_Authorization.pod @@ -85,12 +85,12 @@ Edit C and add C to the list: -Debug ConfigLoader Static::Simple - + StackTrace - + Authentication Authorization::Roles - + Session Session::Store::File Session::State::Cookie @@ -111,12 +111,12 @@ lines to the bottom of the file: ...

Hello [% c.user.username %], you have the following roles:

- +
    [% # Dump list of roles -%] [% FOR role = c.user.roles %]
  • [% role %]
  • [% END %]
- +

[% # Add some simple role-specific logic to template %] [% # Use $c->check_user_roles() to check authz -%] @@ -124,7 +124,7 @@ lines to the bottom of the file: [% # Give normal users a link for 'logout' %] User Logout [% END %] - + [% # Can also use $c->user->check_roles() to check authz -%] [% IF c.check_user_roles('admin') %] [% # Give admin users a link for 'create' %] @@ -149,18 +149,18 @@ admin-level users by editing C and updating C to match the following code: =head2 url_create - + Create a book with the supplied title and rating, with manual authorization - + =cut - + sub url_create :Chained('base') :PathPart('url_create') :Args(3) { # In addition to self & context, get the title, rating & author_id args # from the URL. Note that Catalyst automatically puts extra information # after the "//check_user_roles('admin')) { # Call create() on the book model object. Pass the table @@ -169,13 +169,13 @@ updating C to match the following code: title => $title, rating => $rating }); - + # Add a record to the join table for this book, mapping to # appropriate author $book->add_to_book_authors({author_id => $author_id}); # Note: Above is a shortcut for this: # $book->create_related('book_authors', {author_id => $author_id}); - + # Assign the Book object to the stash and set template $c->stash(book => $book, template => 'books/create_done.tt2'); @@ -243,14 +243,14 @@ C and add the following method (be sure to add it below the "C" line): =head2 delete_allowed_by - + Can the specified user delete the current book? - + =cut - + sub delete_allowed_by { my ($self, $user) = @_; - + # Only allow delete if user has 'admin' role return $user->has_role('admin'); } @@ -261,15 +261,15 @@ C and add the following method below the "C" line: =head2 has_role - + Check if a user has the specified role - + =cut - + use Perl6::Junction qw/any/; sub has_role { my ($self, $role) = @_; - + # Does this user posses the required role? return any(map { $_->role } $self->roles) eq $role; } @@ -291,25 +291,25 @@ C and update the C method to match the following code: =head2 delete - + Delete a book - + =cut - + sub delete :Chained('object') :PathPart('delete') :Args(0) { my ($self, $c) = @_; - + # Check permissions $c->detach('/error_noperms') unless $c->stash->{object}->delete_allowed_by($c->user->get_object); - + # Saved the PK id for status_msg below my $id = $c->stash->{object}->id; - + # Use the book object saved by 'object' and delete it along # with related 'book_authors' entries $c->stash->{object}->delete; - + # Redirect the user back to the list page $c->response->redirect($c->uri_for($self->action_for('list'), {mid => $c->set_status_msg("Deleted book $id")})); @@ -321,14 +321,14 @@ for the '/error_noperms' action to work. Open C and add this method: =head2 error_noperms - + Permissions error screen - + =cut - + sub error_noperms :Chained('/') :PathPart('error_noperms') :Args(0) { my ($self, $c) = @_; - + $c->stash(template => 'error_noperms.tt2'); } diff --git a/lib/Catalyst/Manual/Tutorial/07_Debugging.pod b/lib/Catalyst/Manual/Tutorial/07_Debugging.pod index 9937274..bb9a558 100644 --- a/lib/Catalyst/Manual/Tutorial/07_Debugging.pod +++ b/lib/Catalyst/Manual/Tutorial/07_Debugging.pod @@ -70,11 +70,11 @@ camps: =over 4 -=item * +=item * Fans of C and C statements embedded in the code. -=item * +=item * Fans of interactive debuggers. @@ -90,7 +90,7 @@ Folks in the former group can use Catalyst's C<$c-Elog> facility. following code to a controller action method: $c->log->info("Starting the foreach loop here"); - + $c->log->debug("Value of \$id is: ".$id); Then the Catalyst development server will display your message along @@ -141,13 +141,13 @@ you can obviously indent them if you prefer): # 'Context' that's used to 'glue together' the various components # that make up the application my ($self, $c) = @_; - + $DB::single=1; - + # 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. $c->stash->{template} = 'books/list.tt2'; @@ -170,16 +170,16 @@ simply prepend C to the front of C