}
This method provides a central location (so it can be called by multiple
-actions, such as C<create> and C<edit>) that builds an HTML::Wiget-based
+actions, such as C<create> and C<edit>) that builds an HTML::Widget-based
form with the appropriate fields. The "Get Authors" code uses DBIC to
retrieve a list of model objects and then uses C<map> to create a hash
where the hash keys are the database primary keys from the authors table
=item *
-fill_wiget()
+fill_widget()
Takes data from the database and transfers it to your form widget.
C<populate_from_widget> does not currently handle the relationships
between tables.
+
=head1 AUTHOR
Kennedy Clark, C<hkclark@gmail.com>
Please report any errors, issues or suggestions to the author.
-Copyright 2006, Kennedy Clark. All rights reserved.
-
-This library is free software; you can redistribute it and/or modify it
-under the same terms as Perl itself.
-
-Version: .94
-
+Copyright 2006, Kennedy Clark, under Creative Commons License
+(L<http://creativecommons.org/licenses/by-nc-sa/2.5/>).
=item *
+"%$s/^ "
+
+A shortcut for the previous item (C<%> specifies the entire file; so
+this removes four leading spaces from every line).
+
+=item *
+
":.,$s/^ "
Removes the first four spaces from the line the cursor is on at the time
B<TODO>
+
+=head1 APPENDIX 3: IMPROVED HASHING SCRIPT
+
+Here is an improved SHA-1 hashing script from Gavin Henry that does
+not expose the passwords to "capture" on the command line.
+
+ #!/usr/bin/perl -w
+ #===============================================================================
+ #
+ # FILE: enc_pass.pl
+ #
+ # USAGE: ./enc_pass.pl
+ #
+ # DESCRIPTION: Encrypt a Password using SHA-1
+ #
+ # OPTIONS: ---
+ # REQUIREMENTS: ---
+ # BUGS: ---
+ # NOTES: ---
+ # AUTHOR: Gavin Henry (GH), <ghenry@suretecsystems.com>
+ # COMPANY: Suretec Systems Ltd.
+ # VERSION: 1.0
+ # CREATED: 26/06/2006
+ # REVISION: ---
+ # COPYRIGHT: http://search.cpan.org/dist/perl/pod/perlgpl.pod
+ #===============================================================================
+
+ use strict;
+ use warnings;
+ use Digest::SHA1;
+ use Term::ReadKey;
+
+ sub get_pass {
+ ReadMode 'noecho';
+ chomp( my $pw = ReadLine 0 );
+ ReadMode 'normal';
+ return $pw;
+ }
+
+ print "Enter the password to be encrypted: ";
+ my $pass = get_pass();
+
+ print "\nConfirm the password: ";
+ my $verify = get_pass();
+
+ if ( $pass eq $verify ) {
+ my $sha1_enc = Digest::SHA1->new;
+ $sha1_enc->add($pass);
+
+ print "\nYour encrypted password is: "
+ . $sha1_enc->hexdigest . "\n"
+ . "Paste this into your SQL INSERT/COPY Data.\n";
+ }
+ else {
+ print "\nPasswords do not match!\n";
+ }
+
+
+
+=head1 AUTHOR
+
+Kennedy Clark, C<hkclark@gmail.com>
+
+Please report any errors, issues or suggestions to the author.
+
+Copyright 2006, Kennedy Clark, under Creative Commons License
+(L<http://creativecommons.org/licenses/by-nc-sa/2.5/>).
e727d1464ae12436e899a726da5b2f11d8381b26
$
+B<Note:> You should probably modify this code for production use to
+not read the password from the command line. By having the script
+prompt for the cleartext password, it avoids having the password linger
+in forms such as your C<.bash_history> files (assuming you are using
+BASH as your shell). An example of such a script can be found in
+Appendix 3.
+
=head2 Switch to SHA-1 Password Hashes in the Database
[% META title = 'Book Created' %]
[% # Output information about the record that was added. Note use -%]
- [% # of 'first' to only list the first author (if > 1 author). -%]
- <p>Added book '[% book.title %]' by '[% book.authors.first.last_name %]'
+ [% # of 'first' to only list the first author (if > 1 author). TT -%]
+ [% # v2.15 has an issue that requires -%]
+ [% # 'book.authors.list.first.value.last_name' vs. the shorter -%]
+ [% # 'book.authors.first.last_name' in prior versions. -%]
+ <p>Added book '[% book.title %]'
+ by '[% book.authors.list.first.value.last_name %]'
with a rating of [% book.rating %].</p>
[% # Provide a link back to the list page -%]
Open C<lib/MyApp/Controller/Books.pm> in your editor and add the
following method:
- =head2 Delete
+ =head2 delete
Delete a book
$ export DBIX_CLASS_STORAGE_DBI_DEBUG=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 DBIX_CLASS_STORAGE_DBI_DEBUG 1>).
+
B<NOTE>: You can also set this in your code using
C<$class-E<gt>storage-E<gt>debug(1);>. See
L<DBIx::Class::Manual::Troubleshooting> for details (including options
[% Catalyst.log.debug("This is a test log message") %]
-You can also use L<Data::Dumper> in both Catalyst code (C<use
-Data::Dumper; $c-E<gt>log-E<gt>debug("$var is: ".Dumper($var));)>) and
-TT templates (C<[% Dumper.dump(book) %]>.
+You can also use L<Data::Dumper|Data::Dumper> in both Catalyst code
+(C<use Data::Dumper; $c-E<gt>log-E<gt>debug("$var is: ".Dumper($var));)>)
+and TT templates (C<[% Dumper.dump(book) %]>.
=head1 RUNNING CATALYST UNDER THE PERL DEBUGGER
and C<perldebtut>. You can also type C<h> or C<h h> at the debugger
prompt to view the built-in help screens.
+
+=head1 DEBUGGING MODULES FROM CPAN
+
+Although the techniques discussed above work well for code you are
+writing, what if you want to use print/log/warn messages or set
+breakpoints in code that you have installed from CPAN (or in module
+that ship with Perl)? One helpful approach is to place a copy of
+the module inside the C<lib> directory of your Catalyst project.
+When Catalyst loads, it will load from inside your C<lib> directory
+first, only turning to the global modules if a local copy cannot be
+found. You can then make modifications such as adding a
+C<$DB::single=1> to the local copy of the module without risking
+the copy in the original location.
+
+Matt Trout has suggested the following shortcut to create a local
+copy of an installed module:
+
+ mkdir -p lib/Module; cp `perldoc -l Module::Name` lib/Module/
+
+For example, you could make a copy of
+L<Catalyst::Plugin::Authentication|Catalyst::Plugin::Authentication>
+with the following command:
+
+ mkdir -p lib/Catalyst/Plugin; cp \
+ `perldoc -l Catalyst::Plugin::Authentication` lib/Catalyst/Plugin
+
+B<Note:> Matt has also suggested the following tips for Perl
+debugging:
+
+=over 4
+
+=item *
+
+Check the version of an installed module:
+
+ perl -MModule::Name -e 'print $Module::Name::VERSION;'
+
+For example:
+
+ $ perl -MCatalyst::Plugin::Authentication -e \
+ 'print $Catalyst::Plugin::Authentication::VERSION;'
+ 0.07
+
+=item *
+
+Check if a modules contains a given method:
+
+ perl -MModule::Name -e 'print Module::Name->can("method");'
+
+For example:
+
+ $ perl -MCatalyst::Plugin::Authentication -e \
+ 'print Catalyst::Plugin::Authentication->can("prepare");'
+ CODE(0x9c8db2c)
+
+If the method exists, the Perl C<can> method returns a coderef.
+Otherwise, it returns undef and nothing will be printed.
+
+=back
+
+
=head1 AUTHOR
Kennedy Clark, C<hkclark@gmail.com>
Copyright 2006, Kennedy Clark, under Creative Commons License
(L<http://creativecommons.org/licenses/by-nc-sa/2.5/>).
-
-Version: .94
-
=item *
-The use of HTML::Widget for automated form processing and validation.
+The use of L<HTML::Widget|HTML::Widget> for automated form processing
+and validation.
=back
=item *
-Authentication::Credential::Password -- 0.07
+Catalyst::Plugin::Authentication::Credential::Password -- 0.07
=item *
=head1 RUNNING THE "CANNED" CATALYST TESTS
There are a variety of ways to run Catalyst and Perl tests (for example,
-C<perl Makefile.PL> and C<make test>, but one of the easiest is with the
+C<perl Makefile.PL> and C<make test>), but one of the easiest is with the
C<prove> command. For example, to run all of the tests in the C<t>
directory, enter:
Although the Catalyst helper scripts provide a basic level of checks
"for free," testing can become significantly more helpful when you write
your own script to exercise the various parts of your application. The
-L<Test::WWW::Mechanize::Catalyst> module is very popular for writing
-these sorts of test cases. This module extends L<Test::WWW::Mechanize>
-(and therefore L<WWW::Mechanize>) to allow you to automate the action of
+L<Test::WWW::Mechanize::Catalyst|Test::WWW::Mechanize::Catalyst> module
+is very popular for writing these sorts of test cases. This module
+extends L<Test::WWW::Mechanize|Test::WWW::Mechanize> (and therefore
+L<WWW::Mechanize|WWW::Mechanize>) to allow you to automate the action of
a user "clicking around" inside your application. It gives you all the
benefits of testing on a live system without the messiness of having to
use an actual web server, and a real person to do the clicking.
The C<live_app.t> test cases uses copious comments to explain each step
of the process. In addition to the techniques shown here, there are a
-variety of other methods available in L<Test::WWW::Mechanize::Catalyst>
-(for example, regex-based matching). Consult the documentation for more
+variety of other methods available in
+L<Test::WWW::Mechanize::Catalyst|Test::WWW::Mechanize::Catalyst> (for
+example, regex-based matching). Consult the documentation for more
detail.
B<TIP>: For I<unit tests> vs. the "full application tests" approach used
-by L<Test::WWW::Mechanize::Catalyst>, see L<Catalyst::Test>.
+by L<Test::WWW::Mechanize::Catalyst|Test::WWW::Mechanize::Catalyst>, see
+L<Catalyst::Test|Catalyst::Test>.
B<Note:> The test script does not test the C<form_create> and
C<form_create_do> actions. That is left as an exercise for the reader
variable defined, it will default to the same C<dbi:SQLite:myapp.db> as
before.
+
=head1 AUTHOR
Kennedy Clark, C<hkclark@gmail.com>
Copyright 2006, Kennedy Clark, under Creative Commons License
(L<http://creativecommons.org/licenses/by-nc-sa/2.5/>).
-Version: .94
-