[Jifty-commit] r3583 - in jifty/branches/trimclient: . lib/Jifty lib/Jifty/Manual lib/Jifty/Plugin lib/Jifty/Plugin/Authentication lib/Jifty/Plugin/Authentication/Password lib/Jifty/Plugin/Authentication/Password/Mixin/Model lib/Jifty/Plugin/Debug lib/Jifty/Plugin/OpenID lib/Jifty/Plugin/User/Mixin/Model lib/Jifty/Request lib/Jifty/View/Static share/web/static/js/yui t/Mapper/lib/Mapper/Action t/Mapper/share/web/templates

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Wed Jun 27 22:59:57 EDT 2007


Author: gugod
Date: Wed Jun 27 22:59:56 2007
New Revision: 3583

Added:
   jifty/branches/trimclient/lib/Jifty/Plugin/Debug/
   jifty/branches/trimclient/lib/Jifty/Plugin/Debug.pm
   jifty/branches/trimclient/lib/Jifty/Plugin/Debug/Dispatcher.pm
   jifty/branches/trimclient/share/web/static/js/yui/oom_select.patch
Modified:
   jifty/branches/trimclient/   (props changed)
   jifty/branches/trimclient/lib/Jifty/CurrentUser.pm
   jifty/branches/trimclient/lib/Jifty/Manual/Cookbook.pod
   jifty/branches/trimclient/lib/Jifty/Plugin.pm
   jifty/branches/trimclient/lib/Jifty/Plugin/Authentication/Password.pm
   jifty/branches/trimclient/lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm
   jifty/branches/trimclient/lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm
   jifty/branches/trimclient/lib/Jifty/Plugin/Authentication/Password/View.pm
   jifty/branches/trimclient/lib/Jifty/Plugin/OpenID/View.pm
   jifty/branches/trimclient/lib/Jifty/Plugin/User.pm
   jifty/branches/trimclient/lib/Jifty/Plugin/User/Mixin/Model/User.pm
   jifty/branches/trimclient/lib/Jifty/Request/Mapper.pm
   jifty/branches/trimclient/lib/Jifty/Test.pm
   jifty/branches/trimclient/lib/Jifty/Upgrade.pm
   jifty/branches/trimclient/lib/Jifty/View/Static/Handler.pm
   jifty/branches/trimclient/share/web/static/js/yui/calendar.js
   jifty/branches/trimclient/t/Mapper/lib/Mapper/Action/CrossBridge.pm
   jifty/branches/trimclient/t/Mapper/share/web/templates/index.html
   jifty/branches/trimclient/t/Mapper/t/02-api.t

Log:
 r6937 at GOP (orig r3532):  clkao | 2007-06-20 06:56:51 +0800
 debug plugin for logging dispatched rules and current user.
 r6938 at GOP (orig r3533):  clkao | 2007-06-20 07:05:52 +0800
 info rather than debug.
 r6939 at GOP (orig r3534):  trs | 2007-06-20 10:57:00 +0800
  r24761 at zot:  tom | 2007-06-19 22:56:13 -0400
  * Use Jifty::Util->share_root for finding plugin share roots so that if Jifty isn't installed it still DTRT
  * Only calculate static roots once and report on plugins adding roots (like the mason handler does)
 
 r6943 at GOP (orig r3542):  trs | 2007-06-21 12:06:09 +0800
  r24784 at zot:  tom | 2007-06-21 00:03:42 -0400
  Convert to using the form of declaring titles that works when using the mason wrapper with TD
 
 r6944 at GOP (orig r3543):  trs | 2007-06-21 14:47:05 +0800
  r24794 at zot:  tom | 2007-06-21 02:46:02 -0400
  Restore and update the OOM patch to the YUI calendar
 
 r6945 at GOP (orig r3544):  ruz | 2007-06-21 23:03:23 +0800
 * protect ourself from circular references between User and CurrentUser
 
 we do it in user_object, so solution is generic should work in any case, but
 only if people use the method to set user_object and user model uses _current_user
 key to store reference to the CurrentUser
 
 r6946 at GOP (orig r3545):  gugod | 2007-06-22 13:23:43 +0800
 Add a "next" parameter so one can specify the next page to go after
 openid login.
 
 r6948 at GOP (orig r3546):  ruz | 2007-06-22 21:33:34 +0800
 * add {_resurect_current_user} field into user module
 r6949 at GOP (orig r3547):  bartb | 2007-06-23 06:19:29 +0800
 added see also section to Jifty::Upgrade
 r6950 at GOP (orig r3548):  bartb | 2007-06-24 06:26:00 +0800
 typo
 r6951 at GOP (orig r3549):  alexmv | 2007-06-25 05:19:47 +0800
  r19898 at zoq-fot-pik:  chmrr | 2007-06-24 17:17:51 -0400
   * Mapper edge case failure (when no 'name' was given)
 
 r6952 at GOP (orig r3550):  audreyt | 2007-06-26 01:48:22 +0800
 * No matter what _resurect_current_user is intended for, it ought
   to be spelled _resurrect_current_user instead. :-)
 r6956 at GOP (orig r3570):  sterling | 2007-06-27 00:38:44 +0800
  r7829 at riddle:  andrew | 2007-06-26 11:37:40 -0500
  Added a many-to-many relationship recipe to the cookbook.
 
 r6957 at GOP (orig r3571):  alexmv | 2007-06-27 04:11:04 +0800
  r19955 at zoq-fot-pik:  chmrr | 2007-06-26 16:10:33 -0400
   * Recent YAML::Syck's get confused by trying to be too smart with
     $test_config, which is a filehandle which *also* stringifies to the
     path.  Force stringification to get consistent (working) results.
 
 r6965 at GOP (orig r3580):  sterling | 2007-06-28 09:43:41 +0800
  r7874 at dynpc145:  andrew | 2007-06-27 20:42:34 -0500
  Fleshing out and cleaning up the documentation for Jifty::Plugin::User.
 
 r6966 at GOP (orig r3581):  sterling | 2007-06-28 09:43:53 +0800
  r7875 at dynpc145:  andrew | 2007-06-27 20:43:00 -0500
  Fleshing out and cleaning up the documentation for Jifty::Plugin::Authentication::Password.
 


