[Jifty-commit] r2905 - in jifty/branches/template-declare: .
lib/Jifty lib/Jifty/Plugin lib/Jifty/Plugin/Authentication
lib/Jifty/Plugin/ErrorTemplates lib/Jifty/Plugin/SkeletonApp
jifty-commit at lists.jifty.org
jifty-commit at lists.jifty.org
Sun Mar 4 16:24:17 EST 2007
Author: jesse
Date: Sun Mar 4 16:24:16 2007
New Revision: 2905
Added:
jifty/branches/template-declare/lib/Jifty/Plugin/ErrorTemplates.pm
Removed:
jifty/branches/template-declare/lib/Jifty/View/Declare/WebServices.pm
Modified:
jifty/branches/template-declare/ (props changed)
jifty/branches/template-declare/lib/Jifty/Config.pm
jifty/branches/template-declare/lib/Jifty/Plugin/Authentication/Password.pm
jifty/branches/template-declare/lib/Jifty/Plugin/ErrorTemplates/View.pm
jifty/branches/template-declare/lib/Jifty/Plugin/SkeletonApp/View.pm
jifty/branches/template-declare/lib/Jifty/View/Declare/CoreTemplates.pm
jifty/branches/template-declare/lib/Jifty/View/Declare/Handler.pm
jifty/branches/template-declare/lib/Jifty/View/Declare/Helpers.pm
Log:
r52975 at pinglin: jesse | 2007-03-04 22:22:24 +0100
* T::D branch passes all tests
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 Sun Mar 4 16:24:16 2007
@@ -268,7 +268,6 @@
},
{ Halo => {},},
{ErrorTemplates => {},},
- {SkeletonApp => {},},
{OnlineDocs => {},},
{ CompressedCSSandJS => {},},
{AdminUI => {},}
Modified: jifty/branches/template-declare/lib/Jifty/Plugin/Authentication/Password.pm
==============================================================================
--- jifty/branches/template-declare/lib/Jifty/Plugin/Authentication/Password.pm (original)
+++ jifty/branches/template-declare/lib/Jifty/Plugin/Authentication/Password.pm Sun Mar 4 16:24:16 2007
@@ -7,4 +7,18 @@
# Your plugin goes here. If takes any configuration or arguments, you
# probably want to override L<Jifty::Plugin/init>.
+=head1 NAME
+
+Jifty::Plugin::Authentication::Password
+
+=head1 DESCRIPTION
+
+When finished, this plugin will provide password authentication for
+your Jifty application. (It adds a "password" column to your "User" model class).
+
+Right now, it's useless and should be ignored.
+
+
+=cut
+
1;
Added: jifty/branches/template-declare/lib/Jifty/Plugin/ErrorTemplates.pm
==============================================================================
--- (empty file)
+++ jifty/branches/template-declare/lib/Jifty/Plugin/ErrorTemplates.pm Sun Mar 4 16:24:16 2007
@@ -0,0 +1,20 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::ErrorTemplates;
+use base qw/Jifty::Plugin/;
+
+# Your plugin goes here. If takes any configuration or arguments, you
+# probably want to override L<Jifty::Plugin/init>.
+
+=head1 NAME
+
+Jifty::Plugin::ErrorTemplates
+
+=head1 DESCRIPTION
+
+This plugin provides superusers with online documentation for Jifty and your application's API. It's included by default when using Jifty. (That's a bug).
+
+=cut
+
+1;
Modified: jifty/branches/template-declare/lib/Jifty/Plugin/ErrorTemplates/View.pm
==============================================================================
--- jifty/branches/template-declare/lib/Jifty/Plugin/ErrorTemplates/View.pm (original)
+++ jifty/branches/template-declare/lib/Jifty/Plugin/ErrorTemplates/View.pm Sun Mar 4 16:24:16 2007
@@ -52,34 +52,57 @@
in case the error in question is caused by the Jifty app's wrapper, for instance.
=cut
-sub wrapper (&) {
- my $code = shift;
- html {
- head {
- title { _('Internal error') }
- link { attr { rel => 'stylesheet', type => 'text/css', href => "/__jifty/error/error.css", media => 'all'}};
- }
- body {
- div { attr { id => 'headers'};
- h1 { 'Internal Error' };
- div { attr { id => 'content'};
- a { attr { name => 'content'}};
- if (Jifty->config->framework('AdminMode') ) {
- div { attr { class => "warning admin_mode" };
- outs('Alert:' . tangent( label => 'administration mode' , url => '/__jifty/admin/') .'is enabled.' ) }
- }
- Jifty->web->render_messages;
- $code->();
- }
-
- }
- }}
- }
+{
+ no warnings qw'redefine';
+
+ sub wrapper ($) {
+ my $code = shift;
+ html {
+ head {
+ title { _('Internal error') } link {
+ attr {
+ rel => 'stylesheet',
+ type => 'text/css',
+ href => "/__jifty/error/error.css",
+ media => 'all'
+ }
+ };
+ }
+ body {
+ div {
+ attr { id => 'headers' };
+ h1 {'Internal Error'};
+ div {
+ attr { id => 'content' };
+ a { attr { name => 'content' } };
+ if ( Jifty->config->framework('AdminMode') ) {
+ div {
+ attr { class => "warning admin_mode" };
+ outs(
+ 'Alert:'
+ . tangent(
+ label => 'administration mode',
+ url => '/__jifty/admin/'
+ )
+ . 'is enabled.'
+ );
+ }
+ }
+ Jifty->web->render_messages;
+ $code->();
+ }
+
+ }
+ }
+ }
+ }
+}
+
template '__jifty/error/dhandler' => sub {
my $error = get('error');
Jifty->log->error( "Unhandled web error " . $error );
- wrapper {
+ page {
title is 'Something went awry';
show('_elements/error_text', error => $error );
};
@@ -98,7 +121,7 @@
my $file = get('path');
Jifty->log->error( "404: user tried to get to " . $file );
Jifty->handler->apache->header_out( Status => '404' );
- with( title => _("Something's not quite right") ), wrapper => {
+ with( title => _("Something's not quite right") ), page {
with( id => "overview" ),
div {
Modified: jifty/branches/template-declare/lib/Jifty/Plugin/SkeletonApp/View.pm
==============================================================================
--- jifty/branches/template-declare/lib/Jifty/Plugin/SkeletonApp/View.pm (original)
+++ jifty/branches/template-declare/lib/Jifty/Plugin/SkeletonApp/View.pm Sun Mar 4 16:24:16 2007
@@ -8,6 +8,18 @@
use Scalar::Defer;
+=head1 NAME
+
+Jifty::Plugin::SkeletonApp::View
+
+=head1 DESCRIPTION
+
+This somewhat-finished (But not quite) template library implements
+Jifty's "pony" Application. It could certainly use some refactoring. (And some of the menu stuff should get factored out into a dispatcher or the other plugins that implement it.
+
+
+=cut
+
template '_elements/nav' => sub {
my $top = Jifty->web->navigation;
$top->child( Home => url => "/", sort_order => 1, label => _('Home') );
Modified: jifty/branches/template-declare/lib/Jifty/View/Declare/CoreTemplates.pm
==============================================================================
--- jifty/branches/template-declare/lib/Jifty/View/Declare/CoreTemplates.pm (original)
+++ jifty/branches/template-declare/lib/Jifty/View/Declare/CoreTemplates.pm Sun Mar 4 16:24:16 2007
@@ -2,8 +2,345 @@
use strict;
use warnings;
-use vars qw( $r );
use Jifty::View::Declare -base;
+use Scalar::Defer;
+
+=head1 NAME
+
+Jifty::View::Declare::CoreTemplates
+
+=head1 DESCRIPTION
+
+This library contains templates that Jifty can't function without:
+
+=over
+
+=item PubSub
+
+=item Validate
+
+=item Autocomplete
+
+=item Canonicalize
+
+=item YAML and XML webservice endpoints for core jifty functionality
+
+=cut
+
+template '__jifty/subs' => sub {
+ my ($forever) = get(qw(forever)) || 1;
+
+ Jifty->handler->apache->content_type("text/html; charset=utf-8");
+ Jifty->handler->apache->headers_out->{'Pragma'} = 'no-cache';
+ Jifty->handler->apache->headers_out->{'Cache-control'} = 'no-cache';
+ Jifty->handler->apache->send_http_header;
+
+ my $writer = XML::Writer->new;
+ $writer->xmlDecl( "UTF-8", "yes" );
+
+ my $begin = <<'END';
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/2002/REC-xhtml1-20020801/DTD/xhtml1-strict.dtd">
+<html><head><title></title></head>
+END
+ chomp $begin;
+
+ if ($forever) {
+ my $whitespace = " " x ( 1024 - length $begin );
+ $begin =~ s/<body>$/$whitespace/s;
+ }
+
+ Jifty->web->out($begin);
+ $writer->startTag("body");
+
+ while (1) {
+ my $sent = _write_subs_once($writer);
+ flush STDOUT;
+ last if ( $sent && !$forever );
+ sleep 1;
+ }
+ $writer->endTag();
+ return;
+
+};
+
+sub _write_subs_once {
+ my $writer = shift;
+ Jifty::Subs::Render->render(
+ Jifty->web->session->id,
+ sub {
+ my ( $mode, $name, $content ) = @_;
+ $writer->startTag( "pushfrag", mode => $mode );
+ $writer->startTag( "fragment", id => $name );
+ $writer->dataElement( "content", $content );
+ $writer->endTag();
+ $writer->endTag();
+ }
+ );
+}
+
+template '__jifty/autocomplete.xml' => sub {
+
+ # Note: the only point to this file is to set the content_type; the actual
+ # behavior is accomplished inside the framework. It will go away once we
+ # have infrastructure for serving things of various content-types.
+ Jifty->handler->apache->content_type('text/xml; charset=UTF-8');
+ my $ref = Jifty->web->response->result('autocomplete')->content;
+ my @options = @{ $ref->{'completions'} || [] };
+ body {
+ ul {
+ foreach my $item (@options) {
+ if ( !ref($item) ) {
+ li { $item };
+ }
+ elsif ( exists $item->{label} ) {
+ li {
+ with( class => "informal" ), span { $item->{label} };
+ with( class => "hidden_value" ),
+ span { $item->{value} };
+ };
+ }
+ else {
+ li { $item->{value} };
+ }
+ }
+ };
+ };
+};
+
+
+template '__jifty/validator.xml' => sub {
+ Jifty->handler->apache->content_type('text/xml; charset=UTF-8');
+ my $output = "";
+ use XML::Writer;
+ my $writer = XML::Writer->new( OUTPUT => \$output );
+ $writer->xmlDecl( "UTF-8", "yes" );
+ $writer->startTag("validation");
+ for my $ra ( Jifty->web->request->actions ) {
+ my $action = Jifty->web->new_action_from_request($ra);
+ $writer->startTag( "validationaction", id => $action->register_name );
+ for my $arg ( $action->argument_names ) {
+ if ( not $action->arguments->{$arg}->{ajax_validates} ) {
+ $writer->emptyTag( "ignored",
+ id => $action->error_div_id($arg) );
+ $writer->emptyTag( "ignored",
+ id => $action->warning_div_id($arg) );
+ }
+ elsif ( not defined $action->argument_value($arg)
+ or length $action->argument_value($arg) == 0 )
+ {
+ $writer->emptyTag( "blank", id => $action->error_div_id($arg) );
+ $writer->emptyTag( "blank",
+ id => $action->warning_div_id($arg) );
+ }
+ elsif ( $action->result->field_error($arg) ) {
+ $writer->dataElement(
+ "error",
+ $action->result->field_error($arg),
+ id => $action->error_div_id($arg)
+ );
+ $writer->emptyTag( "ok", id => $action->warning_div_id($arg) );
+ }
+ elsif ( $action->result->field_warning($arg) ) {
+ $writer->dataElement(
+ "warning",
+ $action->result->field_warning($arg),
+ id => $action->warning_div_id($arg)
+ );
+ $writer->emptyTag( "ok", id => $action->error_div_id($arg) );
+ }
+ else {
+ $writer->emptyTag( "ok", id => $action->error_div_id($arg) );
+ $writer->emptyTag( "ok", id => $action->warning_div_id($arg) );
+ }
+ }
+ $writer->endTag();
+ $writer->startTag( "canonicalizeaction", id => $action->register_name );
+ for my $arg ( $action->argument_names ) {
+ no warnings 'uninitialized';
+ if ( $ra->arguments->{$arg} eq $action->argument_value($arg) ) {
+
+ # if the value doesn' t change, it can be ignored .
+
+# canonicalizers can change other parts of the action, so we want to send all changes
+ $writer->emptyTag( "ignored",
+ name => $action->form_field_name($arg) );
+ }
+ elsif ( not defined $action->argument_value($arg)
+ or length $action->argument_value($arg) == 0 )
+ {
+ $writer->emptyTag( "blank",
+ name => $action->form_field_name($arg) );
+ }
+ else {
+ if ( $action->result->field_canonicalization_note($arg) ) {
+ $writer->dataElement(
+ "canonicalization_note",
+ $action->result->field_canonicalization_note($arg),
+ id => $action->canonicalization_note_div_id($arg)
+ );
+ }
+ $writer->dataElement(
+ "update",
+ $action->argument_value($arg),
+ name => $action->form_field_name($arg)
+ );
+ }
+ }
+ $writer->endTag();
+ }
+ $writer->endTag();
+ Jifty->web->out($output);
+};
+
+template '__jifty/webservices/xml' => sub {
+ my $output = "";
+ my $writer = XML::Writer->new(
+ OUTPUT => \$output,
+ UNSAFE => 1
+ );
+ $writer->xmlDecl( "UTF-8", "yes" );
+ $writer->startTag("response");
+ for my $f ( Jifty->web->request->fragments ) {
+
+ # Set up the region stack
+ local Jifty->web->{'region_stack'} = [];
+ my @regions;
+ do {
+ push @regions, $f;
+ } while ( $f = $f->parent );
+
+ for $f ( reverse @regions ) {
+ my $new =
+ Jifty->web->get_region( join '-',
+ grep { $_ } Jifty->web->qualified_region, $f->name );
+
+ # Arguments can be complex mapped hash values. Get their
+ # real values by mapping.
+ my %defaults = %{ $f->arguments || {} };
+ for ( keys %defaults ) {
+ my ( $key, $value ) = Jifty::Request::Mapper->map(
+ destination => $_,
+ source => $defaults{$_}
+ );
+ delete $defaults{$_};
+ $defaults{$key} = $value;
+ }
+
+ $new ||= Jifty::Web::PageRegion->new(
+ name => $f->name,
+ path => $f->path,
+ region_wrapper => $f->wrapper,
+ parent => Jifty->web->current_region,
+ defaults => \%defaults,
+ );
+ $new->enter;
+ }
+
+ # Stuff the rendered region into the XML
+ $writer->startTag( "fragment",
+ id => Jifty->web->current_region->qualified_name );
+ my %args = %{ Jifty->web->current_region->arguments };
+ $writer->dataElement( "argument", $args{$_}, name => $_ )
+ for sort keys %args;
+ $writer->cdataElement( "content",
+ Jifty->web->current_region->as_string );
+ $writer->endTag();
+
+ Jifty->web->current_region->exit while Jifty->web->current_region;
+ }
+
+ my %results = Jifty->web->response->results;
+ for ( keys %results ) {
+ $writer->startTag(
+ "result",
+ moniker => $_,
+ class => $results{$_}->action_class
+ );
+ $writer->dataElement( "success", $results{$_}->success );
+
+ $writer->dataElement( "message", $results{$_}->message )
+ if $results{$_}->message;
+ $writer->dataElement( "error", $results{$_}->error )
+ if $results{$_}->error;
+
+ my %warnings = $results{$_}->field_warnings;
+ my %errors = $results{$_}->field_errors;
+ my %fields;
+ $fields{$_}++ for keys(%warnings), keys(%errors);
+ for ( sort keys %fields ) {
+ next unless $warnings{$_} or $errors{$_};
+ $writer->startTag( "field", name => $_ );
+ $writer->dataElement( "warning", $warnings{$_} )
+ if $warnings{$_};
+ $writer->dataElement( "error", $errors{$_} )
+ if $errors{$_};
+ $writer->endTag();
+ }
+
+ # XXX TODO: Hack because we don't have a good way to serialize
+ # Jifty::DBI::Record's yet, which are technically circular data
+ # structures at some level (current_user of a
+ # current_user->user_object is itself)
+ use Scalar::Util qw(blessed);
+ my $content = $results{$_}->content;
+
+
+ $content = _stripkids($content);
+ use XML::Simple;
+ $writer->raw(
+ XML::Simple::XMLout(
+ $content,
+ NoAttr => 1,
+ RootName => "content",
+ NoIndent => 1
+ )
+ ) if keys %{$content};
+
+ $writer->endTag();
+ }
+
+ $writer->endTag();
+ Jifty->handler->apache->content_type('text/xml; charset=UTF-8');
+
+ # For some reason, this line is needed, lest we end up outputting ISO-8859-1 text
+ utf8::decode($output);
+
+ outs_raw($output);
+};
+
+ sub _stripkids {
+ my $top = shift;
+ if ( not ref $top ) { return $top }
+ elsif (
+ blessed($top)
+ and ( $top->isa("Jifty::DBI::Record")
+ or $top->isa("Jifty::DBI::Collection") )
+ )
+ {
+ return undef;
+ }
+ elsif ( ref $top eq 'HASH' ) {
+ foreach my $item ( keys %$top ) {
+ $top->{$item} = _stripkids( $top->{$item} );
+ }
+ }
+ elsif ( ref $top eq 'ARRAY' ) {
+ for ( 0 .. $#{$top} ) {
+ $top->[$_] = _stripkids( $top->[$_] );
+ }
+ }
+ return $top;
+ }
+
+
+template '__jifty/webservices/yaml' => sub {
+ Jifty->handler->apache->content_type("text/x-yaml");
+ outs( Jifty::YAML::Dump( { Jifty->web->response->results } ) );
+};
+
+
+1;
1;
Modified: jifty/branches/template-declare/lib/Jifty/View/Declare/Handler.pm
==============================================================================
--- jifty/branches/template-declare/lib/Jifty/View/Declare/Handler.pm (original)
+++ jifty/branches/template-declare/lib/Jifty/View/Declare/Handler.pm Sun Mar 4 16:24:16 2007
@@ -28,7 +28,6 @@
my $class = shift;
my $self = {};
bless $self,$class;
- warn "Initting T::D with ". YAML::Dump(\@_);
Template::Declare->init(@_);
return $self;
}
@@ -65,7 +64,6 @@
=cut
sub template_exists { my $pkg =shift;
-warn "Checking for ".join(',', at _);
return Template::Declare->resolve_template(@_);}
Modified: jifty/branches/template-declare/lib/Jifty/View/Declare/Helpers.pm
==============================================================================
--- jifty/branches/template-declare/lib/Jifty/View/Declare/Helpers.pm (original)
+++ jifty/branches/template-declare/lib/Jifty/View/Declare/Helpers.pm Sun Mar 4 16:24:16 2007
@@ -92,6 +92,16 @@
return Jifty->web->new_action(@_);
}
+
+=head2 render_region
+
+A shortcut for Jifty::Web::PageRegion->new(@_)->render which does the
+Template::Declare magic necessary to not mix its output with your current
+page's.
+
+
+=cut
+
sub render_region(@) {
unshift @_, 'name' if @_ % 2;
Template::Declare->new_buffer_frame;
@@ -101,6 +111,35 @@
Jifty->web->out($content);
}
+
+=head2 render_action $action_object, $fields, $args_to_pass_to_action
+
+Renders an action out of whole cloth.
+
+Arguments
+
+=over
+
+=item $action_object
+
+A Jifty::Action object which has already been initialized
+
+=item $fields
+
+A reference to an array of fields that should be rendered when
+displaying this action. If left undefined, all of the
+action's fields will be rendered.
+
+=item $args_to_pass_to_action
+
+A hashref of arguments that should be passed to $action->form_field for
+every field of this action.
+
+=back
+
+
+=cut
+
sub render_action(@) {
my ( $action, $fields, $field_args ) = @_;
my @f = $fields && @$fields ? @$fields : $action->argument_names;
@@ -152,6 +191,16 @@
Jifty->web->current_user;
}
+=head2 get args
+
+Returns arguments as set in the dispatcher or with L</set> below.
+If called in scalar context, pulls the first item in C<args> and returns it.
+If called in list context, returns the values of all items in C<args>.
+
+
+
+=cut
+
sub get {
if (wantarray) {
map { request->argument($_) } @_;
@@ -160,6 +209,15 @@
}
}
+
+=head2 set key => val [ key => val ...]
+
+Sets arguments for later grabbing with L<get>.
+
+
+=cut
+
+
sub set {
while ( my ( $arg, $val ) = ( shift @_, shift @_ ) ) {
request->argument( $arg => $val );
@@ -167,13 +225,29 @@
}
+=head2 render_param $action @args
+
+Takes an action and one or more arguments to pass to L<Jifty::Action->form_field>.
+
+=cut
+
sub render_param {
my $action = shift;
outs_raw( $action->form_field(@_) );
return '';
}
-# template 'foo' => page {{ title is 'Foo' } ... };
+=head2 page
+
+ template 'foo' => page {{ title is 'Foo' } ... };
+
+Renders an HTML page wrapped in L</wrapper>, after calling
+"/_elements/nav" and setting a content type. Generally, you shouldn't
+be using "/_elements/nav" but a Dispatcher rule instead.
+
+=cut
+
+
sub page (&) {
my $code = shift;
sub {
@@ -183,6 +257,15 @@
};
}
+
+=head2 wrapper $coderef
+
+Render a page. $coderef is a L<Template::Declare> coderef.
+This badly wants to be redone.
+
+=cut
+
+
sub wrapper ($) {
my $content_code = shift;
@@ -257,6 +340,13 @@
$done_header . Template::Declare->buffer->data );
}
+
+=head2 render_header $title
+
+Renders an HTML "doctype", <head> and the first part of a page body. This bit isn't terribly well thought out and we're not happy with it.
+
+=cut
+
sub render_header {
my ($title) = @_;
outs_raw(
More information about the Jifty-commit
mailing list