[Jifty-commit] r2831 - in jifty/branches/template-declare: . examples/Chat/etc lib/Jifty lib/Jifty/Plugin lib/Jifty/Plugin/AdminUI lib/Jifty/Plugin/CompressedCSSandJS lib/Jifty/Plugin/Halo lib/Jifty/Plugin/OnlineDocs lib/Jifty/Plugin/OnlineDocs/share/web/templates/__jifty lib/Jifty/Plugin/Yullio share/plugins/Jifty/AdminUI share/plugins/Jifty/OnlineDocs share/plugins/Jifty/Plugin/AdminUI share/plugins/Jifty/Plugin/OnlineDocs

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Fri Feb 23 17:25:37 EST 2007


Author: jesse
Date: Fri Feb 23 17:25:35 2007
New Revision: 2831

Added:
   jifty/branches/template-declare/lib/Jifty/Plugin/AdminUI/
   jifty/branches/template-declare/lib/Jifty/Plugin/AdminUI.pm
   jifty/branches/template-declare/lib/Jifty/Plugin/AdminUI/View.pm
   jifty/branches/template-declare/lib/Jifty/Plugin/CompressedCSSandJS/
   jifty/branches/template-declare/lib/Jifty/Plugin/CompressedCSSandJS.pm
   jifty/branches/template-declare/lib/Jifty/Plugin/CompressedCSSandJS/Dispatcher.pm
   jifty/branches/template-declare/lib/Jifty/Plugin/Halo/
   jifty/branches/template-declare/lib/Jifty/Plugin/Halo.pm
   jifty/branches/template-declare/lib/Jifty/Plugin/Halo/View.pm
   jifty/branches/template-declare/lib/Jifty/Plugin/OnlineDocs.pm
   jifty/branches/template-declare/lib/Jifty/Plugin/OnlineDocs/View.pm
   jifty/branches/template-declare/lib/Jifty/Plugin/Yullio/
   jifty/branches/template-declare/lib/Jifty/Plugin/Yullio/View.pm
   jifty/branches/template-declare/share/plugins/Jifty/Plugin/AdminUI/
      - copied from r2830, /jifty/branches/template-declare/share/plugins/Jifty/AdminUI/
   jifty/branches/template-declare/share/plugins/Jifty/Plugin/OnlineDocs/
      - copied from r2830, /jifty/branches/template-declare/share/plugins/Jifty/OnlineDocs/
Removed:
   jifty/branches/template-declare/lib/Jifty/Plugin/OnlineDocs/share/web/templates/__jifty/
   jifty/branches/template-declare/share/plugins/Jifty/AdminUI/
   jifty/branches/template-declare/share/plugins/Jifty/OnlineDocs/
Modified:
   jifty/branches/template-declare/   (props changed)
   jifty/branches/template-declare/examples/Chat/etc/config.yml
   jifty/branches/template-declare/lib/Jifty/Config.pm
   jifty/branches/template-declare/lib/Jifty/Handler.pm
   jifty/branches/template-declare/lib/Jifty/Plugin.pm
   jifty/branches/template-declare/share/plugins/Jifty/Plugin/OnlineDocs/web/templates/__jifty/online_docs/index.html

Log:
 r48498 at 233:  jesse | 2007-02-23 16:55:13 -0500
 * Extracted OnlineDocs, CSS/JS compression, Halos and the AdminUI into plugins
 * Set up the aforementioned plugins to be installed by default
 * Set up the aforementioned plugins to be enabled by default
 
 * Set Jifty up to allow plugins to install their share/ directories under jifty's (in addition to their own custom location)
 * Set up Jifty to better detect when a plugin had a T::D or Mason view
 
 


Modified: jifty/branches/template-declare/examples/Chat/etc/config.yml
==============================================================================
--- jifty/branches/template-declare/examples/Chat/etc/config.yml	(original)
+++ jifty/branches/template-declare/examples/Chat/etc/config.yml	Fri Feb 23 17:25:35 2007
@@ -17,7 +17,7 @@
   DevelMode: 0
   L10N:
     PoDir: share/po
-  LogLevel: INFO
+  LogLevel: DEBUG
   Mailer: Sendmail
   MailerArgs: []
   Plugins: []

Modified: jifty/branches/template-declare/lib/Jifty/Config.pm
==============================================================================
--- jifty/branches/template-declare/lib/Jifty/Config.pm	(original)
+++ jifty/branches/template-declare/lib/Jifty/Config.pm	Fri Feb 23 17:25:35 2007
@@ -263,7 +263,14 @@
             L10N       => {
                 PoDir => "share/po",
             },
-            Plugins    => [],
+            Plugins    => [
+            { REST => {},
+        },
+        {       Halo => {},},
+        {OnlineDocs => {},},
+        {        CompressedCSSandJS => {},},
+        {AdminUI => {},}
+            ],
             Web        => {
                 Port => '8888',
                 BaseURL => 'http://localhost',

Modified: jifty/branches/template-declare/lib/Jifty/Handler.pm
==============================================================================
--- jifty/branches/template-declare/lib/Jifty/Handler.pm	(original)
+++ jifty/branches/template-declare/lib/Jifty/Handler.pm	Fri Feb 23 17:25:35 2007
@@ -137,7 +137,10 @@
 
     for my $plugin (Jifty->plugins) {
         my $comp_root = $plugin->template_root;
-        next unless $comp_root;
+        unless  ( $comp_root and -d $comp_root) {
+            Jifty->log->debug( "Plugin @{[ref($plugin)]} doesn't appear to have a valid mason template component root ($comp_root)");
+            next;
+        }
         push @{ $config{comp_root} }, [ ref($plugin)."-".Jifty->web->serial => $comp_root ];
     }
     push @{$config{comp_root}}, [jifty => Jifty->config->framework('Web')->{'DefaultTemplateRoot'}];
@@ -167,7 +170,10 @@
 
     for my $plugin ( Jifty->plugins ) {
         my $comp_root = $plugin->template_class;
-        next unless $comp_root;
+        unless (defined $comp_root and $comp_root->isa('Template::Declare') ){
+            Jifty->log->debug( "Plugin @{[ref($plugin)]} doesn't appear to have a ::View class that's a Template::Declare subclass");
+            next;
+        }
         push @{ $config{roots} }, $comp_root ;
     }
 

Modified: jifty/branches/template-declare/lib/Jifty/Plugin.pm
==============================================================================
--- jifty/branches/template-declare/lib/Jifty/Plugin.pm	(original)
+++ jifty/branches/template-declare/lib/Jifty/Plugin.pm	Fri Feb 23 17:25:35 2007
@@ -91,6 +91,25 @@
     Jifty->api->allow(qr/^\Q$class\E::Action/);
 }
 