Modified: jifty/branches/trimclient/lib/Jifty/CurrentUser.pm
==============================================================================
--- jifty/branches/trimclient/lib/Jifty/CurrentUser.pm	(original)
+++ jifty/branches/trimclient/lib/Jifty/CurrentUser.pm	Wed Jun 27 22:59:56 2007
@@ -4,8 +4,9 @@
 package Jifty::CurrentUser;
 
 use base qw/Jifty::Object Class::Accessor::Fast/;
+use Scalar::Util qw();
 
-__PACKAGE__->mk_accessors(qw(is_superuser is_bootstrap_user user_object));
+__PACKAGE__->mk_accessors(qw(is_superuser is_bootstrap_user));
 
 
 =head1 NAME
@@ -98,6 +99,20 @@
 
 =cut
 
+sub user_object {
+    my $self = shift;
+    return $self->{'user_object'} unless @_;
+
+    $self->{'user_object'} = shift;
+    # protect ourself from circular refereces
+    if ( $self->{'user_object'}{'_current_user'} == $self ) {
+        Scalar::Util::weaken( $self->{'user_object'}{'_current_user'} )
+            unless Scalar::Util::isweak( $self->{'user_object'}{'_current_user'} );
+        $self->{'user_object'}{'_resurrect_current_user'} = 1;
+    }
+    return $self->{'user_object'};
+}
+
 =head2 id
 
 Returns C<0> if we don't have a L<user_object>.  When we I<do> have a

Modified: jifty/branches/trimclient/lib/Jifty/Manual/Cookbook.pod
==============================================================================
--- jifty/branches/trimclient/lib/Jifty/Manual/Cookbook.pod	(original)
+++ jifty/branches/trimclient/lib/Jifty/Manual/Cookbook.pod	Wed Jun 27 22:59:56 2007
@@ -400,6 +400,62 @@
         Jifty->web->out($image);
     };
 
+=head2 Create a many-to-many relationship
+
+You need to create two one-to-many relationships with a linking table as you normally would in pure SQL. First, create your linking table by running:
+
+  bin/jifty model --name LinkTable
+
+Modify the newly created C<MyApp::Model::LinkTable> class to add new columns linking back to either side of the table:
+
+  use MyApp::Record schema {
+      column left_table =>
+          refers_to MyApp::Model::LeftTable;
+      column right_table =>
+          refers_to MyApp::Model::RightTable;
+  };
+
+Then create links to the linking table in C<MyApp::Model::LeftTable>:
+
+  use MyApp::Record schema {
+      # other columns...
+      
+      column right_things =>
+          refers_to MyApp::Model::LinkTableCollection by 'left_table';
+  };
+
+Then create links to the linking table in C<MyApp::Model::RightTable>:
+
+  use MyApp::Record schema {
+      # other columns...
+      
+      column left_things =>
+          refers_to MyApp::Model::LinkTableCollection by 'right_table';
+  };
+
+Now, add your records. To create a relationship between a row the two tables:
+
+  my $left = MyApp::Model::LeftTable->new;
+  $left->load(1);
+
+  my $right = MyApp::Model::RightTable->new;
+  $right->laod(1);
+
+  my $link = MyApp::Model::LinkTable->new;
+  $link->create(
+      left_table  => $left,
+      right_table => $right,
+  );
+
+And to get all the "right things" from the left table, you need to make the extra hop in your loop:
+
+  my $links = $left->right_things;
+  while (my $link = $links->next) {
+      my $right = $link->right_table;
+  
+      # Do stuff with $right
+  }
+
 =for comment
 Document how to do this with Mason
 

