[Jifty-commit] r3240 - in jifty/branches/virtual-models: . lib/Jifty/Manual lib/Jifty/Module lib/Jifty/Plugin/Authentication/Password/Action lib/Jifty/Plugin/REST lib/Jifty/Plugin/SiteNews lib/Jifty/Plugin/SiteNews/Mixin lib/Jifty/Plugin/SiteNews/Mixin/Model lib/Jifty/Plugin/SiteNews/View lib/Jifty/Plugin/SkeletonApp lib/Jifty/View/Declare lib/Jifty/View/Mason lib/Jifty/Web share/web/templates/__jifty

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Sun May 13 18:36:53 EDT 2007


Author: jesse
Date: Sun May 13 18:36:51 2007
New Revision: 3240

Added:
   jifty/branches/virtual-models/lib/Jifty/Plugin/SiteNews/
   jifty/branches/virtual-models/lib/Jifty/Plugin/SiteNews/Dispatcher.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/SiteNews/Mixin/
   jifty/branches/virtual-models/lib/Jifty/Plugin/SiteNews/Mixin/Model/
   jifty/branches/virtual-models/lib/Jifty/Plugin/SiteNews/Mixin/Model/News.pm   (contents, props changed)
   jifty/branches/virtual-models/lib/Jifty/Plugin/SiteNews/View/
   jifty/branches/virtual-models/lib/Jifty/Plugin/SiteNews/View/News.pm
   jifty/branches/virtual-models/lib/Jifty/View/Declare/CRUD.pm
Modified:
   jifty/branches/virtual-models/   (props changed)
   jifty/branches/virtual-models/AUTHORS
   jifty/branches/virtual-models/lib/Jifty/Manual/Cookbook.pod
   jifty/branches/virtual-models/lib/Jifty/Module/Pluggable.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Action/Login.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/REST/Dispatcher.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm
   jifty/branches/virtual-models/lib/Jifty/View/Declare/Handler.pm
   jifty/branches/virtual-models/lib/Jifty/View/Declare/Helpers.pm
   jifty/branches/virtual-models/lib/Jifty/View/Mason/Handler.pm
   jifty/branches/virtual-models/lib/Jifty/Web/Menu.pm
   jifty/branches/virtual-models/share/web/templates/__jifty/validator.xml
   jifty/branches/virtual-models/t/TestApp/lib/TestApp/View.pm

Log:
* Merge from trunk