+sub _calculate_share {
+    my $self = shift;
+    my $class = ref($self) || $self;
+    unless ( $self->{share} ) {
+        local $@; # We're just avoiding File::ShareDir's failure behaviour of dying
+        eval { $self->{share} = File::ShareDir::module_dir($class) };
+    }
+    unless ( $self->{share} ) {
+        local $@ ; # We're just avoiding File::ShareDir's failure behaviour of dying
+        eval { $self->{share} = File::ShareDir::module_dir('Jifty') };
+        if ( $self->{'share'} ) {
+            my $class_to_path = $class;
+            $class_to_path =~ s|::|/|g;
+            $self->{share} .= "/plugins/" . $class_to_path;
+        }
+    }
+}
+
+
 =head2 template_root
 
 Returns the root of the C<HTML::Mason> template directory for this plugin
@@ -99,11 +118,7 @@
 
 sub template_root {
     my $self = shift;
-    my $class = ref($self) || $self;
-    unless (exists $self->{share}) {
-        $self->{share} = undef;
-        eval { $self->{share} = File::ShareDir::module_dir($class) };
-    }
+    $self->_calculate_share();
     return unless $self->{share};
     return $self->{share}."/web/templates";
 }
@@ -130,11 +145,6 @@
 
 sub static_root {
     my $self = shift;
-    my $class = ref($self) || $self;
-    unless (exists $self->{share}) {
-        $self->{share} = undef;
-        eval { $self->{share} = File::ShareDir::module_dir($class) };
-    }
     return unless $self->{share};
     return $self->{share}."/web/static";
 }

Added: jifty/branches/template-declare/lib/Jifty/Plugin/AdminUI.pm
==============================================================================
--- (empty file)
+++ jifty/branches/template-declare/lib/Jifty/Plugin/AdminUI.pm	Fri Feb 23 17:25:35 2007
@@ -0,0 +1,10 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::AdminUI;
+use base qw/Jifty::Plugin/;
+
+# Your plugin goes here.  If takes any configuration or arguments, you
+# probably want to override L<Jifty::Plugin/init>.
+
+1;

