[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(' ');
+ ');
+ }
+}
+}
+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(
+ (
+ ' '
+ 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(
+ (
+ ' '
+ x $indent
+ )
+ );
+ $m->print("$1<br />");
+ $indent++;
+ }
+ }
+ elsif (
+ $prev =~ /^$parent\::(.*::)/ )
+ {
+ my $foo = $1;
+ while ( $foo =~ s/::// ) {
+ $indent--;
+ }
+ }
+ $m->print(
+ (
+ ' ' 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