r56752 at pinglin (orig r3210):  ruz | 2007-05-07 17:27:38 -0400
 * FCGI.pm ties our streams and its implementation doesn't have support
   for setting IO layers with binmode, but we can do the same using
   Encode::encode. We just turn on raw mode on STDOUT and convert to
   octets ourself using Encode.pm and charset definition from the content
   type field.
 r56764 at pinglin (orig r3215):  jesse | 2007-05-07 22:43:22 -0400
  r56763 at pinglin:  jesse | 2007-05-07 22:42:53 -0400
  * Very early version of Jifty::View::Declare::CRUD lifted from BabelBee
  * Early sketch of how to possibly use it.
  
 
 r56773 at pinglin (orig r3217):  jesse | 2007-05-08 14:23:02 -0400
  r56772 at pinglin:  jesse | 2007-05-08 14:22:34 -0400
  * the new crud stuff displays a list and is editable. edits don't save.
  
 
 r56780 at pinglin (orig r3218):  clkao | 2007-05-09 04:06:57 -0400
 REST plugin: render referencing fields in a saner fashion.
 r56781 at pinglin (orig r3219):  jesse | 2007-05-10 14:21:01 -0400
  r56774 at pinglin:  jesse | 2007-05-08 14:44:48 -0400
  * CRUD builder search works
  
 
 r56782 at pinglin (orig r3220):  jesse | 2007-05-10 14:21:06 -0400
  r56777 at pinglin:  jesse | 2007-05-10 14:20:18 -0400
  * Make compile errors in autorequired modules fatal
 
 r56783 at pinglin (orig r3221):  jesse | 2007-05-10 14:21:11 -0400
  r56778 at pinglin:  jesse | 2007-05-10 14:20:38 -0400
  * Stop a certain class of validator error that causes an infinite loop in IE
 
 r56784 at pinglin (orig r3222):  jesse | 2007-05-10 14:21:18 -0400
  r56779 at pinglin:  jesse | 2007-05-10 14:20:45 -0400
  * quiet some tests
 
 r56788 at pinglin (orig r3224):  yves | 2007-05-11 08:41:42 -0400
 add a render_as_classical_menu to have the same menu with T::D view than older mason _elements/nav.
 
 r56789 at pinglin (orig r3225):  yves | 2007-05-11 09:24:00 -0400
 clean url for submenu
 
 r56790 at pinglin (orig r3226):  yves | 2007-05-11 11:47:56 -0400
 * quiet warning
 
 r56791 at pinglin (orig r3227):  falcone | 2007-05-11 12:51:12 -0400
  r18558 at ketch:  falcone | 2007-05-11 12:48:56 -0400
  * add docs to pass the pod-coverage tests
 
 r56794 at pinglin (orig r3229):  jesse | 2007-05-11 18:25:14 -0400
  r56785 at pinglin:  jesse | 2007-05-11 18:13:16 -0400
  * REST dispatcher: always use warnings and strict.
 
 r56795 at pinglin (orig r3230):  jesse | 2007-05-11 18:25:22 -0400
  r56793 at pinglin:  jesse | 2007-05-11 18:25:01 -0400
  * '*'  matches only a single level in the dispatcher. '**' matches all level.s We want to run the "Home" rule at all dispatcher levels.
  
  
 
 r56802 at pinglin (orig r3231):  jesse | 2007-05-11 23:07:26 -0400
  r56801 at pinglin:  jesse | 2007-05-11 23:06:58 -0400
  * nonworking draft of a new 'site news' plugin that uses the new crud view. 
    This plugin doesn't work because T::D alias semantics seem a little screwy.
  
 
 r56810 at pinglin (orig r3235):  jesse | 2007-05-12 04:00:58 -0400
  r56809 at pinglin:  jesse | 2007-05-12 04:00:42 -0400
  * site news plugin very close to working. Big known problem is that 'T::D package variables don't propagate quite right.
 
 r56813 at pinglin (orig r3236):  alech | 2007-05-12 05:41:52 -0400
 Added section on dynamically created binary content in the cookbook
 
 r56814 at pinglin (orig r3237):  ruz | 2007-05-12 17:48:20 -0400
 * return id of the user from action
 r56815 at pinglin (orig r3238):  jesse | 2007-05-12 19:05:44 -0400
  r56811 at pinglin:  jesse | 2007-05-12 19:04:57 -0400
  * Always use an application's 'wrapper' in preference to the Jifty default
  
 
 r56816 at pinglin (orig r3239):  jesse | 2007-05-12 19:05:51 -0400
  r56812 at pinglin:  jesse | 2007-05-12 19:05:30 -0400
  * CRUD view and a working example (sitenews)
 


Modified: jifty/branches/virtual-models/AUTHORS
==============================================================================
--- jifty/branches/virtual-models/AUTHORS	(original)
+++ jifty/branches/virtual-models/AUTHORS	Sun May 13 18:36:51 2007
@@ -27,3 +27,4 @@
 Christian Ternus <ternus at mit.edu>
 David Brunton <dbrunton at yahoo.com>
 Marc Mims <marc at questright.com>
+Alexander Klink <alech at cpan.org>

Modified: jifty/branches/virtual-models/lib/Jifty/Manual/Cookbook.pod
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Manual/Cookbook.pod	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Manual/Cookbook.pod	Sun May 13 18:36:51 2007
@@ -388,3 +388,17 @@
 If you've actually installed your app into C<@INC>, you can skip the
 C<use lib> line.
 
+=head2 Send out dynamically created binary data
+
+In a C<Template::Declare> view, do something like this:
+    
+    template 'image' => sub {
+        # ...
+        # create dynamic $image, for example using Chart::Clicker
+
+        Jifty->handler->apache->content_type('image/png');
+        Jifty->web->out($image);
+    };
+
+=for comment
+Document how to do this with Mason

Modified: jifty/branches/virtual-models/lib/Jifty/Module/Pluggable.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Module/Pluggable.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Module/Pluggable.pm	Sun May 13 18:36:51 2007
@@ -56,7 +56,10 @@
     no warnings; # This is lexical and turns off exactly one warning below -- "Can't locate package in @ISA".
                  # (for some reason, "no warnings 'syntax'" does not work as advertised here.)
                  # Note that it does _not_ turn off warnings triggered in the $module itself.