Added: jifty/branches/template-declare/lib/Jifty/Plugin/AdminUI/View.pm
==============================================================================
--- (empty file)
+++ jifty/branches/template-declare/lib/Jifty/Plugin/AdminUI/View.pm	Fri Feb 23 17:25:35 2007
@@ -0,0 +1,487 @@
+package Jifty::Plugin::AdminUI::View;
+
+use strict;
+use warnings;
+
+use Jifty::View::Declare -base;
+
+use Scalar::Defer;
+
+warn "here";
+
+template '__jifty/admin/_elements/nav' => sub {
+    my $nav =
+      Jifty->web->navigation->child(
+        "Administration" => url => '/__jifty/admin/' );
+    foreach my $model ( Jifty->class_loader->models ) {
+        next unless $model->isa('Jifty::Record');
+        next unless ( $model =~ /^(?:.*)::(.*?)$/ );
+        my $type = $1;
+        $nav->child( $type => url => '/__jifty/admin/model/' . $type );
+    }
+    return;
+};
+
+template '__jifty/admin/action/dhandler' => sub {
+    # XXX move to dispatcher
+    my $action_class = Jifty->api->qualify( die('$m->dhandler_arg') );
+
+    my $object_type = die "No object type defined";
+
+    my $action = new_action(
+        class   => $action_class,
+        moniker => "run-$action_class",
+    );
+
+    $action->sticky_on_failure(1);
+    page {
+        title is { _('Manage records: [_1]',$object_type) };
+        form {
+
+            for ( $action->argument_names ) {
+                render_param( $action, $_ );
+            }
+
+            Jifty->web->form->submit( label => _("Run the action") );
+        };
+
+        h2 { _('Done?') };
+        hyperlink(
+            url   => "/__jifty/admin/",
+            label => _('Back to the admin console')
+        );
+
+      }
+};
+
+template '__jifty/admin/autohandler' => sub {
+
+# If "AdminMode" is turned off in Jifty's config file, don't let people at the admin UI.
+    unless ( Jifty->config->framework('AdminMode') ) {
+        redirect('/__jifty/error/permission_denied');
+        return;
+    }
+    show('/__jifty/admin/elements/nav'); # XXX TODO hm. should be in dispatcher.
+};
+
+template '__jifty/admin/fragments/list/list' => sub {
+    my ( $object_type, $page, $new_slot, $item_path, $list_path, $limit_field, $limit_val, $per_page, $sort_by, $order, $search_slot ) =
+      get(qw( object_type page new_slot item_path list_path limit_field limit_val per_page sort_by order search_slot));
+
+    $page ||= 1;
+    $new_slot = 1 unless defined $new_slot;
+    $item_path ||= "/__jifty/admin/fragments/list/view";
+    $list_path ||= "/__jifty/admin/fragments/list";
+    $per_page ||=25;
+    $search_slot ||=1; 
+
+
+
+    my $collection_class =
+      Jifty->app_class( "Model", $object_type . "Collection" );
+    my $search = Jifty->web->response->result('search');
+    my $collection  = $collection_class->new();
+;
+    if ( !$search ) {
+   if ( $limit_field && $limit_val ) {
+      $collection->limit(column => $limit_field, value => $limit_val);
+   } else {
+      $collection->unlimit();
+   }
+   $collection->order_by(column => $sort_by, order=>'ASC') if ($sort_by && !$order);
+   $collection->order_by(column => $sort_by, order=>'DESC') if ($sort_by && $order);
+    }
+    else {
+        $collection = $search->content('search');
+        warn $collection->build_select_query;
+    }
+
+    $collection->set_page_info(
+        current_page => $page,
+        per_page     => $per_page
+    );
+
+if ($search_slot) {
+    my $search_region = Jifty::Web::PageRegion->new(
+        name => 'search',
+        path => '/__jifty/empty',
+    );
+
+    hyperlink(
+        onclick => [
+            {
+                region       => $search_region->qualified_name,
+                replace_with => $list_path. 'search',
+                toggle       => 1,
+                args         => { object_type => $object_type }
+            },
+        ],
+        label => _('Toggle search')
+    );
+
+    $search_region->render;
+}
+    if ( $collection->pager->last_page > 1 ) {
+        with( class => "page-count" ), span {
+            _( 'Page %1 of %2', $page, $collection->pager->last_page );
+          }
+    }
+
+    if ( $collection->pager->total_entries == 0 ) {
+        outs(_('No items found'));
+    } else {
+        outs(_('%1 entries', $collection-> count));
+        show( $list_path.'header', object_type => $object_type, list_path => $list_path, 
+    mask_field => $limit_field, mask_val => $limit_val, sort_by => $sort_by, order => $order);
+    }
+
+    with( class => "list" ), div {
+        while ( my $item = $collection->next ) {
+            Jifty->web->region(
+                name     => 'item-' . $item->id,
+                path     => $item_path,
+                defaults => { id => $item->id, object_type => $object_type,
+list_path => $list_path, mask_field => $limit_field , mask_val => $limit_val 
+ }
+            );
+        }
+
+    };
+
+    with( class => "paging" ), div {
+        if ( $collection->pager->previous_page ) {
+            with( class => "prev-page" ), span {
+                hyperlink(
+                    label   => _("Previous Page"),
+                    onclick =>
+                      { args => { page => $collection->pager->previous_page } }
+                );
+              }
+        }
+        if ( $collection->pager->next_page ) {
+            with( class => "next-page" ), span {
+                hyperlink(
+                    label   => _("Next Page"),
+                    onclick =>
+                      { args => { page => $collection->pager->next_page } }
+                );
+              }
+        }
+    };
+
+    if ($new_slot) {
+        Jifty->web->region(
+            name     => 'new_item',
+        path => $list_path.'new_item',
+        defaults => {   object_type => $object_type, list_path => $list_path,
+                     mask_field => $limit_field , mask_val => $limit_val },
+        );
+    }
+
+};
+
+# When you hit "save" and create a item, you want to put a fragment
+# containing the new item in the associated list and refresh the current
+# fragment
+#
+template '__jifty/admin/fragments/list/new_item' => sub {
+    my ( $object_type, $region, $mask_field, $mask_val, $list_path ) = get(qw(object_type region mask_field mask_val list_path));
+    my $record_class = Jifty->app_class( "Model", $object_type );
+    my $create = new_action( class => 'Create' . $object_type );
+    if ($mask_field) {
+        $create->hidden($mask_field,$mask_val);
+        }
+
+    div {
+    attr{ class => "jifty_admin create item inline" };
+        foreach my $argument ( $create->argument_names ) {
+            if ( $argument ne $mask_field ) {
+            render_param( $create => $argument );
+        }
+        }
+    };
+
+    Jifty->web->form->submit(
+        label   => _('Create'),
+        onclick => [
+            { submit       => $create },
+            { refresh_self => 1 },
+            {
+                element => $region->parent->get_element('div.list'),
+                append  => $list_path.'view',
+                args    => {
+                    object_type => $object_type,
+                    list_path => $list_path,
+                    id          => { result_of => $create, name => 'id' },
+                },
+            },
+        ]
+      )
+
+};
+
+template '__jifty/admin/fragments/list/header' => sub {
+my ($object_type, $mask_val , $mask_field, $sort_by, $order, $list_path) =
+get(qw(object_type mask_val mask_field sort_by order list_path));
+my $record_class = Jifty->app_class("Model", $object_type);
+my $record = $record_class->new();
+ my $update = Jifty->web->new_action(class => 'Update'.$object_type);
+div {
+attr { class=>"jifty_admin_header" };
+
+ foreach my $argument ($update->argument_names) {
+ unless( $argument eq $mask_field ||  $argument eq 'id' || $argument =~ /_confirm$/i
+        && lc $update->arguments->{$argument}{render_as} eq 'password') {
+span { attr {class=>"<% ($sort_by && !$order && $sort_by eq $argument)?'up_select':'up' %>"};
+
+    hyperlink(
+        label   => _("asc"),
+        onclick => 
+            { 
+            replace_with => $list_path.'list' ,
+            args   => {
+                object_type => $object_type,
+                limit_val => $mask_val,
+                limit_field => $mask_field,
+                list_path => $list_path,
+                sort_by => $argument,
+                order => undef
+                },
+            },
+        #as_button => 1
+        );
+}
+span { attr{ class=>"<% ($sort_by && $order && $sort_by eq $argument )?'down_select':'down' %>" };
+    hyperlink(
+        label   => _("desc"),
+        onclick => 
+            {
+            replace_with => $list_path.'list',
+            args   => {
+                object_type => $object_type,
+                limit_val => $mask_val,
+                limit_field => $mask_field,
+                list_path => $list_path,
+                sort_by => $argument,
+                order => 'D'
+                },
+            },
+        #as_button => 1
+        )
+}
+span { attr { class=>"field" };
+    outs ($argument );
+}
+ }
+ }
+hr {};
+}
+};
+
+
+template '__jifty/admin/fragments/list/search' => sub {
+    my ($object_type) = get(qw(object_type));
+    my $search = new_action(
+        class             => "Search" . $object_type,
+        moniker           => "search",
+        sticky_on_success => 1,
+    );
+
+    with( class => "jifty_admin" ), div {
+        for my $arg ( $search->argument_names ) {
+            render_param( $search => $arg );
+        }
+
+        $search->button(
+            label   => _('Search'),
+            onclick => {
+                submit  => $search,
+                refresh => Jifty->web->current_region->parent,
+                args    => { page => 1 }
+            }
+        );
+        hr {};
+      }
+};
+
+template '__jifty/admin/fragments/list/update' => sub {
+    my ( $id, $object_type, $mask_field, $mask_val, $list_path ) = get(qw(id object_type mask_field mask_val list_path));
+    my $record_class = Jifty->app_class( "Model", $object_type );
+    my $record       = $record_class->new();
+    my $update       = new_action(
+        class   => "Update" . $object_type,
+        moniker => "update-" . Jifty->web->serial,
+        record  => $record
+    );
+    with( class => "jifty_admin update item inline $object_type" ), div {
+        with( class => "editlink" ), div {
+            hyperlink(
+                label   => _("Save"),
+                onclick => [
+                    { submit => $update },
+                    {
+                        replace_with => $list_path.'view',
+                        args => { object_type => $object_type, id => $id, list_path => $list_path }
+                    }
+                ]
+            );
+
+            hyperlink(
+                label   => _("Cancel"),
+                onclick => {
+                    replace_with => $list_path.'view',
+                    args         => { object_type => $object_type, id => $id, list_path => $list_path}
+                },
+                as_button => 1
+            );
+
+        };
+        if ($mask_field) {
+        $update->hidden($mask_field, $mask_val);
+        }
+
+        foreach my $argument ( $update->argument_names ) {
+            if ( $argument ne $mask_field ) {
+            render_param( $update => $argument );
+            }
+        }
+        hr {};
+    };
+};
+
+template '__jifty/admin/fragments/list/view' => sub {
+    my ( $id, $object_type, $mask_field, $mask_val, $list_path ) = get(qw( id object_type mask_field mask_val list_path ));
+    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
+    );
+    my $delete = new_action(
+        class   => "Delete" . $object_type,
+        moniker => "delete-" . Jifty->web->serial,
+        record  => $record
+    );
+
+    with( class => "jifty_admin read item inline" ), div {
+
+        Jifty->web->form->submit(
+            class   => "editlink",
+            label   => _("Delete"),
+            onclick => [
+               { confirm => _("Confirm delete?")},
+                {submit  => $delete},
+                {delete  => Jifty->web->current_region->qualified_name }
+            ]
+        );
+        hyperlink(
+            label   => _("Edit"),
+            class   => "editlink",
+            onclick => {
+                replace_with => $list_path."update",
+                args         => { object_type => $object_type, id => $id, 
+list_path => $list_path, mask_field => $mask_field, mask_val => $mask_val}
+            },
+            as_button => 1
+        );
+
+        $delete->hidden( 'id', $id );
+        foreach my $argument ( $update->argument_names ) {
+            unless ( $argument eq $mask_field ||  $argument =~ /_confirm$/
+                && lc $update->arguments->{$argument}{render_as} eq 'password' )
+            {
+                render_param( $update => $argument, render_mode => 'read' );
+            }
+        }
+
+        hr {};
+    };
+
+};
+
+template '__jifty/admin/index' => page {
+    title is 'Jifty Administrative Console' ;
+
+        h1 { _('Database Administration') };
+
+        p {
+            _(
+'This console lets you manage the records in your Jifty database. Below, you should see a list of all your database tables. Feel free to go through and add, delete or modify records.'
+            );
+        };
+
+        p {
+            _(
+'To disable this administrative console, add "AdminMode: 0" under the "framework:" settings in the config file (etc/config.yml).'
+            );
+        };
+
+        h2 { _('Models') };
+        ul {
+            foreach my $model ( Jifty->class_loader->models ) {
+                next unless $model->isa('Jifty::Record');
+                next unless ( $model =~ /^(?:.*)::(.*?)$/ );
+                my $type = $1;
+                li {
+                    hyperlink(
+                        url   => '/__jifty/admin/model/' . $type,
+                        label => $type
+                    );
+                };
+            }
+        };
+        h2 { _('Actions') };
+        ul {
+            foreach my $action ( Jifty->api->actions ) {
+                Jifty::Util->require($action);
+                next
+                  if (  $action->can('autogenerated')
+                    and $action->autogenerated );
+                li {
+                    hyperlink(
+                        url   => '/__jifty/admin/action/' . $action,
+                        label => $action
+                    );
+                };
+            }
+        };
+        h2 { _('Done?') };
+        Jifty->web->return(
+            to    => "/",
+            label => _('Back to the application')
+        );
+};
+
+template '__jifty/admin/model/dhandler' => page {
+    # XXX move to dispatcher
+    my $object_type = die('$m->dhandler_arg');
+
+    my $collection_class =
+      Jifty->app_class( "Model", $object_type . "Collection" );
+    my $records = $collection_class->new();
+    $records->unlimit;
+        h1 { _( 'Manage records: [_1]', $object_type ) };
+        form {
+            Jifty->web->region(
+                name     => "admin-$object_type",
+                path     => "/__jifty/admin/fragments/list/list",
+                defaults => {
+                    object_type   => $object_type,
+                    render_submit => 1
+                }
+            );
+
+        };
+
+        h2 { _('Done?') };
+        hyperlink(
+            url   => "/__jifty/admin/",
+            label => _('Back to the admin console')
+        );
+
+};
+
+warn "and here";
+1;