Modified: jifty/branches/trimclient/lib/Jifty/Plugin.pm
==============================================================================
--- jifty/branches/trimclient/lib/Jifty/Plugin.pm	(original)
+++ jifty/branches/trimclient/lib/Jifty/Plugin.pm	Wed Jun 27 22:59:56 2007
@@ -98,8 +98,7 @@
         eval { $self->{share} = module_dir($class) };
     }
     unless ( $self->{share} ) {
-        local $@; # We're just avoiding File::ShareDir's failure behaviour of dying
-        eval { $self->{share} = module_dir('Jifty') };
+        $self->{share} = Jifty::Util->share_root;
         if ( $self->{'share'} ) {
             my $class_to_path = $class;
             $class_to_path =~ s|::|/|g;

Modified: jifty/branches/trimclient/lib/Jifty/Plugin/Authentication/Password.pm
==============================================================================
--- jifty/branches/trimclient/lib/Jifty/Plugin/Authentication/Password.pm	(original)
+++ jifty/branches/trimclient/lib/Jifty/Plugin/Authentication/Password.pm	Wed Jun 27 22:59:56 2007
@@ -4,23 +4,17 @@
 package Jifty::Plugin::Authentication::Password;
 use base qw/Jifty::Plugin/;
 
-# Your plugin goes here.  If takes any configuration or arguments, you
-# probably want to override L<Jifty::Plugin/init>.
-
 =head1 NAME
 
-Jifty::Plugin::Authentication::Password
+Jifty::Plugin::Authentication::Password - password authentication plugin
 
 =head1 DESCRIPTION
 
-When finished, this plugin will provide password authentication for 
-your Jifty application. (It adds a "password" column to your "User" model class).
-
-Right now, it's useless and should be ignored.
+B<CAUTION:> This plugin is experimental.
 
+This may be combined with the L<Jifty::Plugin::User> and L<Jifty::Plugin::LetMe> plugins to provide user accounts and form-based password authentication to your application.
 
-=cut
-
+=head2 METHODS
 
 =head2 prereq_plugins
 
@@ -33,4 +27,15 @@
     return ('User', 'LetMe');
 }
 
+=head1 SEE ALSO
+
+L<Jifty::Plugin::User>, L<Jifty::Plugin::LetMe>, L<Jifty::Plugin::Authentication::Password::Mixin::Model::User>
+
+=head1 LICENSE
+
+Jifty is Copyright 2005-2007 Best Practical Solutions, LLC.
+Jifty is distributed under the same terms as Perl itself.
+
+=cut
+
 1;

Modified: jifty/branches/trimclient/lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm
==============================================================================
--- jifty/branches/trimclient/lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm	(original)
+++ jifty/branches/trimclient/lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm	Wed Jun 27 22:59:56 2007
@@ -4,25 +4,22 @@
 package Jifty::Plugin::Authentication::Password::Dispatcher;
 use Jifty::Dispatcher -base;
 
-# Put any plugin-specific dispatcher rules here.
-
-
 =head1 NAME
 
-Jifty::Plugin::Authentication::Password::Dispatcher
+Jifty::Plugin::Authentication::Password::Dispatcher - password plugin dispatcher
 
 =head1 DESCRIPTION
 
 All the dispatcher rules jifty needs to support L<Jifty::Authentication::Password/>
 
-=cut
-
-
 =head1 RULES
 
-
 =head2 before logout
 
+Logout and return home.
+
+See L<Jifty::Plugin::Authentication::Password::Action::Logout>.
+
 =cut
 
 before 'logout' => run {
@@ -35,6 +32,8 @@
 
 =head2 before *
 
+Setup the navigation menu for login or logout.
+
 =cut
 
 before '*' =>  run {
@@ -47,7 +46,11 @@
 
 };
 
-=head2 on qr/^(?:passwordreminder|signup)$/ 
+=head2 on qr/^(?:passwordreminder|signup|lost_password)$/ 
+
+Redirect to home if logged.
+
+Request a password reminder or signup for an account otherwise.
 
 =cut
 
@@ -58,6 +61,10 @@
 
 =head2 on login
 
+Redirect to home if logged.
+
+Show the login form otherwise.
+
 =cut
 
 before qr|^/(?:login)$| => run {
@@ -65,12 +72,22 @@
     set 'next' => Jifty->web->request->continuation || Jifty::Continuation->new( request => Jifty::Request->new( path => "/" ) );
 };
 
+=head2 before reset_lost_password
+
+Request a password reset.
+
+=cut
+
 before qr|(?:reset_lost_password)| => run {
     set 'next' => Jifty->web->request->continuation || Jifty::Continuation->new( request => Jifty::Request->new( path => "/" ) );
 };
 # Send a password reminder for a lost password
 
-=head2 on passwordreminder
+=head2 before passwordreminder
+
+Request a new password reminder to be sent by email.
+
+See L<Jifty::Plugin::Authentication::Password::Action::SendPasswordReminder>.
 
 =cut
 
@@ -79,9 +96,11 @@
 };
 
 
-=head2 on signup
+=head2 before signup
+
+Sign up for an account.
 
-# Sign up for an account
+See L<Jifty::Plugin::Authentication::Password::Action::Signup>.
 
 =cut
 
@@ -90,9 +109,11 @@
 
 };
 
-=head2 on login
+=head2 before login
 
-Login
+Login to your account.
+
+See L<Jifty::Plugin::Authentication::Password::Action::Login>.
 
 =cut
 
@@ -102,6 +123,8 @@
 
 =head2 not_logged_in_nav
 