-    $module->require(); # We'd prefer to use Jifty::Util->require() here, but it spews crazy warnings
+    if ((not $module->require()) &&  ( $UNIVERSAL::require::ERROR !~ /^Can't locate/)) {
+        die $UNIVERSAL::require::ERROR;    
+    } 
+         # We'd prefer to use Jifty::Util->require() here, but it spews crazy warnings
 
     return $UNIVERSAL::require::ERROR;
 } 

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Action/Login.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Action/Login.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/Authentication/Password/Action/Login.pm	Sun May 13 18:36:51 2007
@@ -159,6 +159,7 @@
 
     # Set up our login message
     $self->result->message( $self->login_message($user));
+    $self->result->content( id => $user->id );
 
     # Actually do the signin thing.
     Jifty->web->current_user(Jifty->app_class('CurrentUser')->new( id => $user->id));

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin/REST/Dispatcher.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin/REST/Dispatcher.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/REST/Dispatcher.pm	Sun May 13 18:36:51 2007
@@ -1,5 +1,7 @@
-package Jifty::Plugin::REST::Dispatcher;
 use warnings;
+use strict;
+
+package Jifty::Plugin::REST::Dispatcher;
 
 
 
@@ -93,11 +95,27 @@
 =cut
 
 sub stringify {
+    # XXX: allow configuration to specify model fields that are to be
+    # expanded
     no warnings 'uninitialized';
-    my @r = map { defined $_ ? '' . $_ : undef } @_;
+    my @r = map { ref($_) && UNIVERSAL::isa($_, 'Jifty::Record')
+                             ? reference_to_data($_) :
+                  defined $_ ? '' . $_               : undef } @_;
     return wantarray ? @r : pop @r;
 }
 
+=head2 reference_to_data
+
+provides a saner output format for models than MyApp::Model::Foo=HASH(0x1800568)
+
+=cut
+
+sub reference_to_data {
+    my $obj = shift;
+    my ($model) = map { s/::/./g; $_ } ref($obj);
+    return { jifty_model_reference => 1, id => $obj->id, model => $model };
+}
+
 =head2 object_to_data OBJ
 
 Takes an object and converts the known types into simple data structures.

Added: jifty/branches/virtual-models/lib/Jifty/Plugin/SiteNews/Dispatcher.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/SiteNews/Dispatcher.pm	Sun May 13 18:36:51 2007
@@ -0,0 +1,10 @@
+use warnings;
+use strict;
+
+package Jifty::Plugin::SiteNews::Dispatcher;
+use base 'Jifty::Dispatcher';
+
+
+
+
+1;

Added: jifty/branches/virtual-models/lib/Jifty/Plugin/SiteNews/Mixin/Model/News.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/SiteNews/Mixin/Model/News.pm	Sun May 13 18:36:51 2007
@@ -0,0 +1,80 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::SiteNews::Mixin::Model::News;
+use Jifty::DBI::Schema;
+use base 'Jifty::DBI::Record::Plugin';
+
+our @EXPORT = qw(current_user_can);
+
+use Jifty::Plugin::SiteNews::Record schema {
+
+    my $user_class = Jifty->app_class('Model', 'User');
+
+#column author_id => refers_to $user_class; label is 'Author';
+column created   =>
+  type is 'timestamp',
+  filters are qw( Jifty::Filter::DateTime Jifty::DBI::Filter::DateTime),
+  label is 'Created on';
+column title     =>
+  type is 'text',
+  label is 'Title';
+column content   =>
+  type is 'text',
+  label is 'Article',
+  render_as is 'Textarea';
+};
+
+
+sub create {
+    my $self = shift;
+    my %args = (
+        author_id => $self->current_user->id,
+        created   => DateTime->now->iso8601,
+        title     => undef,
+        content   => undef,
+        @_
+    );
+
+    $self->SUPER::create(%args);
+}
+
+=head2 current_user_can
+
+Anyone can read news articles, only administrators can create, update,
+or delete them.
+
+=cut
+
+sub current_user_can {
+    my $self = shift;
+    my $right = shift;
+
+    return 1;
+    # Anyone can read
+    return 1 if ($right eq "read");
+    
+    # Only admins can do other things
+    return $self->current_user->user_object->access_level eq "staff";
+}
+
+=head2 as_atom_entry
+
+Returns the task as an L<XML::Atom::Entry> object.
+
+=cut
+
+sub as_atom_entry {
+    my $self = shift;
+
+    my $author = XML::Atom::Person->new;
+    $author->name($self->author->name);
+
+    my $entry = XML::Atom::Entry->new;
+    $entry->author( $author );
+    $entry->title( $self->title );
+    $entry->content( $self->content);
+    return $entry;
+}
+
+1;