Added: jifty/branches/template-declare/lib/Jifty/Plugin/CompressedCSSandJS.pm
==============================================================================
--- (empty file)
+++ jifty/branches/template-declare/lib/Jifty/Plugin/CompressedCSSandJS.pm	Fri Feb 23 17:25:35 2007
@@ -0,0 +1,12 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::CompressedCSSandJS;
+use base qw/Jifty::Plugin/;
+
+# Your plugin goes here.  If takes any configuration or arguments, you
+# probably want to override L<Jifty::Plugin/init>.
+
+
+
+1;

Added: jifty/branches/template-declare/lib/Jifty/Plugin/CompressedCSSandJS/Dispatcher.pm
==============================================================================
--- (empty file)
+++ jifty/branches/template-declare/lib/Jifty/Plugin/CompressedCSSandJS/Dispatcher.pm	Fri Feb 23 17:25:35 2007
@@ -0,0 +1,97 @@
+
+package Jifty::Plugin::CompressedCSSandJS::Dispatcher;
+
+use warnings;
+use strict;
+
+use Jifty::Dispatcher -base;
+
+on '/__jifty/js/*' => run {
+    my $arg = $1;
+    warn "My arg is $arg";
+    if ( $arg !~ /^[0-9a-f]{32}\.js$/ ) {
+
+        # This doesn't look like a real request for squished JS,
+        # so redirect to a more failsafe place
+        Jifty->web->redirect( "/static/js/" . $arg );
+    }
+
+    Jifty->web->generate_javascript;
+
+    use HTTP::Date ();
+
+    if ( Jifty->handler->cgi->http('If-Modified-Since')
+        and $arg eq Jifty->web->cached_javascript_digest . '.js' )
+    {
+        Jifty->log->debug("Returning 304 for cached javascript");
+        Jifty->handler->apache->header_out( Status => 304 );
+        Jifty->handler->apache->send_http_header();
+        return;
+    }
+
+    Jifty->handler->apache->content_type("application/x-javascript");
+    Jifty->handler->apache->header_out( 'Expires' => HTTP::Date::time2str( time + 31536000 ) );
+
+    # XXX TODO: If we start caching the squished JS in a file somewhere, we
+    # can have the static handler serve it, which would take care of gzipping
+    # for us.
+    use Compress::Zlib qw();
+
+    if ( Jifty::View::Static::Handler->client_accepts_gzipped_content ) {
+        Jifty->log->debug("Sending gzipped squished JS");
+        Jifty->handler->apache->header_out( "Content-Encoding" => "gzip" );
+        Jifty->handler->apache->send_http_header();
+        binmode STDOUT;
+        print Compress::Zlib::memGzip( Jifty->web->cached_javascript );
+    } else {
+        Jifty->log->debug("Sending squished JS");
+        Jifty->handler->apache->send_http_header();
+        print Jifty->web->cached_javascript;
+    }
+    abort;
+};
+
+on '/__jifty/css/*' => run {
+    my $arg = $1;
+    warn "My arg is $arg";
+    if ( $arg !~ /^[0-9a-f]{32}\.css$/ ) {
+
+        # This doesn't look like a real request for squished CSS,
+        # so redirect to a more failsafe place
+        Jifty->web->redirect( "/static/css/" . $arg );
+    }
+
+    Jifty->web->generate_css;
+
+    use HTTP::Date ();
+
+    if ( Jifty->handler->cgi->http('If-Modified-Since')
+        and $arg eq Jifty->web->cached_css_digest . '.css' )
+    {
+        Jifty->log->debug("Returning 304 for cached css");
+        Jifty->handler->apache->header_out( Status => 304 );
+        return;
+    }
+
+    Jifty->handler->apache->content_type("text/css");
+    Jifty->handler->apache->header_out( 'Expires' => HTTP::Date::time2str( time + 31536000 ) );
+
+    # XXX TODO: If we start caching the squished CSS in a file somewhere, we
+    # can have the static handler serve it, which would take care of gzipping
+    # for us.
+    use Compress::Zlib qw();
+
+    if ( Jifty::View::Static::Handler->client_accepts_gzipped_content ) {
+        Jifty->log->debug("Sending gzipped squished CSS");
+        Jifty->handler->apache->header_out( "Content-Encoding" => "gzip" );
+        Jifty->handler->apache->send_http_header();
+        binmode STDOUT;
+        print Compress::Zlib::memGzip( Jifty->web->cached_css );
+    } else {
+        Jifty->log->debug("Sending squished CSS");
+        Jifty->handler->apache->send_http_header();
+        print Jifty->web->cached_css;
+    }
+    abort;
+};
+1;