+Adds the login and signup links to the navigation menu.
+
 =cut
 
 sub not_logged_in_nav {
@@ -119,6 +142,8 @@
 
 =head2 logged_in_nav
 
+Adds the logout link to the navigation menu.
+
 =cut
 
 sub logged_in_nav {
@@ -130,5 +155,14 @@
 
 }
 
+=head1 SEE ALSO
+
+L<Jifty::Plugin::Authentication::Password>, L<Jifty::Plugin::Authentication::Password::View>
+
+=head1 COPYRIGHT
+
+Jifty is Copyright 2005-2007 Best Practical Solutions, LLC.
+Jifty is distributed under the same terms as Perl itself.
+
 
 1;

Modified: jifty/branches/trimclient/lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm
==============================================================================
--- jifty/branches/trimclient/lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm	(original)
+++ jifty/branches/trimclient/lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm	Wed Jun 27 22:59:56 2007
@@ -9,6 +9,40 @@
 
 our @EXPORT = qw(password_is hashed_password_is regenerate_auth_token has_alternative_auth);
 
+=head1 NAME
+
+Jifty::Plugin::Authentication::Password::Mixin::Model::User - password plugin user mixin model
+
+=head1 SYNOPSIS
+
+  package MyApp::Model::User;
+  use Jifty::DBI::Schema;
+  use MyApp::Record schema {
+      # custom column defrinitions
+  };
+
+  use Jifty::Plugin::User::Mixin::Model::User; # name, email, email_confirmed
+  use Jifty::Plugin::Authentication::Password::Mixin::Model::User;
+  # ^^ password, auth_token
+
+=head1 DESCRIPTION
+
+This mixin model is added to the application's account model for use with the password authentication plugin. This mixin should be used in combination with L<Jifty::Plugin::User::Mixin::Model::User>.
+
+=head1 SCHEMA
+
+This mixin adds the following columns to the model schema:
+
+=head2 auth_token
+
+This is a unique identifier used when confirming a user's email account and recovering a lost password.
+
+=head2 password
+
+This is the user's password. It will be stored in the database after being processed through L<Digest::MD5>, so the password cannot be directly recovered from the database.
+
+=cut
+
 use Jifty::Plugin::Authentication::Password::Record schema {
 
 
@@ -31,6 +65,14 @@
 
 };
 
+=head1 METHODS
+
+=head2 register_triggers
+
+Adds the triggers to the model this mixin is added to.
+
+=cut
+
 sub register_triggers {
     my $self = shift;
     $self->add_trigger(name => 'after_create', callback => \&after_create);
@@ -60,7 +102,9 @@
 =head2 hashed_password_is HASH TOKEN
 
 Check if the given I<HASH> is the result of hashing our (already
-salted and hashed) password with I<TOKEN>
+salted and hashed) password with I<TOKEN>.
+
+This can be used in cases where the pre-hashed password is sent during login as an additional security precaution (such as could be done via Javascript).
 
 =cut
 
@@ -93,6 +137,14 @@
     return 1;
 }
 
+=head2 after_create
+
+This trigger is added to the account model. It automatically sends a notification email to the user for password confirmation.
+
+See L<Jifty::Plugin::Authentication::Password::Notification::ConfirmEmail>.
+
+=cut
+
 
 sub after_create {
     my $self = shift;
@@ -143,7 +195,16 @@
     $self->__set(column => 'auth_token', value => $auth_token);
 }
 
+=head1 SEE ALSO
+
+L<Jifty::Plugin::Authentication::Password>, L<Jifty::Plugin::User::Mixin::Model>
 
+=head1 LICENSE
+
+Jifty is Copyright 2005-2007 Best Practical Solutions, LLC.
+Jifty is distributed under the same terms as Perl itself.
+
+=cut
 
 1;
 

Modified: jifty/branches/trimclient/lib/Jifty/Plugin/Authentication/Password/View.pm
==============================================================================
--- jifty/branches/trimclient/lib/Jifty/Plugin/Authentication/Password/View.pm	(original)
+++ jifty/branches/trimclient/lib/Jifty/Plugin/Authentication/Password/View.pm	Wed Jun 27 22:59:56 2007
@@ -4,12 +4,19 @@
 
 =head1 NAME
 
-Jifty::Plugin::Authentication::Password::Login::View
+Jifty::Plugin::Authentication::Password::View - views for password plugin
 
 =head1 DESCRIPTION
 
-This code is only useful on the new Jifty "Declarative templates" branch. It shouldn't get in the way 
-if you're running a traditional (0.610 or before) Jifty.
+This code is only useful on the new Jifty "Declarative templates" branch. It shouldn't get in the way if you're running a traditional (0.610 or before) Jifty.
+
+=begin comment
+
+Is the above really true or need to said anymore? -- Sterling
+
+=end
+
+This provides the templates for the pages and forms used by the password authentication plugin.
 
 =cut
 
@@ -24,9 +31,15 @@
 }
 }
 
+=head1 TEMPLATES
 
