From: Kennedy Clark Date: Sun, 7 Dec 2008 21:17:07 +0000 (+0000) Subject: Remove TTSite in favor of manually created wrapper template and css X-Git-Tag: v5.8005~248 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Manual.git;a=commitdiff_plain;h=1390ef0ecd30a0dcfe59f212353ed81094fdf64a Remove TTSite in favor of manually created wrapper template and css Update and test for Ubuntu 8.10 (Cat 5.7014, C::Devel 1.07, DBIC 0.08010, etc.) Change flow of MoreCatalystBasics.pod (eg, use incremental build where run in smaller chunks) Change MyApp.pm from "use Catalyst" to "__PACKAGE__->setup()" Whitespace cleanup Move TT Debugging section from MoreCatalystBasics.pod to Debugging.pod Misc edits --- diff --git a/lib/Catalyst/Manual/Tutorial/Appendices.pod b/lib/Catalyst/Manual/Tutorial/Appendices.pod index c9c548a..6b471ed 100644 --- a/lib/Catalyst/Manual/Tutorial/Appendices.pod +++ b/lib/Catalyst/Manual/Tutorial/Appendices.pod @@ -457,60 +457,59 @@ Create the C<.sql> file and load the data: Open the C in your editor and enter: - -- - -- Create a very simple database to hold book and author information - -- - -- The sequence is how we get a unique id in PostgreSQL - -- - CREATE SEQUENCE books_seq START 5 ; - SELECT nextval ('books_seq'); - - CREATE TABLE books ( - id INTEGER PRIMARY KEY DEFAULT nextval('books_seq'), - title TEXT , - rating INTEGER - ); - - -- 'book_authors' is a many-to-many join table between books & authors - CREATE TABLE book_authors ( - book_id INTEGER, - author_id INTEGER, - PRIMARY KEY (book_id, author_id) - - ); - - CREATE SEQUENCE authors_seq START 8 ; - SELECT nextval ('authors_seq'); - - CREATE TABLE authors ( - id INTEGER PRIMARY KEY DEFAULT nextval('authors_seq'), - first_name TEXT, - last_name TEXT - ); - --- - --- Load some sample data - --- - INSERT INTO books VALUES (1, 'CCSP SNRS Exam Certification Guide', 5); - INSERT INTO books VALUES (2, 'TCP/IP Illustrated, Volume 1', 5); - INSERT INTO books VALUES (3, 'Internetworking with TCP/IP Vol.1', 4); - INSERT INTO books VALUES (4, 'Perl Cookbook', 5); - INSERT INTO books VALUES (5, 'Designing with Web Standards', 5); - INSERT INTO authors VALUES (1, 'Greg', 'Bastien'); - INSERT INTO authors VALUES (2, 'Sara', 'Nasseh'); - INSERT INTO authors VALUES (3, 'Christian', 'Degu'); - INSERT INTO authors VALUES (4, 'Richard', 'Stevens'); - INSERT INTO authors VALUES (5, 'Douglas', 'Comer'); - INSERT INTO authors VALUES (6, 'Tom', 'Christiansen'); - INSERT INTO authors VALUES (7, 'Nathan', 'Torkington'); - INSERT INTO authors VALUES (8, 'Jeffrey', 'Zeldman'); - INSERT INTO book_authors VALUES (1, 1); - INSERT INTO book_authors VALUES (1, 2); - INSERT INTO book_authors VALUES (1, 3); - INSERT INTO book_authors VALUES (2, 4); - INSERT INTO book_authors VALUES (3, 5); - INSERT INTO book_authors VALUES (4, 6); - INSERT INTO book_authors VALUES (4, 7); - INSERT INTO book_authors VALUES (5, 8); + -- + -- Create a very simple database to hold book and author information + -- + -- The sequence is how we get a unique id in PostgreSQL + -- + CREATE SEQUENCE books_seq START 5 ; + SELECT nextval ('books_seq'); + + CREATE TABLE books ( + id INTEGER PRIMARY KEY DEFAULT nextval('books_seq'), + title TEXT , + rating INTEGER + ); + + -- 'book_authors' is a many-to-many join table between books & authors + CREATE TABLE book_authors ( + book_id INTEGER, + author_id INTEGER, + PRIMARY KEY (book_id, author_id) + ); + + CREATE SEQUENCE authors_seq START 8 ; + SELECT nextval ('authors_seq'); + + CREATE TABLE authors ( + id INTEGER PRIMARY KEY DEFAULT nextval('authors_seq'), + first_name TEXT, + last_name TEXT + ); + --- + --- Load some sample data + --- + INSERT INTO books VALUES (1, 'CCSP SNRS Exam Certification Guide', 5); + INSERT INTO books VALUES (2, 'TCP/IP Illustrated, Volume 1', 5); + INSERT INTO books VALUES (3, 'Internetworking with TCP/IP Vol.1', 4); + INSERT INTO books VALUES (4, 'Perl Cookbook', 5); + INSERT INTO books VALUES (5, 'Designing with Web Standards', 5); + INSERT INTO authors VALUES (1, 'Greg', 'Bastien'); + INSERT INTO authors VALUES (2, 'Sara', 'Nasseh'); + INSERT INTO authors VALUES (3, 'Christian', 'Degu'); + INSERT INTO authors VALUES (4, 'Richard', 'Stevens'); + INSERT INTO authors VALUES (5, 'Douglas', 'Comer'); + INSERT INTO authors VALUES (6, 'Tom', 'Christiansen'); + INSERT INTO authors VALUES (7, 'Nathan', 'Torkington'); + INSERT INTO authors VALUES (8, 'Jeffrey', 'Zeldman'); + INSERT INTO book_authors VALUES (1, 1); + INSERT INTO book_authors VALUES (1, 2); + INSERT INTO book_authors VALUES (1, 3); + INSERT INTO book_authors VALUES (2, 4); + INSERT INTO book_authors VALUES (3, 5); + INSERT INTO book_authors VALUES (4, 6); + INSERT INTO book_authors VALUES (4, 7); + INSERT INTO book_authors VALUES (5, 8); =item * @@ -519,21 +518,21 @@ Load the data: $ psql -U catmyapp -W mycatapp Password for user catmyapp: catalyst Welcome to psql 8.1.8, the PostgreSQL interactive terminal. - + Type: \copyright for distribution terms \h for help with SQL commands \? for help with psql commands \g or terminate with semicolon to execute query \q to quit - + mycatapp=> \i myapp01_psql.sql - + CREATE SEQUENCE nextval --------- 5 (1 row) - + psql:myapp01_psql.sql:11: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "books_pkey" for table "books" CREATE TABLE psql:myapp01_psql.sql:19: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "book_authors_pkey" for table @@ -544,7 +543,7 @@ Load the data: --------- 8 (1 row) - + psql:myapp01_psql.sql:30: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "authors_pkey" for table "authors" CREATE TABLE INSERT 0 1 @@ -565,7 +564,7 @@ Make sure the data loaded correctly: public | book_authors | table | catmyapp public | books | table | catmyapp (3 rows) - + mycatapp=> select * from books; id | title | rating ----+------------------------------------+-------- @@ -575,7 +574,7 @@ Make sure the data loaded correctly: 4 | Perl Cookbook | 5 5 | Designing with Web Standards | 5 (5 rows) - + mycatapp=> \q =back @@ -585,13 +584,13 @@ Make sure the data loaded correctly: After the steps where you: edit lib/MyApp.pm - + create lib/MyAppDB.pm - + create lib/MyAppDB/Book.pm - + create lib/MyAppDB/Author.pm - + create lib/MyAppDB/BookAuthor.pm @@ -619,10 +618,10 @@ Open C in your editor and enter: -- -- Add users and roles tables, along with a many-to-many join table -- - + CREATE SEQUENCE users_seq START 3 ; SELECT nextval ('users_seq'); - + CREATE TABLE users ( id INTEGER PRIMARY KEY DEFAULT nextval('users_seq'), username TEXT, @@ -632,21 +631,21 @@ Open C in your editor and enter: last_name TEXT, active INTEGER ); - + CREATE SEQUENCE roles_seq START 2 ; SELECT nextval ('roles_seq'); - + CREATE TABLE roles ( id INTEGER PRIMARY KEY DEFAULT nextval('roles_seq'), role TEXT ); - + CREATE TABLE user_roles ( user_id INTEGER, role_id INTEGER, PRIMARY KEY (user_id, role_id) ); - + -- -- Load up some initial test data -- @@ -667,21 +666,21 @@ Load the data: $ psql -U catmyapp -W mycatapp Password for user catmyapp: catalyst Welcome to psql 8.1.8, the PostgreSQL interactive terminal. - + Type: \copyright for distribution terms \h for help with SQL commands \? for help with psql commands \g or terminate with semicolon to execute query \q to quit - + mycatapp=> \i myapp02_psql.sql - + CREATE SEQUENCE nextval --------- 3 (1 row) - + psql:myapp02_psql.sql:16: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "users_pkey" for table "users" CREATE TABLE CREATE SEQUENCE @@ -689,7 +688,7 @@ Load the data: --------- 2 (1 row) - + psql:myapp02_psql.sql:24: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "roles_pkey" for table "roles" CREATE TABLE psql:myapp02_psql.sql:30: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "user_roles_pkey" for table "user_roles" @@ -704,7 +703,7 @@ Load the data: INSERT 0 1 INSERT 0 1 mycatapp=> - + mycatapp=> select * from users; id | username | password | email_address | first_name | last_name | active ----+----------+----------+---------------+------------+-----------+-------- @@ -734,13 +733,13 @@ Load in the data $ psql -U catmyapp -W mycatapp Password for user catmyapp: Welcome to psql 8.1.8, the PostgreSQL interactive terminal. - + Type: \copyright for distribution terms \h for help with SQL commands \? for help with psql commands \g or terminate with semicolon to execute query \q to quit - + mycatapp=> \i myapp03_psql.sql UPDATE 1 UPDATE 1 diff --git a/lib/Catalyst/Manual/Tutorial/Authentication.pod b/lib/Catalyst/Manual/Tutorial/Authentication.pod index b670e67..590a51d 100644 --- a/lib/Catalyst/Manual/Tutorial/Authentication.pod +++ b/lib/Catalyst/Manual/Tutorial/Authentication.pod @@ -65,7 +65,7 @@ cleartext authentication and 2) hash-based authentication. You can checkout the source code for this example from the catalyst subversion repository as per the instructions in -L +L. =head1 BASIC AUTHENTICATION @@ -126,6 +126,12 @@ the new tables added in the previous step, let's use the C option on the DBIC model helper to do most of the work for us: $ script/myapp_create.pl model DB DBIC::Schema MyApp::Schema create=static dbi:SQLite:myapp.db + exists "/root/dev/MyApp/script/../lib/MyApp/Model" + exists "/root/dev/MyApp/script/../t" + Dumping manual schema for MyApp::Schema to directory /root/dev/MyApp/script/../lib ... + Schema dump completed. + exists "/root/dev/MyApp/script/../lib/MyApp/Model/DB.pm" + $ $ ls lib/MyApp/Schema Authors.pm BookAuthors.pm Books.pm Roles.pm UserRoles.pm Users.pm @@ -136,7 +142,6 @@ files, those changes would have only been written above the C<# DO NOT MODIFY THIS OR ANYTHING ABOVE!> comment and your hand-editted enhancements would have been preserved. - Speaking of "hand-editted enhancements," we should now add relationship information to the three new result source files. Edit each of these files and add the following information between the C<# @@ -147,14 +152,14 @@ C: # # 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 __PACKAGE__->has_many(map_user_role => 'MyApp::Schema::UserRoles', 'user_id'); - + # many_to_many(): # args: # 1) Name of relationship, DBIC will create accessor with this name @@ -169,7 +174,7 @@ C: # # Set relationships: # - + # has_many(): # args: # 1) Name of relationship, DBIC will create accessor with this name @@ -183,14 +188,14 @@ C: # # 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(user => 'MyApp::Schema::Users', 'user_id'); - + # belongs_to(): # args: # 1) Name of relationship, DBIC will create accessor with this name @@ -247,19 +252,19 @@ by Catalyst under C. Edit C and update it as follows (everything below C is new): - use Catalyst qw/ + __PACKAGE__->setup(qw/ -Debug ConfigLoader Static::Simple - + StackTrace - + Authentication - + Session Session::Store::FastMmap Session::State::Cookie - /; + /); The C plugin supports Authentication while the C plugins are required to maintain state across multiple HTTP @@ -304,6 +309,8 @@ L where to locate information in your database. To do this, edit the C file and update it to match: + # rename this file to MyApp.yml and put a : in front of "name" if + # you want to use yaml like in old versions of Catalyst name MyApp default_realm dbic @@ -343,6 +350,7 @@ Note that you can use many other config file formats with catalyst. See L for details. + =head2 Add Login and Logout Controllers Use the Catalyst create script to create two stub controller files: @@ -366,18 +374,18 @@ line: Then update it 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 @@ -391,7 +399,7 @@ Then update it to match: $c->stash->{error_msg} = "Bad username or password."; } } - + # If either of above don't work out, send to the login page $c->stash->{template} = 'login.tt2'; } @@ -403,10 +411,10 @@ will stay at the login page and receive an error message. If the C and C values are not present in the form, the user will be taken to the empty login form. -Note that we could have used something like C, -however partly for historical reasons, and partly for code clarity it -is generally recommended only to use C in -C, and then mainly to generate the 404 not +Note that we could have used something like C, +however, it is generally recommended (partly for historical reasons, +and partly for code clarity) only to use C in +C, and then mainly to generate the 404 not found page for the application. Instead, we are using C here to @@ -424,17 +432,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('/')); } @@ -449,7 +457,7 @@ line of the C. Create a login form by opening C and inserting: [% META title = 'Login' %] - +
@@ -481,17 +489,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 anauthenticated users to reach any action in the Login # controller. To lock it down to a single action, we could use: @@ -501,7 +509,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 @@ -511,7 +519,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; } @@ -616,21 +624,25 @@ running) and restart it: $ script/myapp_server.pl -B If you are having issues with authentication on -Internet Explorer, be sure to check the system clocks on both your -server and client machines. Internet Explorer is very picky about -timestamps for cookies. Note that you can quickly sync an Ubuntu +B If you are having issues with authentication on +Internet Explorer, be sure to check the system clocks on both your +server and client machines. Internet Explorer is very picky about +timestamps for cookies. Note that you can quickly sync an Ubuntu system with the following command: sudo ntpdate ntp.ubuntu.com -Now trying going to L and you should -be redirected to the login page, hitting Shift+Reload if necessary (the -"You are already logged in" message should I appear -- if it does, -click the C button and try again). Note the C<***Root::auto User -not found...> debug message in the development server output. Enter -username C and password C, and you should be taken to -the Book List page. +Or possibly try C (to us an +unpriviledged port) or C (to try a +different server in case the Ubuntu NTP server is down). + +Now trying going to L and you should +be redirected to the login page, hitting Shift+Reload or Ctrl+Reload +if necessary (the "You are already logged in" message should I +appear -- if it does, click the C button and try again). Note +the C<***Root::auto User not found...> debug message in the +development server output. Enter username C and password +C, and you should be taken to the Book List page. Open C and add the following lines to the bottom (below the closing
tag): @@ -709,7 +721,7 @@ Then use the following command to update the SQLite database: $ sqlite3 myapp.db < myapp03.sql -B We are using SHA-1 hashes here, but many other hashing +B We are using SHA-1 hashes here, but many other hashing algorithms are supported. See C for more information. @@ -719,6 +731,8 @@ C Edit C and update it to match (the C and C are new, everything else is the same): + # rename this file to MyApp.yml and put a : in front of "name" if + # you want to use yaml like in old versions of Catalyst name MyApp default_realm dbic @@ -754,6 +768,7 @@ C are new, everything else is the same): + =head2 Try Out the Hashed Passwords Press C to kill the previous server instance (if it's still @@ -783,37 +798,42 @@ to match the following (everything after the model search line of code has changed): =head2 delete - + Delete a book - + =cut - + sub delete : Local { # $id = primary key of book to delete my ($self, $c, $id) = @_; - + # Search for the book and then delete it $c->model('DB::Books')->search({id => $id})->delete_all; - + # 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('/books/list')); } -Next, open C and update the TT code to pull from +Next, open C and update the TT code to pull from flash vs. the C query parameter: - - + ...
- [% status_msg || c.flash.status_msg %] - [% error_msg %] - [% content %] -
+ [%# Status and error messages %] + [% status_msg || c.flash.status_msg %] + [% error_msg %] + [%# This is where TT will stick all of your template's contents. -%] + [% content %] + + ... - +Although the sample above only shows the C div, leave the +rest of the file intact -- the only change we made to the C +was to add "C<|| c.request.params.status_msg>" to the +Cspan class="message"E> line. =head2 Try Out Flash @@ -832,13 +852,14 @@ after that first time (unless you reset it). Please refer to L for additional information. + =head2 Switch To Flash-To-Stash Although the a use of flash above is certainly an improvement over the -C we employed in Part 4 of the tutorial, the C statement is a little ugly. A nice +C we employed in Part 4 of the tutorial, the +C statement is a little ugly. A nice alternative is to use the C feature that automatically -copies the content of flash to stash. This makes your code controller +copies the content of flash to stash. This makes your controller and template code work regardless of where it was directly access, a forward, or a redirect. To enable C, you can either set the value in C by changing the default @@ -859,8 +880,8 @@ The C<__PACKAGE__-Econfig> option is probably preferable here since it's not something you will want to change at runtime without it possibly breaking some of your code. -Then edit C and change the C line -to look like the following: +Then edit C and change the C line +to match the following: [% status_msg %] diff --git a/lib/Catalyst/Manual/Tutorial/Authorization.pod b/lib/Catalyst/Manual/Tutorial/Authorization.pod index 331325b..66ada75 100644 --- a/lib/Catalyst/Manual/Tutorial/Authorization.pod +++ b/lib/Catalyst/Manual/Tutorial/Authorization.pod @@ -64,30 +64,32 @@ at how the ACL authorization plugin can simplify your code. You can checkout the source code for this example from the catalyst subversion repository as per the instructions in -L +L. + =head1 BASIC AUTHORIZATION In this section you learn how to manually configure authorization. + =head2 Update Plugins to Include Support for Authorization Edit C and add C to the list: - use Catalyst qw/ + __PACKAGE__->setup(qw/ -Debug ConfigLoader Static::Simple - + StackTrace - + Authentication Authorization::Roles - + Session Session::Store::FastMmap Session::State::Cookie - /; + /; =head2 Add Config Information for Authorization @@ -95,6 +97,8 @@ Edit C and add C to the list: Edit C and update it to match the following (the C and C definitions are new): + # rename this file to MyApp.yml and put a : in front of "name" if + # you want to use yaml like in old versions of Catalyst name MyApp default_realm dbic @@ -143,12 +147,12 @@ Open C in your editor and add the following 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 -%] @@ -156,7 +160,7 @@ lines to the bottom of the file: [% # Give normal users a link for 'logout' %] 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' %] @@ -167,6 +171,7 @@ lines to the bottom of the file: This code displays a different combination of links depending on the roles assigned to the user. + =head2 Limit C to C Users C statements in TT templates simply control the output that is sent @@ -180,18 +185,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 : 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 "//check_user_roles('admin')) { # Call create() on the book model object. Pass the table @@ -200,16 +205,16 @@ 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 for display in the view $c->stash->{book} = $book; - + # This is a hack to disable XSUB processing in Data::Dumper # (it's used in the view). This is a work-around for a bug in # the interaction of some versions or Perl, Data::Dumper & DBIC. @@ -217,7 +222,7 @@ updating C to match the following code: # you are running DBIC 0.06001 or greater), but adding it doesn't # hurt anything either. $Data::Dumper::Useperl = 1; - + # Set the TT template to use $c->stash->{template} = 'books/create_done.tt2'; } else { @@ -242,6 +247,7 @@ create a new copy and comment out the original by making it look like a Pod comment. For example, put something like C<=begin> before C and C<=end> after the closing C<}>. + =head2 Try Out Authentication And Authorization Press C to kill the previous server instance (if it's still @@ -249,13 +255,13 @@ running) and restart it: $ script/myapp_server.pl -Now trying going to L and you should -be taken to the login page (you might have to C your -browser and/or click the "Logout" link on the book list page). Try -logging in with both C and C (both use a password -of C) and notice how the roles information updates at the -bottom of the "Book List" page. Also try the C link on the -book list page. +Now trying going to L and you should +be taken to the login page (you might have to C or +C your browser and/or click the "Logout" link on the book +list page). Try logging in with both C and C (both +use a password of C) and notice how the roles information +updates at the bottom of the "Book List" page. Also try the C +link on the book list page. Now the "url_create" URL will work if you are already logged in as user C, but receive an authorization failure if you are logged in as @@ -263,8 +269,8 @@ C. Try: http://localhost:3000/books/url_create/test/1/6 -while logged in as each user. Use one of the 'Logout' links (or go to -L in your browser directly) when you are +while logged in as each user. Use one of the 'Logout' links (or go to +L in your browser directly) when you are done. @@ -275,20 +281,22 @@ L plugin can automate much of the work required to perform role-based authorization in a Catalyst application. + =head2 Add the C Plugin Open C in your editor and add the following plugin to the -C statement: +C<__PACKAGE__-Esetup> statement: Authorization::ACL Note that the remaining C plugins from earlier sections are not shown here, but they should still be included. + =head2 Add ACL Rules to the Application Class Open C in your editor and add the following B the -C<__PACKAGE__-Esetup;> statement: +C<__PACKAGE__-Esetup> statement: # Authorization::ACL Rules __PACKAGE__->deny_access_unless( @@ -358,6 +366,7 @@ C B the C<__PACKAGE__-Esetup;> line. =back + =head2 Add a Method to Handle Access Violations By default, @@ -372,17 +381,17 @@ Open C in your editor and add the following method: =head2 access_denied - + Handle Catalyst::Plugin::Authorization::ACL access denied exceptions - + =cut - + sub access_denied : Private { my ($self, $c) = @_; - + # Set the error message $c->stash->{error_msg} = 'Unauthorized!'; - + # Display the list $c->forward('list'); } diff --git a/lib/Catalyst/Manual/Tutorial/BasicCRUD.pod b/lib/Catalyst/Manual/Tutorial/BasicCRUD.pod index bc96f3d..fa5a5a9 100644 --- a/lib/Catalyst/Manual/Tutorial/BasicCRUD.pod +++ b/lib/Catalyst/Manual/Tutorial/BasicCRUD.pod @@ -66,9 +66,17 @@ focus on the Create and Delete aspects of CRUD. More advanced capabilities, including full Update functionality, will be addressed in Part 9. +Although this part of the tutorial will show you how to build CRUD +functionality yourself, another option is to use a "CRUD builder" type +of tool to automate the process. You get less control, but it's quick +and easy. For example, see +L, +L, and +L. + You can checkout the source code for this example from the catalyst subversion repository as per the instructions in -L +L. =head1 FORMLESS SUBMISSION @@ -172,22 +180,20 @@ Edit C and then enter: [% Dumper.dump(book) %] -The TT C directive allows access to a variety of plugin modules (TT -plugins, that is, not Catalyst plugins) to add extra functionality to -the base TT capabilities. Here, the plugin allows L -"pretty printing" of objects and variables. Other than that, the rest -of the code should be familiar from the examples in Part 3. +The TT C directive allows access to a variety of plugin modules +(TT plugins, that is, not Catalyst plugins) to add extra functionality +to the base TT capabilities. Here, the plugin allows +L "pretty printing" of objects and +variables. Other than that, the rest of the code should be familiar +from the examples in Part 3. -B As mentioned earlier, the C view -class created by TTSite redefines the name used to access the Catalyst -context object in TT templates from the usual C to C. =head2 Try the C Feature If the application is still running from before, use C to kill it. Then restart the server: - $ script/myapp_server.pl + $ DBIC_TRACE=1 script/myapp_server.pl Note that new path for C appears in the startup debug output. @@ -218,9 +224,9 @@ The C statements are obviously adding the book and linking it to the existing record for Richard Stevens. The C