Added: jifty/branches/template-declare/lib/Jifty/Plugin/Halo.pm
==============================================================================
--- (empty file)
+++ jifty/branches/template-declare/lib/Jifty/Plugin/Halo.pm	Fri Feb 23 17:25:35 2007
@@ -0,0 +1,10 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::Halo;
+use base qw/Jifty::Plugin/;
+
+# Your plugin goes here.  If takes any configuration or arguments, you
+# probably want to override L<Jifty::Plugin/init>.
+
+1;

Added: jifty/branches/template-declare/lib/Jifty/Plugin/Halo/View.pm
==============================================================================
--- (empty file)
+++ jifty/branches/template-declare/lib/Jifty/Plugin/Halo/View.pm	Fri Feb 23 17:25:35 2007
@@ -0,0 +1,214 @@
+package Jifty::View::Declare::CoreTemplates;
+
+use strict;
+use warnings;
+use vars qw( $r );
+
+use Jifty::View::Declare -base;
+
+
+
+                                sub __jifty::halo {
+                                    my @stack = shift; die;
+                                    for my $id ( 0 .. $#stack ) {
+                                        my @kids;
+                                        my $looking = $id;
+                                        while ( ++$looking <= $#stack
+                                            and $stack[$looking]->{depth} >=
+                                            $stack[$id]->{depth} + 1 )
+                                        {
+                                            push @kids,
+                                              {
+                                                id   => $stack[$looking]{id},
+                                                path => $stack[$looking]{path},
+                                                render_time =>
+                                                  $stack[$looking]{render_time}
+                                              }
+                                              if $stack[$looking]->{depth} ==
+                                              $stack[$id]->{depth} + 1;
+                                        }
+                                        $stack[$id]{kids} = \@kids;
+
+                                        if ( $stack[$id]{depth} > 1 ) {
+                                            $looking = $id;
+                                            $looking--
+                                              while ( $stack[$looking]{depth} >=
+                                                $stack[$id]{depth} );
+                                            $stack[$id]{parent} = {
+                                                id   => $stack[$looking]{id},
+                                                path => $stack[$looking]{path},
+                                                render_time =>
+                                                  $stack[$looking]{render_time}
+                                            };
+                                        }
+                                    }
+
+                                    my $depth = 0;
+
+                                    div {
+                                        outs_raw( q{<a href="#" id="render_info" onclick="Element.toggle('render_info_tree'); return false">Page info</a>});
+                                    };
+                                      div {
+                                      attr {  style => "display: none",
+                                        id    => "render_info_tree"};
+                                        foreach my $item (@stack) {
+                                            if ( $item->{depth} > $depth ) {
+                                                ul { }
+                                            }
+                                                  elsif ( $item->{depth} < $depth ) {
+                                                    for ( $item->{depth} +
+                                                        1 .. $depth )
+                                                    {
+                                                    }
+                                                }
+                                      elsif ( $item->{depth} == $depth ) {
+                                    }
+                                }
+
+                                li {
+                                    my $id = $item->{id};
+                                    outs_raw(
+                                    a {
+                                        attr { href=>"#", class=>"halo_comp_info", onmouseover=>"halo_over(' $id ')", onmouseout=>"halo_out(' $id ')",  onclick=>"halo_toggle(' $id '); return false;"};
+
+outs( $item->{' name '} ."-". $item->{' render_time '} );
+}
+                                    unless ( $item->{subcomponent} ) {
+                                        Jifty->web->tangent(
+                                            url =>
+                                              "/__jifty/edit/mason_component/"
+                                              . $item->{'path'},
+                                            label => _('Edit')
+                                        );
+                                    }
+                                    $depth = $item->{'depth'};
+                                  }
+
+                                  for ( 1 .. $depth ) {
+                                }
+                              }
+                        }
+                    }
+
+                    foreach my $item (@stack){
+                        show('frame', frame => $item );
+                        } 
+                        
+                        my (@stack) = get(qw(stack));
+
+sub frame {
+                            class => "halo_actions" id => "halo-outs( $id ), div {-menu" style =
+"display: none; top: 5px; left: 500px; min-width: 200px; width: 300px; z-index: 5;"
+                              > <h1 id="halo-outs( $id ) -title ">
+  <span style=" float: right;
+                              "><a href=" #" onclick="halo_toggle('outs( $id )'); return false">[ X ]</a>}
+                              < %$frame->{name} % >
+                          } < div style =
+                          "position: absolute; bottom: 3px; right: 3px" > with(
+                            class => "resize" title = "Resize" id =>
+                              "halo-outs( $id %), span {-resize" >
+                          };
+                      }
+
+                      with( class => "body" ),
+                    div {
+                        with( class => "path" ),
+                          div { outs( $frame-> {path} ) } with( class => "time" ),
+                          div {
+                            Rendered in < %$frame->{'render_time'} % > s}
+}
+ if ($frame->{parent}
+                          ) {
+                            with( class => "section" ),
+                            div { Parent } with( class => "body" ),
+                            div {
+                                ul {
+                                    li {
+<a href="#" class="halo_comp_info" onmouseover="halo_over('outs( $frame->
+                                          {parent}{ id }
+                                        ) ')"
+                                       onmouseout="halo_out(' <
+                                          %$frame->{parent}{id} % > ')"
+                                       onclick="halo_toggle(' <
+                                          %$frame->{parent}{id} % >
+                                          '); return false;">
+outs( $frame->{parent}{' path '} ) - outs( $frame->{parent}{' render_time '} )</a>}
+}}
+}
+% if (@{$frame->{kids}}) {
+with ( class => "section"), div {Children}
+with ( class => "body"), div {ul { 
+% for my $item (@{$frame->{kids}}) {
+li {<a href="#" class="halo_comp_info" onmouseover="halo_over(' <
+                                          %$item->{id} % > ')"
+                                       onmouseout="halo_out(' < %$item->{id} % >
+                                          ')"
+                                       onclick="halo_toggle(' < %$item->{id} % >
+                                          '); return false;">
+outs( $item->{' path '} ) - outs( $item->{' render_time '} )</a>}
+}
+}
+}
+}
+% if (@args) {
+with ( class => "section"), div {Variables}
+with ( class => "body"), div {<ul class="fixed">
+% for my $e (@args) {
+li {<b>outs( $e->[0] )</b>:
+% if ($e->[1]) {
+% my $expanded = Jifty->web->serial;
+<a href="#" onclick="Element.toggle(' < %$expanded % >
+                                          '); return false">outs( $e->[1] )</a>
+with ( id => "outs( $expanded %), div {" style="display: none; position: absolute; left: 200px; border: 1px solid black; background: #ccc; padding: 1em; padding-top: 0; width: 300px; height: 500px; overflow: auto"><pre>outs( Jifty::YAML::Dump($e->[2]) )</pre>}
+} elsif (defined $e->[2]) {
+outs( $e->[2] )
+} else {
+<i>undef</i>
+}
+}
+}
+}}
+}
+% if (@stmts) {
+with ( class => "section"), div {outs(_(' SQL Statements '))}
+with ( class => "body" style="height: 300px; overflow: auto"), div {ul { 
+ for (@stmts) {
+li {
+with ( class => "fixed"), span {outs( $_->[1] )}<br />
+% if (@{$_->[2]}) {
+<b>Bindings:</b> <tt>outs( join(',
+', map {defined $_ ? ($_ =~ /[^[:space:][:graph:]]/ ? "*BLOB*" : $_ ) : "undef"} @{$_->[2]}) )</tt><br />
+}
+<i>outs( _(' % 1 seconds ', $_->[3]) )</i>
+}
+ }
+}}
+ }
+div {
+attr {class => "section"};
+ unless ($frame->{subcomponent}) {
+tangent( url =>"/__jifty/edit/mason_component/".$frame->{'path'}, label => _('Edit'));
+ } else {
+outs_raw(' &nbsp;');
+                                        ');
+ }
+}
+}
+my ( $frame) = get(qw(frame));
+my $id = $frame->{id};
+
+my @args;
+while (my ($key, $value) = splice(@{$frame->{args}},0,2)) {
+    push @args, [$key, ref($value), $value];
+}
+ at args = sort {$a->[0] cmp $b->[0]} @args;
+
+my $prev = '';
+my @stmts = @{$frame->{' sql_statements '}};
+</%def>
+}
+
+=cut
+
+
+1;