-template 'signup' => page {
-    title is _('Sign up');
+=head2 signup
+
+Displays a sign-up form.
+
+=cut
+
+template 'signup' => page { title => _('Sign up') } content {
     my ( $action, $next ) = get(qw(action next));
     Jifty->web->form->start( call => $next );
     render_param( $action => 'name' , focus => 1);
@@ -35,11 +48,26 @@
     Jifty->web->form->end();
 };
 
-template login => page {
-    { title is _('Login!') };
+=head2 login
+
+Displays the login form.
+
+=cut
+
+template login => page { title => _('Login!') } content {
     show('login_widget');
 };
 
+=head2 login_widget
+
+A handy template for embedding the login form. Just include it in your templates via:
+
+  show('login_widget');
+
+See L<Jifty::Plugin::Authentication::Password::Action::Login>.
+
+=cut
+
 template login_widget => sub {
 
     my ( $action, $next ) = get( 'action', 'next' );
@@ -69,9 +97,16 @@
     }
 };
 
-template 'let/reset_lost_password' => page {
+=head2 let/reset_lost_password
+
+After requesting a password reset and clicking on the link sent by email, this receives that click and provides the form for resetting the password.
+
+See L<Jifty::Plugin::Authentication::Action::ResetLostPassword>.
+
+=cut
+
+template 'let/reset_lost_password' => page { title => 'Reset lost password' } content {
     my ( $next ) = get(qw(next));
-    title is 'Reset lost password' ;
     my $action = Jifty->web->new_action( class => 'ResetLostPassword' );
 
     Jifty->web->form->start( call => $next );
@@ -80,19 +115,34 @@
     Jifty->web->form->end();
 };
 
+=head2 let/confirm_email
+
+Handles the work of confirming an email address for a new account.
+
+See L<Jifty::Plugin::Authenticaiton::Password::View>.
+
+=cut
+
 template 'let/confirm_email' => sub {
     new_action( class => 'ConfirmEmail' )->run;
     redirect("/");
 };
 
-template 'lost_password' => page {
+=head2 lost_password
+
+Starts the process of sending a link to reset a lost password by email.
+
+See L<Jifty::Plugin::Authentication::Password::SendPasswordReminder>.
+
+=cut
+
+template 'lost_password' => page { title => 'Send a link to reset your password' } content {
     my ( $next ) = get(qw(next));
     my $action = Jifty->web->new_action(
         moniker => 'password_reminder',
         class   => 'SendPasswordReminder',
     );
 
-    title is _('Send a link to reset your password');
     outs( _(  "You lost your password. A link to reset it will be sent to the following email address:"));
     my $focused = 0;
     Jifty->web->form->start( call => $next );
@@ -102,9 +152,22 @@
 
 };
 
-template 'passwordreminder' => page {
+=head2 passwordreminder
+
+Starts the process of sending a link to reset a lost password by email.
+
+See L<Jifty::Plugin::Authentication::Password::SendPasswordReminder>.
+
+=begin comment
+
+What's the difference between lost_password and passwordreminder? -- Sterling
+
+=end
+
+=cut
+
+template 'passwordreminder' => page { title => 'Send a password reminder' } content {
     my $next = get('next');
-     title is  _('Send a password reminder');
     my $action = Jifty->web->new_action(
         moniker => 'password_reminder',
         class   => 'SendPasswordReminder',
@@ -118,8 +181,15 @@
     Jifty->web->form->end();
 };
 
-template 'resend_confirmation' => page {
-    attr { title => "Resend Confirmation Email" };
+=head2 resend_confirmation
+
+Request a new email confirmation message be sent to your email account.
+
+See L<Jifty::Plugin::Authentication::Password::Action::ResendConfirmation>.
+
+=cut
+
+template 'resend_confirmation' => page { title => 'Resend Confirmation Email' } content {
     my $resend = Jifty->web->new_action(
         class   => 'ResendConfirmation',
         moniker => 'resendconf'
@@ -147,6 +217,16 @@
     }
 };
 
+=head1 SEE ALSO
+
+L<Jifty::Plugin::Authentication::Password>, L<Jifty::Plugin::Authentication::Password::Dispatcher>
+
+=head1 LICENSE
+
+Jifty is Copyright 2005-2007 Best Practical Solutions, LLC.
+Jifty is distributed under the same terms as Perl itself.
+
+=cut
 
 
 1;

Added: jifty/branches/trimclient/lib/Jifty/Plugin/Debug.pm
==============================================================================
--- (empty file)
+++ jifty/branches/trimclient/lib/Jifty/Plugin/Debug.pm	Wed Jun 27 22:59:56 2007
@@ -0,0 +1,7 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::Debug;
+use base qw/Jifty::Plugin/;
+
+1;

Added: jifty/branches/trimclient/lib/Jifty/Plugin/Debug/Dispatcher.pm
==============================================================================
--- (empty file)
+++ jifty/branches/trimclient/lib/Jifty/Plugin/Debug/Dispatcher.pm	Wed Jun 27 22:59:56 2007
@@ -0,0 +1,12 @@
+use warnings;
+use strict;
+
+package Jifty::Plugin::Debug::Dispatcher;
+use Jifty::Dispatcher -base;
+
+on qr'(.*)' => run {
+    Jifty->log->info("[$$] $1 ".(Jifty->web->current_user->id ? Jifty->web->current_user->username : ''));
+};
+
+1;
+

Modified: jifty/branches/trimclient/lib/Jifty/Plugin/OpenID/View.pm
==============================================================================
--- jifty/branches/trimclient/lib/Jifty/Plugin/OpenID/View.pm	(original)
+++ jifty/branches/trimclient/lib/Jifty/Plugin/OpenID/View.pm	Wed Jun 27 22:59:56 2007
@@ -15,7 +15,7 @@
 
 template 'openid/login' => page {
     { title is _("Login with your OpenID") }
-    my $action = get('action');
+    my ($action, $next) = get('action', 'next');
 
     div {
         unless ( Jifty->web->current_user->id ) {
@@ -29,13 +29,13 @@
                         }
                     }
                 );
-                form {
-                    render_action($action);
-                    form_submit(
-                        label  => _("Go for it!"),
-                        submit => $action
-                    );
-                }
+                Jifty->web->form->start( call => $next );
+                render_action($action);
+                form_submit(
+                    label  => _("Go for it!"),
+                    submit => $action
+                );
+                Jifty->web->form->end;
             };
         }
         else {

Modified: jifty/branches/trimclient/lib/Jifty/Plugin/User.pm
==============================================================================
--- jifty/branches/trimclient/lib/Jifty/Plugin/User.pm	(original)
+++ jifty/branches/trimclient/lib/Jifty/Plugin/User.pm	Wed Jun 27 22:59:56 2007
@@ -4,18 +4,22 @@
 package Jifty::Plugin::User;
 use base qw/Jifty::Plugin/;
 
-# Your plugin goes here.  If takes any configuration or arguments, you
-# probably want to override L<Jifty::Plugin/init>.
-
 =head1 NAME
 
-Jifty::Plugin::User
+Jifty::Plugin::User - plugin for building user models
 
 =head1 DESCRIPTION
 
 This plugin provides a "user" mixin for your application's user model class.
 
-See L<Jifty::Plugin::User/> for more details.
+=head1 SEE ALSO
+
+L<Jifty::Plugin::User::Mixin::Model::User>, L<Jifty::Plugin::Authentication::Password>
+
+=head1 LICENSE
+
+Jifty is Copyright 2005-2007 Best Practical Solutions, LLC.
+Jifty is distributed under the same terms as Perl itself.
 
 =cut
 

Modified: jifty/branches/trimclient/lib/Jifty/Plugin/User/Mixin/Model/User.pm
==============================================================================
--- jifty/branches/trimclient/lib/Jifty/Plugin/User/Mixin/Model/User.pm	(original)
+++ jifty/branches/trimclient/lib/Jifty/Plugin/User/Mixin/Model/User.pm	Wed Jun 27 22:59:56 2007
@@ -7,9 +7,9 @@
 
 =head1 NAME
 
-Jifty::Plugin::User::Mixin::Model::User
+Jifty::Plugin::User::Mixin::Model::User - user model base mixin
 
-=head1 DESCRIPTION
+=head1 SYNOPSIS
 
  package MyApp::Model::User;
  use Jifty::DBI::Schema;
@@ -18,8 +18,27 @@
  };
  
  use Jifty::Plugin::User::Mixin::Model::User; # Imports two columns: name and email
- 
 
+=head1 DESCRIPTION
+
+This mixin may be added to a model to give your user accounts a name and an email address. This module may be used as the basic building block for building account models in your application. It can be combined with mixins from an authentication plugin to create an object suitable for a given authentication mechanism.
+
+=head1 SCHEMA
+
+This mixin model adds the following columns to the model.
+
+=head2 name
+
+This is the username/nickname for the user of the account.
+
+=head2 email
+
+This is the email address of the account. It is intended as a bare minimum confirmation of identity and for communication of password resets and other account information.
+
+=head2 email_confirmed
+
+This is a flag indicating whether the user has confirmed ownership of the given email address.
+ 
 =cut
 
 use base 'Jifty::DBI::Record::Plugin';
@@ -37,9 +56,7 @@
 
 };
 
-# Your model-specific methods go here.
-
-
+=head1 METHODS
 
 =head2 set_email ADDRESS
 
@@ -92,6 +109,16 @@
     return 1;
 }
 
+=head1 SEE ALSO
+
+L<Jifty::Plugin::Authentication::Password>, L<Jifty::Plugin::Authentication::Password::Mixin::Model::User>
+
+=head1 LICENSE
+
+Jifty is Copyright 2005-2007 Best Practical Solutions, LLC.
+Jifty is distributed under the same terms as Perl itself.
+
+=cut
 
 1;
 

Modified: jifty/branches/trimclient/lib/Jifty/Request/Mapper.pm
==============================================================================
--- jifty/branches/trimclient/lib/Jifty/Request/Mapper.pm	(original)
+++ jifty/branches/trimclient/lib/Jifty/Request/Mapper.pm	Wed Jun 27 22:59:56 2007
@@ -87,7 +87,11 @@
             for (grep {/^(result(_of)?|argument(_to)?)$/} keys %mapping) {
                 my $action  = $mapping{$_};
                 my $moniker = ref $action ? $action->moniker : $action;
-                my $name = $mapping{name} || $key;
+                # If $key is for an argument of an action, we want to
+                # extract only the argument's name, and not just use
+                # the whole encoded J:A:F-... string.
+                my (undef, $a, undef) = Jifty::Request->parse_form_field_name($key);
+                my $name = $mapping{name} || $a || $key;
 
                 my $type = ($_ =~ /result/) ? "R" : "A";
 
@@ -120,7 +124,7 @@
 
 =item request
 
-The L<Jifty::Request> object to pull action arguments from.  Defauts
+The L<Jifty::Request> object to pull action arguments from.  Defaults
 to the current request.
 
 =item response

Modified: jifty/branches/trimclient/lib/Jifty/Test.pm
==============================================================================
--- jifty/branches/trimclient/lib/Jifty/Test.pm	(original)
+++ jifty/branches/trimclient/lib/Jifty/Test.pm	Wed Jun 27 22:59:56 2007
@@ -158,9 +158,9 @@
     my $class = shift;
 
     my $test_config = File::Temp->new( UNLINK => 0 );
-    Jifty::YAML::DumpFile($test_config, $class->test_config(Jifty::Config->new));
+    Jifty::YAML::DumpFile("$test_config", $class->test_config(Jifty::Config->new));
     # Invoking bin/jifty and friends will now have the test config ready.
-    $ENV{'JIFTY_TEST_CONFIG'} ||= $test_config;
+    $ENV{'JIFTY_TEST_CONFIG'} ||= "$test_config";
     $class->builder->{test_config} = $test_config;
     {
         # Cache::Memcached stores things. And doesn't let them expire
@@ -187,7 +187,7 @@
     # Mason's disk caching sometimes causes false tests
     rmtree([ File::Spec->canonpath("$root/var/mason") ], 0, 1);
 
-$class->setup_test_database;
+    $class->setup_test_database;
 
     $class->setup_mailbox;
 }

Modified: jifty/branches/trimclient/lib/Jifty/Upgrade.pm
==============================================================================
--- jifty/branches/trimclient/lib/Jifty/Upgrade.pm	(original)
+++ jifty/branches/trimclient/lib/Jifty/Upgrade.pm	Wed Jun 27 22:59:56 2007
@@ -152,4 +152,12 @@
     $package->just_renamed($renamed);
 }
 
+
+
+=head1 SEE ALSO
+
+L<Jifty::Manual::Upgrading>
+
+=cut
+
 1;

Modified: jifty/branches/trimclient/lib/Jifty/View/Static/Handler.pm
==============================================================================
--- jifty/branches/trimclient/lib/Jifty/View/Static/Handler.pm	(original)
+++ jifty/branches/trimclient/lib/Jifty/View/Static/Handler.pm	Wed Jun 27 22:59:56 2007
@@ -50,7 +50,20 @@
 =cut
 sub new {
     my $class = shift;
-    my $self = {};
+    
+    my @roots = (Jifty->config->framework('Web')->{StaticRoot});
+    for my $plugin ( Jifty->plugins ) {
+        my $root = $plugin->static_root;
+        if ( -d $root and -r $root ) {
+            push @roots, $root;
+            Jifty->log->debug( "Plugin @{[ref($plugin)]} static root added: (@{[$root ||'']})");
+        }
+    }
+    push @roots, (Jifty->config->framework('Web')->{DefaultStaticRoot});
+
+    my $self = {
+        roots => \@roots
+    };
     bless $self, $class;
 }
 
@@ -138,14 +151,11 @@
 sub file_path {
     my $self    = shift;
     my $file    = shift;
-    my @options = (Jifty->config->framework('Web')->{StaticRoot});
-    push @options, grep { -d $_ && -r $_ } map {$_->static_root} Jifty->plugins;
-    push @options, (Jifty->config->framework('Web')->{DefaultStaticRoot});
 
     # Chomp a leading "/static" - should this be configurable?
     $file =~ s/^\/*?static//; 
 
-    foreach my $path (@options) {
+    foreach my $path ( @{$self->{'roots'}} ) {
         my $abspath = Jifty::Util->absolute_path( File::Spec->catdir($path,$file ));
         # If the user is trying to request something outside our static root, 
         # decline the request

Modified: jifty/branches/trimclient/share/web/static/js/yui/calendar.js
==============================================================================
--- jifty/branches/trimclient/share/web/static/js/yui/calendar.js	(original)
+++ jifty/branches/trimclient/share/web/static/js/yui/calendar.js	Wed Jun 27 22:59:56 2007
@@ -1,4 +1,8 @@
 /*
+    This file has been PATCHED by trs to allow selecting of out of month dates.
+    Please do not update it without also applying the patch (oom_select.patch).
+*/
+/*
 Copyright (c) 2007, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
@@ -903,6 +907,7 @@
 	MINDATE : {key:"mindate", value:null},
 	MAXDATE : {key:"maxdate", value:null},
 	MULTI_SELECT : {key:"multi_select",	value:false},
+	OOM_SELECT : {key:"oom_select",	value:false},
 	START_WEEKDAY : {key:"start_weekday", value:0},
 	SHOW_WEEKDAYS : {key:"show_weekdays", value:true},
 	SHOW_WEEK_HEADER : {key:"show_week_header", value:false},
@@ -1505,6 +1510,14 @@
 	*/
 	this.cfg.addProperty(defCfg.MULTI_SELECT.key,	{ value:defCfg.MULTI_SELECT.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
 
+    /**
+    * True if the Calendar should allow selection of out-of-month dates. False by default.
+    * @config OOM_SELECT
+    * @type Boolean
+    * @default false
+    */
+    this.cfg.addProperty(defCfg.OOM_SELECT.key,      { value:defCfg.OOM_SELECT.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
+
 	/**
 	* The weekday the week begins on. Default is 0 (Sunday).
 	* @config START_WEEKDAY
@@ -2176,7 +2189,7 @@
 		weekClass = weekPrefix + weekNum;
 
 		// Local OOM check for performance, since we already have pagedate
-		if (r !== 0 && hideBlankWeeks === true && workingDate.getMonth() != useDate.getMonth()) {
+		if (r !== 0 && hideBlankWeeks === true && workingDate.getMonth() != useDate.getMonth() && !this.cfg.getProperty(defCfg.OOM_SELECT.key)) {
 			break;
 		} else {
 
@@ -2203,7 +2216,7 @@
 				this.cellDates[this.cellDates.length] = workingArray; // Add this date to cellDates
 				
 				// Local OOM check for performance, since we already have pagedate
-				if (workingDate.getMonth() != useDate.getMonth()) {
+				if (workingDate.getMonth() != useDate.getMonth() && !this.cfg.getProperty(defCfg.OOM_SELECT.key)) {
 					cellRenderers[cellRenderers.length]=cal.renderCellNotThisMonth;
 				} else {
 					YAHOO.util.Dom.addClass(cell, workingDayPrefix + workingDate.getDay());

Added: jifty/branches/trimclient/share/web/static/js/yui/oom_select.patch
==============================================================================
--- (empty file)
+++ jifty/branches/trimclient/share/web/static/js/yui/oom_select.patch	Wed Jun 27 22:59:56 2007
@@ -0,0 +1,54 @@
+=== share/web/static/js/yui/calendar.js
+==================================================================
+--- share/web/static/js/yui/calendar.js	(revision 24788)
++++ share/web/static/js/yui/calendar.js	(local)
+@@ -1,4 +1,8 @@
+ /*
++    This file has been PATCHED by trs to allow selecting of out of month dates.
++    Please do not update it without also applying the patch (oom_select.patch).
++*/
++/*
+ Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+ Code licensed under the BSD License:
+ http://developer.yahoo.net/yui/license.txt
+@@ -903,6 +907,7 @@
+ 	MINDATE : {key:"mindate", value:null},
+ 	MAXDATE : {key:"maxdate", value:null},
+ 	MULTI_SELECT : {key:"multi_select",	value:false},
++	OOM_SELECT : {key:"oom_select",	value:false},
+ 	START_WEEKDAY : {key:"start_weekday", value:0},
+ 	SHOW_WEEKDAYS : {key:"show_weekdays", value:true},
+ 	SHOW_WEEK_HEADER : {key:"show_week_header", value:false},
+@@ -1505,6 +1510,14 @@
+ 	*/
+ 	this.cfg.addProperty(defCfg.MULTI_SELECT.key,	{ value:defCfg.MULTI_SELECT.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
+ 
++    /**
++    * True if the Calendar should allow selection of out-of-month dates. False by default.
++    * @config OOM_SELECT
++    * @type Boolean
++    * @default false
++    */
++    this.cfg.addProperty(defCfg.OOM_SELECT.key,      { value:defCfg.OOM_SELECT.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
++
+ 	/**
+ 	* The weekday the week begins on. Default is 0 (Sunday).
+ 	* @config START_WEEKDAY
+@@ -2176,7 +2189,7 @@
+ 		weekClass = weekPrefix + weekNum;
+ 
+ 		// Local OOM check for performance, since we already have pagedate
+-		if (r !== 0 && hideBlankWeeks === true && workingDate.getMonth() != useDate.getMonth()) {
++		if (r !== 0 && hideBlankWeeks === true && workingDate.getMonth() != useDate.getMonth() && !this.cfg.getProperty(defCfg.OOM_SELECT.key)) {
+ 			break;
+ 		} else {
+ 
+@@ -2203,7 +2216,7 @@
+ 				this.cellDates[this.cellDates.length] = workingArray; // Add this date to cellDates
+ 				
+ 				// Local OOM check for performance, since we already have pagedate
+-				if (workingDate.getMonth() != useDate.getMonth()) {
++				if (workingDate.getMonth() != useDate.getMonth() && !this.cfg.getProperty(defCfg.OOM_SELECT.key)) {
+ 					cellRenderers[cellRenderers.length]=cal.renderCellNotThisMonth;
+ 				} else {
+ 					YAHOO.util.Dom.addClass(cell, workingDayPrefix + workingDate.getDay());

Modified: jifty/branches/trimclient/t/Mapper/lib/Mapper/Action/CrossBridge.pm
==============================================================================
--- jifty/branches/trimclient/t/Mapper/lib/Mapper/Action/CrossBridge.pm	(original)
+++ jifty/branches/trimclient/t/Mapper/lib/Mapper/Action/CrossBridge.pm	Wed Jun 27 22:59:56 2007
@@ -6,6 +6,7 @@
 param name      => default is 'something';
 param 'quest';
 param colour    => valid are ("Blue, I mean greeeeeen!", "Green");
+param 'castle';
 
 };
 

Modified: jifty/branches/trimclient/t/Mapper/share/web/templates/index.html
==============================================================================
--- jifty/branches/trimclient/t/Mapper/share/web/templates/index.html	(original)
+++ jifty/branches/trimclient/t/Mapper/share/web/templates/index.html	Wed Jun 27 22:59:56 2007
@@ -11,6 +11,7 @@
 % my $grail_1  = Jifty->web->form->add_action( class => 'GetGrail', order => 1 );
 % my $bridge_1 = Jifty->web->new_action( class => 'CrossBridge',    order => 2 );
 <% $bridge_1->form_field( 'quest',  default_value => { result_of => $grail_1, name => 'castle' } ) %>
+<% $bridge_1->form_field( 'castle', default_value => { result_of => $grail_1 } ) %>
 <% $bridge_1->form_field( 'colour', default_value => 'Green' ) %>
 <% Jifty->web->form->submit( label => 'Do both') %>
 <% Jifty->web->form->end %>

Modified: jifty/branches/trimclient/t/Mapper/t/02-api.t
==============================================================================
--- jifty/branches/trimclient/t/Mapper/t/02-api.t	(original)
+++ jifty/branches/trimclient/t/Mapper/t/02-api.t	Wed Jun 27 22:59:56 2007
@@ -12,7 +12,7 @@
 use lib 't/lib';
 use Jifty::SubTest;
 
-use Jifty::Test tests => 11;
+use Jifty::Test tests => 13;
 
 use_ok('Jifty::Test::WWW::Mechanize');
 
@@ -38,6 +38,11 @@
 $mech->content_like(qr/got the grail/i, "Got the grail");
 $mech->content_like(qr/crossed the bridge/i, "And crossed the bridge");
 
+# Tests for proper generation of default "name" parameter to
+# argument_of and result_to
+$mech->content_unlike(qr/R`[^']+`J:A:F/, "Doesn't have full argument name");
+$mech->content_like(qr/J:A:F-castle-(\S+): Aaaaaargh/, "Has the right value name");
+
 # And then, the same, but via default_values on the form field
 $mech->form_number(3);
 ok($mech->click_button(value => "Do both"));


More information about the Jifty-commit mailing list