Added: jifty/branches/virtual-models/lib/Jifty/Plugin/SiteNews/View/News.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/SiteNews/View/News.pm	Sun May 13 18:36:51 2007
@@ -0,0 +1,48 @@
+use warnings;
+use strict;
+
+package Jifty::Plugin::SiteNews::View::News;
+use Jifty::View::Declare -base;
+use Jifty::View::Declare::CRUD;
+
+import_templates Jifty::View::Declare::CRUD under '/';
+
+sub object_type { 'News' }
+
+sub fragment_base_path {'/news'}
+
+template 'index.html' => page {
+    title is  'Site news' ;
+    form {
+        show('/news/list');
+    }
+
+};
+
+
+template 'view' => sub {
+    my $self = shift;
+    my ( $object_type, $id ) = ( $self->object_type, get('id') );
+    my $update = new_action(
+        class => 'Update' . $object_type,
+        moniker => "update-" . Jifty->web->serial,
+        record  => $self->get_record( $id )
+    );
+
+    my $record = $self->get_record($id);
+
+    h1 { $record->title };
+    blockquote {$record->content};
+        hyperlink(
+                label   => "Edit",
+                class   => "editlink",
+                onclick => {
+                    replace_with => $self->fragment_for('update'),
+                    args         => { object_type => $object_type, id => $id }
+                },
+        );
+
+
+};
+
+1;

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm	Sun May 13 18:36:51 2007
@@ -18,7 +18,7 @@
 
     
 