Added: jifty/branches/template-declare/lib/Jifty/Plugin/OnlineDocs.pm
==============================================================================
--- (empty file)
+++ jifty/branches/template-declare/lib/Jifty/Plugin/OnlineDocs.pm	Fri Feb 23 17:25:35 2007
@@ -0,0 +1,10 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::OnlineDocs;
+use base qw/Jifty::Plugin/;
+
+# Your plugin goes here.  If takes any configuration or arguments, you
+# probably want to override L<Jifty::Plugin/init>.
+
+1;

Added: jifty/branches/template-declare/lib/Jifty/Plugin/OnlineDocs/View.pm
==============================================================================
--- (empty file)
+++ jifty/branches/template-declare/lib/Jifty/Plugin/OnlineDocs/View.pm	Fri Feb 23 17:25:35 2007
@@ -0,0 +1,251 @@
+package Jifty::View::Declare::CoreTemplates;
+
+use strict;
+use warnings;
+use vars qw( $r );
+
+use Jifty::View::Declare -base;
+
+use Scalar::Defer;
+
+sub __jifty::online_docs::autohandler {
+
+# If "AdminMode" is turned off in Jifty's config file, don't let people at the admin UI.
+    unless ( Jifty->config->framework('AdminMode') ) {
+        $m->redirect('/__jifty/error/permission_denied');
+        $m->abort();
+    }
+
+    $m->call_next();
+}
+
+                                sub '__jifty::online_docs::content . html' {
+                                    <?xml version="1.0" encoding="UTF-8"?> <
+                                      !DOCTYPE html PUBLIC
+                                      "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"
+                                      > <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
+                                      < head > <title> <
+                                      %_ ( $n || 'Jifty' ) % >
+                                      -<%_('Jifty Pod Online')%> < /title>
+<style type="text/css"><!--
+a { text-decoration: none }
+a:hover { text-decoration: underline }
+a:focus { background: #99ff99; border: 1px black dotted }
+--></style>
+</head>
+body {
+<%PERL>
+my $jifty_dirname = Jifty::Util->jifty_root." / ";
+my $app_dirname = Jifty::Util->app_root." / lib /";
+$n =~ s/ :: /\//g;
+
+                                    my @options = (
+                                        $app_dirname . $n . ".pod",
+                                        $app_dirname . $n . ".pm",
+                                        $jifty_dirname . $n . ".pod",
+                                        $jifty_dirname . $n . ".pm"
+                                    );
+
+                                    my $total_body;
+                                    foreach my $file (@options) {
+                                        next unless -r "$file";
+                                        local $/;
+                                        my $fh;
+                                        open $fh, "$file" or next;
+                                        $total_body = <$fh>;
+                                        close $fh;
+                                    }
+                                    my $body;
+                                    my $schema;
+                                    my $converter = Pod::Simple::HTML->new();
+                                    if ( $n !~ /^Jifty\// ) {
+                                        if ( $total_body =~
+/package (.*?)::Schema;(.*)package/ismx
+                                          )
+                                        {
+                                            $schema = $2;
+                                        }
+                                    }
+
+                                    $converter->output_string( \$body );
+                                    $converter->parse_string_document(
+                                        $total_body);
+                                    $body =~ s{.*?<body [^>]+>}{}s;
+                                    $body =~ s{</body>\s*</html>\s*$}{};
+                                    $n    =~ s{/}{::}g;
+                                    $m->print("h1 {$n}");
+                                    $m->print( "h2 {"
+                                          . _('Schema')
+                                          . "}<pre>$schema</pre>" )
+                                      if ($schema);
+                                    $body =~
+s{<a href="http://search\.cpan\.org/perldoc\?(Jifty%3A%3A[^"]+)"([^>]*)>}{<a href="content.html?n=$1"$2>}g;
+                                    $body =~ s!}\n\tul { !ul { !;
+                                    $body =~ s!}!}}!;
+                                    $body =~ s!p { }!!;
+                                    $body =~ s!<a name=!<a id=!g;
+                                    $body =~ s!__index__!index!g;
+                                    $m->print($body);
+                                    </%PERL> < /body></ html >
+                                      <%ARGS> $Target => '&method=content' $n =>
+                                      'Jifty' < /%ARGS>
+require File::Basename;
+require File::Find;
+require File::Temp;
+require File::Spec;
+require Pod::Simple::HTML;
+}
+
+sub __jifty::online_docs::index.html { 
+<!DOCTYPE HTML PUBLIC "-/ / W3C // DTD HTML 4.01 Frameset // EN "
+" http: // www . w3 . org / TR / html4 /">
+<html lang="en">
+<head>
+<title><%_( $n || 'Jifty') %> - <%_('Online Documentation')%></ title >
+                                      <style type="text/css"> <
+                                      !--a     { text-decoration: none }
+                                      a: hover { text-decoration: underline }
+                                      a: focus {
+                                        background: #99ff99; border: 1px black dotted }
+                                        --> </style> < /head>
+<FRAMESET COLS="*, 250">
+    <FRAME src="./content . html " name=" podcontent ">
+    <FRAME src=" . /toc.html" name="podtoc">
+    <NOFRAMES>
+        <a style="display: none" href="#toc"><%_('Table of Contents')%></ a >
+                                          <& content.html, Target => '' & > h1 {
+                                            <a id="toc"> <
+                                              %_ ('Table of Contents') % > </a>;
+                                          }
+                                          <& toc.html, Target => '' & >
+                                          </NOFRAMES> < /FRAMESET>
+my (
+$n => undef
+) = get(qw());
+}
+
+sub __jifty::online_docs::toc.html { 
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-/ / W3C // DTD XHTML 1.1 // EN "
+" http: // www . w3 . org / TR / xhtml11 / DTD / xhtml11 . dtd ">
+<html xmlns=" http: // www . w3 . org / 1999 / xhtml " xml:lang=" en " >
+<head>
+<title><% _($n || 'Jifty') %> - <%_('Jifty Developer Documentation Online')%></title>
+<style type=" text / css "><!--
+a { text-decoration: none }
+a:hover { text-decoration: underline }
+a:focus { background: #99ff99; border: 1px black dotted }
+--></style>
+</head>
+<body style=" background:    #dddddd">
+                                          <%PERL> my @found;
+                                        File::Find::find(
+                                            {
+                                                untaint => 1,
+                                                wanted  => sub {
+                                                    return
+                                                      unless
+                                                      /(\w+)\.(?:pm|pod)$/;
+                                                    my $name =
+                                                      $File::Find::name;
+                                                    $name =~ s/.*lib\b.//;
+                                                    $name =~ s!\.(?:pm|pod)!!i;
+                                                    $name =~ s!\W!::!g;
+                                                    push @found, $name;
+                                                },
+                                                follow => ( $^O ne 'MSWin32' )
+                                            },
+                                            Jifty::Util->app_root . "/lib",
+                                        );
+
+                                        File::Find::find(
+                                            {
+                                                untaint => 1,
+                                                wanted  => sub {
+                                                    return
+                                                      unless $File::Find::name
+                                                      =~ /^(?:.*?)(Jifty.*?\.(?:pm|pod))$/;
+                                                    my $name = $1;
+                                                    $name =~ s/.*lib\b.//;
+                                                    $name =~ s!\.(?:pm|pod)!!i;
+                                                    $name =~ s!\/!::!g;
+                                                    push @found, $name;
+                                                },
+                                                follow => ( $^O ne 'MSWin32' )
+                                            },
+                                            Jifty::Util->jifty_root,
+                                        );
+
+                                        my $indent = 0;
+                                        my $prev   = '';
+                                        foreach my $file ( sort @found ) {
+                                            my ( $parent, $name ) = ( $1, $2 )
+                                              if $file =~ /(?:(.*)::)?(\w+)$/;
+                                            $parent = '' unless defined $parent;
+                                            if ( $file =~ /^$prev\::(.*)/ ) {
+                                                my $foo = $1;
+                                                while ( $foo =~ s/(\w+)::// ) {
+                                                    $indent++;
+                                                    $m->print(
+                                                        (
+                                                            '&nbsp;&nbsp;&nbsp;'
+                                                              x $indent
+                                                        )
+                                                    );
+                                                    $m->print("$1<br />");
+                                                }
+                                                $indent++;
+                                            }
+                                            elsif ( $prev !~ /^$parent\::/ ) {
+                                                $indent = 0
+                                                  unless length $parent;
+                                                while ( $parent =~ s/(\w+)// ) {
+                                                    next if $prev =~ s/\b$1:://;
+                                                    while ( $prev =~ s/::// ) {
+                                                        $indent--;
+                                                    }
+                                                    $m->print(
+                                                        (
+                                                            '&nbsp;&nbsp;&nbsp;'
+                                                              x $indent
+                                                        )
+                                                    );
+                                                    $m->print("$1<br />");
+                                                    $indent++;
+                                                }
+                                            }
+                                            elsif (
+                                                $prev =~ /^$parent\::(.*::)/ )
+                                            {
+                                                my $foo = $1;
+                                                while ( $foo =~ s/::// ) {
+                                                    $indent--;
+                                                }
+                                            }
+                                            $m->print(
+                                                (
+                                                    '&nbsp;&nbsp;&nbsp;' x
+                                                      $indent
+                                                )
+                                                . '<a target="podcontent" href="content.html?n='
+                                                  . $file . '">'
+                                                  . $name
+                                                  . '</a><br />' . "\n"
+                                            );
+                                            $prev = $file;
+                                        }
+
+                                        </%PERL> < /body></ html >
+                                          <%INIT> require File::Basename;
+                                        require File::Find;
+                                        require File::Temp;
+                                        require File::Spec;
+                                        require Pod::Simple::HTML;
+                                        </%INIT> < %ARGS >
+                                          $n => '' $method => '' $Target =>
+                                          '&method=content' < /%ARGS>
+}
+                  }
+
+1;

Added: jifty/branches/template-declare/lib/Jifty/Plugin/Yullio/View.pm
==============================================================================
--- (empty file)
+++ jifty/branches/template-declare/lib/Jifty/Plugin/Yullio/View.pm	Fri Feb 23 17:25:35 2007
@@ -0,0 +1,65 @@
+package Jifty::View::Declare::Yullio;
+use strict;
+use warnings;
+
+# XXX: To be converted to a plugin with included css and images.
+
+use Jifty::View::Declare -base;
+
+use base 'Exporter';
+our @EXPORT = qw(yullio);
+
+=head1 NAME
+
+Jifty::View::Declare::Yullio - Yullio layout bundles
+
+=head1 SYNOPSIS
+
+  use Jifty::View::Declare::Yullio
+  template 'index2.html' => page {
+    with ( width => 'doc2', column_template => 'yui-t6' ),
+    yullio
+     { outs('This is main content') }
+     sub { outs('This is something on the side') } };
+
+=head1 DESCRIPTION
+
+C<Jifty::View::Declare::Yullio> provides an alternative C<page>
+temlpate constructor that makes use of yui grid layouts.
+
+=cut
+
+sub _yullio_content {
+    my ($code1, $code2) = @_;
+    # XXX: fix get_current_attr with multiple arguments
+    my ($width, $column_template) = map {get_current_attr($_)}
+	qw(width column_template);
+    sub {
+	# XXX: T::D is propagating our with to deeper callstacks as we
+	# are not calling from "_tag"
+	with (),
+
+
+	div {
+	    { id is $width, class is $column_template }
+
+	    div { { id is 'hd' }
+		  div { { id is 'yui-main' }
+		        div { { class is 'yui-b' }
+                              div { { id is 'content' }
+                                    $code1->() } } };
+                  if ($column_template ne 'yui-t7') {
+		      div { { id is 'yui-b' }
+                            div { { id is 'utility' }
+                                  $code2->() } }
+		  } } }
+    };
+}
+
+sub yullio(&&) {
+    my ($code1, $code2) = @_;
+    _yullio_content($code1, $code2)->();
+}
+
+1;
+

Modified: jifty/branches/template-declare/share/plugins/Jifty/Plugin/OnlineDocs/web/templates/__jifty/online_docs/index.html
==============================================================================
--- /jifty/branches/template-declare/share/plugins/Jifty/OnlineDocs/web/templates/__jifty/online_docs/index.html	(original)
+++ jifty/branches/template-declare/share/plugins/Jifty/Plugin/OnlineDocs/web/templates/__jifty/online_docs/index.html	Fri Feb 23 17:25:35 2007
@@ -10,8 +10,8 @@
 --></style>
 </head>
 <FRAMESET COLS="*, 250">
-    <FRAME src="./content.html" name="podcontent">
-    <FRAME src="./toc.html" name="podtoc">
+    <FRAME src="content.html" name="podcontent">
+    <FRAME src="toc.html" name="podtoc">
     <NOFRAMES>
         <a style="display: none" href="#toc"><%_('Table of Contents')%></a>
 <& content.html, Target => '' &>


More information about the Jifty-commit mailing list