-on '*' => run {
+on '**' => run {
     my $top = Jifty->web->navigation;
     $top->child( Home => url => "/", sort_order => 1, label => _('Home') );
     if ( Jifty->config->framework('AdminMode') ) {

Added: jifty/branches/virtual-models/lib/Jifty/View/Declare/CRUD.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/lib/Jifty/View/Declare/CRUD.pm	Sun May 13 18:36:51 2007
@@ -0,0 +1,271 @@
+use warnings;
+use strict;
+
+package Jifty::View::Declare::CRUD;
+use Jifty::View::Declare -base;
+use base 'Exporter';
+our @EXPORT = qw(object_type fragment_for get_record);
+
+
+sub object_type {
+    my $self = shift;
+    return $self->package_variable('object_type')|| get('object_type');
+}
+
+sub fragment_for {
+    my $self = shift;
+    my $fragment = shift;
+    
+    if (my $coderef = $self->can('fragment_for_'.$fragment) ) {
+        return $coderef->($self);
+    }
+
+    return $self->package_variable('fragment_for_'.$fragment)||$self->fragment_base_path ."/". $fragment;
+}
+
+sub fragment_base_path {
+    my $self = shift;
+    return    $self->package_variable('base_path')|| '/crud';
+}
+
+sub get_record {
+    my ($self, $id) = @_;
+
+    my $record_class = Jifty->app_class("Model", $self->object_type);
+    my $record = $record_class->new();
+    $record->load($id);
+
+    return $record;
+}
+
+template 'search' => sub {
+    my $self          = shift;
+    my ($object_type) = ( $self->object_type );
+    my $search        = Jifty->web->new_action(
+        class             => "Search" . $object_type,
+        moniker           => "search",
+        sticky_on_success => 1,
+    );
+
+    div {
+        { class is "jifty_admin" };
+        render_action($search);
+
+        $search->button(
+            label   => _('Search'),
+            onclick => {
+                submit  => $search,
+                refresh => Jifty->web->current_region->parent,
+                args    => { page => 1 }
+            }
+        );
+
+        }
+};
+
+template 'view' => sub {
+    my $self = shift;
+    my ( $object_type, $id ) = ( $self->object_type, get('id') );
+    my $update = new_action(
+        class   => 'Update' . $object_type,
+        moniker => "update-" . Jifty->web->serial,
+        record  => $self->get_record($id)
+    );
+
+    div {
+        { class is 'crud read item inline' };
+        hyperlink(
+            label   => "Edit",
+            class   => "editlink",
+            onclick => {
+                replace_with => $self->fragment_for('update'),
+                args         => { object_type => $object_type, id => $id }
+            },
+        );
+
+        my @fields = grep {
+            !( m/_confirm/
+                || lc $update->arguments->{$_}{render_as} eq 'password' )
+        } $update->argument_names;
+        render_action( $update, \@fields, { render_mode => 'read' } );
+        hr {};
+    };
+
+};
+
+template 'update' => sub {
+    my $self = shift;
+    my ( $object_type, $id ) = ( $self->object_type, get('id') );
+
+    my $record_class = Jifty->app_class( "Model", $object_type );
+    my $record = $record_class->new();
+    $record->load($id);
+    my $update = new_action(
+        class   => "Update" . $object_type,
+        moniker => "update-" . Jifty->web->serial,
+        record  => $record
+    );
+
+    div {
+        { class is "crud update item inline " . $object_type }
+
+        div {
+            { class is 'crud editlink' };
+            hyperlink(
+                label   => "Save",
+                onclick => [
+                    { submit => $update },
+                    {   replace_with => $self->fragment_for('view'),
+                        args => { object_type => $object_type, id => $id }
+                    }
+                ]
+            );
+            hyperlink(
+                label   => "Cancel",
+                onclick => {
+                    replace_with => $self->fragment_for('view'),
+                    args         => { object_type => $object_type, id => $id }
+                },
+                as_button => 1
+            );
+        };
+
+        render_action($update);
+        hr {};
+        }
+};
+
+template 'list' => sub {
+    my $self = shift;
+    my ($object_type) = ( $self->object_type );
+
+    my ( $page, $fragment_for_new_item, $item_path, $search_collection )
+        = get(qw(page fragment_for_new_item item_path search_collection));
+
+    $fragment_for_new_item ||= $self->fragment_for('new_item');
+    $item_path ||= $self->fragment_for("view");
+
+    my $collection_class
+        = Jifty->app_class( "Model", $object_type . "Collection" );
+    my $search = $search_collection || Jifty->web->response->result('search');
+    my $collection;
+    if ( !$search ) {
+        $collection = $collection_class->new();
+        $collection->unlimit();
+    } else {
+        $collection = $search->content('search');
+    }
+
+    $collection->set_page_info(
+        current_page => $page,
+        per_page     => 25
+    );
+    my $search_region = Jifty::Web::PageRegion->new(
+        name => 'search',
+        path => '/__jifty/empty',
+    );
+
+    hyperlink(
+        onclick => [
+            {   region       => $search_region->qualified_name,
+                replace_with => $self->fragment_for('search'),
+                toggle       => 1,
+                args         => { object_type => $object_type }
+            },
+        ],
+        label => 'Toggle search'
+    );
+
+    outs( $search_region->render );
+
+    if ( $collection->pager->last_page > 1 ) {
+        span {
+            { class is 'page-count' };
+            outs(
+                _( "Page %1 of %2", $page, $collection->pager->last_page ) );
+            }
+    }
+
+    if ( $collection->pager->total_entries == 0 ) {
+        outs( _("No items found") );
+    }
+
+    div {
+        { class is 'list' };
+        while ( my $item = $collection->next ) {
+            render_region(
+                name     => 'item-' . $item->id,
+                path     => $item_path,
+                defaults => { id => $item->id, object_type => $object_type }
+            );
+        }
+    };
+
+    div {
+        { class is 'paging' };
+        if ( $collection->pager->previous_page ) {
+            span {
+                { class is 'prev-page' };
+                hyperlink(
+                    label   => "Previous Page",
+                    onclick => {
+                        args => { page => $collection->pager->previous_page }
+                    }
+                );
+                }
+        }
+        if ( $collection->pager->next_page ) {
+            span {
+                { class is 'next-page' };
+                hyperlink(
+                    label   => "Next Page",
+                    onclick =>
+                        { args => { page => $collection->pager->next_page } }
+                );
+                }
+        }
+    };
+
+    if ($fragment_for_new_item) {
+        render_region(
+            name     => 'new_item',
+            path     => $fragment_for_new_item,
+            defaults => { object_type => $object_type },
+        );
+    }
+};
+
+
+template 'new_item' => sub {
+    my $self = shift;
+    my ( $object_type, $id ) = ( $self->object_type, get('id') );
+
+    my $record_class = Jifty->app_class( "Model", $object_type );
+    my $create = Jifty->web->new_action( class => 'Create' . $object_type );
+
+    div {
+        { class is 'crud create item inline' };
+        render_action($create);
+
+        outs(
+            Jifty->web->form->submit(
+                label   => 'Create',
+                onclick => [
+                    { submit       => $create },
+                    { refresh_self => 1 },
+                    {   element =>
+                            undef,  #$region->parent->get_element('div.list'),
+                        append => $self->fragment_for('view'),
+                        args   => {
+                            object_type => $object_type,
+                            id => { result_of => $create, name => 'id' },
+                        },
+                    },
+                ]
+            )
+        );
+        }
+};
+
+1;
+

Modified: jifty/branches/virtual-models/lib/Jifty/View/Declare/Handler.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/View/Declare/Handler.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/View/Declare/Handler.pm	Sun May 13 18:36:51 2007
@@ -83,18 +83,12 @@
         Jifty->handler->apache->send_http_header;
     }
 
+    binmode *STDOUT;
     if ( my ($enc) = $r->content_type =~ /charset=([\w-]+)$/ ) {
-        if ( lc($enc) =~ /utf-?8/) {
-            binmode *STDOUT, ":utf8" or die "couldn't set layers: $!";
-        }
-        else {
-            binmode *STDOUT, ":encoding($enc)" or die "couldn't set layers: $!";
-        }
+        print STDOUT Encode::encode($enc, $content);
     } else {
-        binmode *STDOUT or die "couldn't set layers: $!";
+        print STDOUT $content;
     }
-
-    print STDOUT $content;
     return undef;
 }
 

Modified: jifty/branches/virtual-models/lib/Jifty/View/Declare/Helpers.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/View/Declare/Helpers.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/View/Declare/Helpers.pm	Sun May 13 18:36:51 2007
@@ -155,7 +155,8 @@
 
 sub render_action(@) {
     my ( $action, $fields, $field_args ) = @_;
-    my @f = $fields && @$fields ? @$fields : $action->argument_names;
+   
+    my @f = ($fields && ref ($fields) eq 'ARRAY') ? @$fields : $action->argument_names;
     foreach my $argument (@f) {
         outs_raw( $action->form_field( $argument, %$field_args ) );
     }
@@ -276,7 +277,12 @@
     sub {
         my $self = shift;
         Jifty->handler->apache->content_type('text/html; charset=utf-8');
+        if ( my $wrapper = Jifty->app_class('View')->can('wrapper') ) {
+            $wrapper->(sub { $code->($self)});
+        } else {
+
         wrapper(sub { $code->($self) });
+    }
     };
 }
 

Modified: jifty/branches/virtual-models/lib/Jifty/View/Mason/Handler.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/View/Mason/Handler.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/View/Mason/Handler.pm	Sun May 13 18:36:51 2007
@@ -131,17 +131,6 @@
 
     $r->content_type || $r->content_type('text/html; charset=utf-8'); # Set up a default
 
-    if ( my ($enc) = $r->content_type =~ /charset=([\w-]+)$/ ) {
-        if ( lc($enc) =~ /utf-?8/ ) {
-            binmode *STDOUT, ":utf8";
-        }
-        else {
-            binmode *STDOUT, ":encoding($enc)";
-        }
-    } else {
-        binmode *STDOUT;
-    }
-
     unless ( $r->http_header_sent or not $m->auto_send_headers ) {
         $r->send_http_header();
     }
@@ -150,7 +139,12 @@
     # wouldn't have to keep checking whether headers have been
     # sent and what the $r->method is.  That would require
     # additions to the Request interface, though.
-    print STDOUT grep {defined} @_;
+    binmode *STDOUT;
+    if ( my ($enc) = $r->content_type =~ /charset=([\w-]+)$/ ) {
+        print STDOUT map Encode::encode($enc, $_), grep {defined} @_;
+    } else {
+        print STDOUT grep {defined} @_;
+    }
 }
 
 

Modified: jifty/branches/virtual-models/lib/Jifty/Web/Menu.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Web/Menu.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Web/Menu.pm	Sun May 13 18:36:51 2007
@@ -70,6 +70,8 @@
     $self->{url} = URI->new_abs($self->{url}, $self->parent->url . "/")->as_string
       if $self->parent and $self->parent->url;
 
+    $self->{url} =~ s!///!/! if $self->{url};
+
     return $self->{url};
 }
 
@@ -197,10 +199,8 @@
 
 Render this menu with html markup as an inline dropdown menu.
 
-
 =cut
 
-
 sub render_as_context_menu {
 	my $self = shift;
     	Jifty->web->out( qq{<ul class="context_menu">});
@@ -253,6 +253,50 @@
 
 }
 
+=head2 render_as_classical_menu
+
+Render this menu with html markup as old classical mason menu. 
+Currently renders one level of submenu, if it exists.
+
+=cut
+
+sub  render_as_classical_menu {
+	my $self = shift;
+    my @kids = $self->children;
+
+    Jifty->web->out( qq{<ul class="menu">});
+
+    for (@kids) {
+	    $_->_render_as_classical_menu_item();
+    }
+
+    Jifty->web->out(qq{</ul>});
+    '';
+}
+
+sub _render_as_classical_menu_item {
+    my $self = shift;
+    my %args = (
+        class => '',
+        @_
+    );
+    my @kids = $self->children;
+    Jifty->web->out( qq{<li} . ($self->active ? qq{ class="active"} : '' ) . qq{>} );
+    Jifty->web->out( $self->as_link );
+    if (@kids) {
+      Jifty->web->out( qq{<ul class="submenu">} );
+      for (@kids) {
+         Jifty->web->out( qq{<li} . ($_->active ? qq{ class="active"} : '' ) . qq{>} );
+         Jifty->web->out( $_->as_link );
+         Jifty->web->out("</li>");
+      }
+      Jifty->web->out(qq{</ul>});
+    }
+    Jifty->web->out(qq{</li>});
+    '';
+
+}
+
 =head2 render_as_yui_menubar
 
 Render menubar with YUI menu, suitable for an application's menu.

Modified: jifty/branches/virtual-models/share/web/templates/__jifty/validator.xml
==============================================================================
--- jifty/branches/virtual-models/share/web/templates/__jifty/validator.xml	(original)
+++ jifty/branches/virtual-models/share/web/templates/__jifty/validator.xml	Sun May 13 18:36:51 2007
@@ -8,6 +8,11 @@
 $writer->startTag("validation");
 for my $ra ( Jifty->web->request->actions ) {
     my $action = Jifty->web->new_action_from_request($ra);
+    unless ($action ){
+        warn "Couldn't turn $ra into an action";
+        next;
+        
+    }
     $writer->startTag( "validationaction", id => $action->register_name );
     for my $arg ( $action->argument_names ) {
         if ( not $action->arguments->{$arg}->{ajax_validates} ) {

Modified: jifty/branches/virtual-models/t/TestApp/lib/TestApp/View.pm
==============================================================================
--- jifty/branches/virtual-models/t/TestApp/lib/TestApp/View.pm	(original)
+++ jifty/branches/virtual-models/t/TestApp/lib/TestApp/View.pm	Sun May 13 18:36:51 2007
@@ -47,5 +47,23 @@
 import_templates TestApp::View::base under '/base';
 import_templates TestApp::View::instance under '/instance';
 
+use Jifty::View::Declare::CRUD;
+
+foreach my $model  (Jifty->class_loader->models) {
+    my $bare_model;
+    if ($model =~ /^.*::(.*?)$/) {
+        $bare_model = $1;
+    }
+    alias Jifty::View::Declare::CRUD under '/crud/'.$bare_model,  { object_type => $bare_model, base_path => '/crud/'.$bare_model };
+
+}
+
+
+template userlist => page {
+    form {
+    render_region( "users", path => '/crud/User/list');
+    };
+};
+
 
 1;


More information about the Jifty-commit mailing list