[Bps-public-commit] r17034 - in Prophet/branches/actions: . doc lib/Prophet lib/Prophet/Server lib/Prophet/Web t/WebToy t/WebToy/bin t/WebToy/lib t/WebToy/lib/App t/WebToy/lib/App/WebToy/Collection t/WebToy/lib/App/WebToy/Model t/WebToy/lib/App/WebToy/Server
jesse at bestpractical.com
jesse at bestpractical.com
Thu Nov 27 13:55:50 EST 2008
Author: jesse
Date: Thu Nov 27 13:55:50 2008
New Revision: 17034
Added:
Prophet/branches/actions/doc/web_form_handling
Prophet/branches/actions/lib/Prophet/Server/Controller.pm
Prophet/branches/actions/lib/Prophet/Web/
Prophet/branches/actions/lib/Prophet/Web/Field.pm
Prophet/branches/actions/t/WebToy/
Prophet/branches/actions/t/WebToy/bin/
Prophet/branches/actions/t/WebToy/bin/webtoy (contents, props changed)
Prophet/branches/actions/t/WebToy/lib/
Prophet/branches/actions/t/WebToy/lib/App/
Prophet/branches/actions/t/WebToy/lib/App/WebToy/
Prophet/branches/actions/t/WebToy/lib/App/WebToy.pm
Prophet/branches/actions/t/WebToy/lib/App/WebToy/CLI.pm
Prophet/branches/actions/t/WebToy/lib/App/WebToy/Collection/
Prophet/branches/actions/t/WebToy/lib/App/WebToy/Collection/WikiPage.pm
Prophet/branches/actions/t/WebToy/lib/App/WebToy/Model/
Prophet/branches/actions/t/WebToy/lib/App/WebToy/Model/WikiPage.pm
Prophet/branches/actions/t/WebToy/lib/App/WebToy/Server/
Prophet/branches/actions/t/WebToy/lib/App/WebToy/Server/Dispatcher.pm
Prophet/branches/actions/t/WebToy/lib/App/WebToy/Server/View.pm
Modified:
Prophet/branches/actions/Makefile.PL
Prophet/branches/actions/lib/Prophet/Collection.pm
Prophet/branches/actions/lib/Prophet/Server.pm
Prophet/branches/actions/lib/Prophet/Server/ViewHelpers.pm
Log:
* iniital work on actions
Modified: Prophet/branches/actions/Makefile.PL
==============================================================================
--- Prophet/branches/actions/Makefile.PL (original)
+++ Prophet/branches/actions/Makefile.PL Thu Nov 27 13:55:50 2008
@@ -1,7 +1,7 @@
#!/usr/bin/perl
#
use inc::Module::Install;
-name('Prophet'); # App::Settings App::Settings::CLI
+name('Prophet'); # App::Settings App::Settings::CLI App::WebToy App::WebToy::CLI
author('clkao and jesse');
license('Perl');
Added: Prophet/branches/actions/doc/web_form_handling
==============================================================================
--- (empty file)
+++ Prophet/branches/actions/doc/web_form_handling Thu Nov 27 13:55:50 2008
@@ -0,0 +1,14 @@
+# in the dispatcher:
+
+ # get all form fields that match the spec
+ # bundle them by record
+ # order them by the desired order
+ # canonicalize
+ # validate
+ # execute if we're to execute
+ # on failure
+ # rerender the current page
+ # on success
+ # go to "next page"
+
+
Modified: Prophet/branches/actions/lib/Prophet/Collection.pm
==============================================================================
--- Prophet/branches/actions/lib/Prophet/Collection.pm (original)
+++ Prophet/branches/actions/lib/Prophet/Collection.pm Thu Nov 27 13:55:50 2008
@@ -25,9 +25,10 @@
has type => (
is => 'rw',
isa => 'Str',
+ lazy => 1,
default => sub {
my $self = shift;
- $self->record_class->record_type;
+ $self->record_class->new(app_handle => $self->app_handle)->record_type;
},
);
@@ -70,14 +71,13 @@
sub matching {
my $self = shift;
my $coderef = shift;
-
return undef unless $self->handle->type_exists( type => $self->type );
-
# find all items,
Carp::cluck unless defined $self->type;
my $records = $self->handle->list_records( type => $self->type );
+
# run coderef against each item;
# if it matches, add it to items
for my $key (@$records) {
@@ -93,6 +93,16 @@
}
+=head2 items
+
+Returns a reference to an array of all the items found
+
+=head2 add_item
+
+=head2 count
+
+=cut
+
__PACKAGE__->meta->make_immutable;
no Moose;
Modified: Prophet/branches/actions/lib/Prophet/Server.pm
==============================================================================
--- Prophet/branches/actions/lib/Prophet/Server.pm (original)
+++ Prophet/branches/actions/lib/Prophet/Server.pm Thu Nov 27 13:55:50 2008
@@ -52,6 +52,10 @@
my ( $self, $cgi ) = validate_pos( @_, { isa => 'Prophet::Server' }, { isa => 'CGI' } );
$self->cgi($cgi);
+
+ my $controller = Prophet::Server::Controller->new(cgi => $self->cgi);
+ $controller->handle_actions();
+
my $dispatcher_class = ref($self->app_handle) . "::Server::Dispatcher";
if (!$self->app_handle->try_to_require($dispatcher_class)) {
$dispatcher_class = "Prophet::Server::Dispatcher";
Added: Prophet/branches/actions/lib/Prophet/Server/Controller.pm
==============================================================================
--- (empty file)
+++ Prophet/branches/actions/lib/Prophet/Server/Controller.pm Thu Nov 27 13:55:50 2008
@@ -0,0 +1,138 @@
+package Prophet::Server::Controller;
+use Moose;
+
+
+has cgi => (isa => 'CGI');
+
+has failed => ( isa => 'Bool');
+has failure_message => ( isa => 'Bool');
+
+=head1 NAME
+
+=head1 METHODS
+
+=head1 DESCRIPTION
+
+=cut
+
+=head1 METHODS
+
+=cut
+
+sub extract_actions_from_cgi {
+ my $self = shift;
+
+ my $cgi = $self->cgi;
+ my @params = $cgi->all_parameters;
+
+ my $bundles = $self->_bundle_params_by_action(\@params);
+ for (values %$bundles) {
+ push @action_hashes, $self->_bundle_to_hash($_);
+ }
+ return \@action_hashes;
+}
+
+
+sub _bundle_params_by_action {
+ my $self = shift;
+ my $params = shift;
+
+ my $bundles = {};
+ my @actions = $self->_find_actions_from_cgi_params($params);
+ foreach my $param (@$params) {
+ my $action = $self->_parse_cgi_param_name($param);
+
+ $bundles{$action}
+ }
+
+
+ return $bundles;
+}
+
+sub find_actions_from_cgi {
+ my $self = shift;
+ my $params = shift;
+
+ my $cgi = $self->cgi;
+ my $actions = {};
+ foreach my $param (@$params) {
+ next unless $param =~ /^prophet-action(.*)$/;
+ my %attr = map {split(/=/) grep {$_} split(/|/,$1)};
+ $attr{value} = $cgi->param($param);
+
+ warn "Duplicate action definition for @{[$attr{name}]}." if ($actions{$attr{name}};
+ $actions{$attr{name}} = \%attr;
+ $actions{$attr{name}}->{params} =
+ $self->params_for_action_from_cgi($attr{name});
+ }
+
+}
+
+sub params_for_action_from_cgi {
+ my $self = shift;
+ my $action = shift;
+
+ my @params = grep { /^prophet-field|.*?|action=$action|/}
+ $self->cgi->all_parameters
+}
+
+
+sub _parse_cgi_param_name {
+ my $self = shift;
+ my $param = shift;
+
+ my ($uuid, $prop, $value);
+ if ($param =~ /|uuid-(.*?)|) {
+ $uuid = $1;
+ }
+ if ($param =~ /|prop-(.*?)|) {
+ $prop = $1;
+ }
+ my $value = $self->cgi->param($param);
+
+}
+
+sub _bundle_to_hash {
+ my $self = shift;
+}
+
+sub handle_actions {
+ my $self = shift;
+
+ my @workflow = qw(
+ extract_actions_from_cgi
+ canonicalize_actions
+ validate_actions
+ execute_actions
+ );
+ eval {
+ $self->$_() for @workflow;
+ };
+
+ if (my $err = $@) {
+ $self->failed(1);
+ $self->failure_message($err);
+ }
+}
+
+
+sub extract_actions_from_cgi {
+ my $self = shift;
+}
+
+sub canonicalize_actions {
+ my $self = shift;
+}
+
+sub validate_actions {
+
+}
+
+sub execute_actions {
+
+}
+__PACKAGE__->meta->make_immutable;
+no Moose;
+
+1;
+
Modified: Prophet/branches/actions/lib/Prophet/Server/ViewHelpers.pm
==============================================================================
--- Prophet/branches/actions/lib/Prophet/Server/ViewHelpers.pm (original)
+++ Prophet/branches/actions/lib/Prophet/Server/ViewHelpers.pm Thu Nov 27 13:55:50 2008
@@ -4,8 +4,10 @@
package Prophet::Server::ViewHelpers;
use base 'Exporter::Lite';
+use Params::Validate qw/validate/;
use Template::Declare::Tags;
-our @EXPORT = qw(page content);
+use Prophet::Web::Field;
+our @EXPORT = qw(page content widget function);
sub page (&;$) {
unshift @_, undef if $#_ == 0;
@@ -35,5 +37,58 @@
return $sub_ref;
}
+sub function {
+ my %args = validate(
+ @_,
+ { action => { regex => qr/^(?:create|update|delete)$/ },
+ record => 1,
+ order => 0,
+ name => {
+ regex => qr/^(?:|[\w\d]+)$/,
+ optional => 1
+ },
+ }
+ );
+
+ my %bits = {
+ order => $args{order},
+ name => $args{'name'},
+ uuid => $args{'record'}->uuid
+ };
+
+ my $string
+ = "|"
+ . join( "|", map { $args{$_} ? $_ . "-" . $args{$_} : '' } keys %bits )
+ . "|";
+
+ input {
+ attr {
+ type => 'hidden',
+ name => "prophet-action|" . $string,
+
+ value => $args{'action'}
+ };
+ };
+
+}
+
+sub widget {
+ my %args = validate( @_, { prop => 1, record => 1 } );
+
+ my $f = Prophet::Web::Field->new(
+ name => Prophet::Server::ViewHelpers->_generate_name(%args),
+ record => $args{record},
+ label => $args{prop},
+ value => $args{record}->prop( $args{'prop'} )
+ );
+ outs_raw($f->render);
+}
+
+sub _generate_name {
+ my $class = shift;
+ my %args = validate( @_, { prop => 1, record => 1 } );
+ my $r = $args{'record'};
+ return "prophet-field||uuid-".$r->uuid."|prop-".$args{prop}."|";
+}
1;
Added: Prophet/branches/actions/lib/Prophet/Web/Field.pm
==============================================================================
--- (empty file)
+++ Prophet/branches/actions/lib/Prophet/Web/Field.pm Thu Nov 27 13:55:50 2008
@@ -0,0 +1,57 @@
+package Prophet::Web::Field;
+use Moose;
+
+has name => ( isa => 'Str', is => 'rw' );
+has record => ( isa => 'Prophet::Record', is => 'rw' );
+has prop => ( isa => 'Str', is => 'rw' );
+has value => ( isa => 'Str', is => 'rw' );
+has label => ( isa => 'Str', is => 'rw', default => sub {''});
+has id => ( isa => 'Str', is => 'rw' );
+has class => ( isa => 'Str', is => 'rw' );
+has value => ( isa => 'Str', is => 'rw' );
+
+sub _render_attr {
+ my $self = shift;
+ my $attr = shift;
+ my $value = $self->$attr() || return '';
+ return $attr . '="' . $self->$attr() . '"';
+}
+
+sub render_name {
+ my $self = shift;
+ $self->_render_attr('name');
+
+}
+
+sub render_id {
+ my $self = shift;
+ $self->_render_attr('id');
+}
+
+sub render_class {
+ my $self = shift;
+ $self->_render_attr('class');
+}
+
+sub render_value {
+ my $self = shift;
+ $self->_render_attr('value');
+}
+
+sub render {
+ my $self = shift;
+
+ my $output = <<EOF;
+<label @{[$self->render_name]}>@{[$self->label]}</label>
+<input type="text" @{[$self->render_name]} @{[$self->render_id]} @{[$self->render_class]} @{[$self->render_value]} />
+
+EOF
+
+ return $output;
+
+}
+
+__PACKAGE__->meta->make_immutable;
+no Moose;
+
+1;
Added: Prophet/branches/actions/t/WebToy/bin/webtoy
==============================================================================
--- (empty file)
+++ Prophet/branches/actions/t/WebToy/bin/webtoy Thu Nov 27 13:55:50 2008
@@ -0,0 +1,13 @@
+#!/usr/bin/env perl
+use warnings;
+use strict;
+use lib 'lib';
+use lib '../../lib';
+use App::WebToy::CLI;
+# Moose likes generating very noisy backtraces. Most users don't need to see
+# anything more than the root cause of the failure. Developers and the curious
+# can set environment variable SD_VERBOSE_ERROR to retain the backtraces.
+# When Moose's error throwing is more malleable we should switch to using that.
+my $cli = App::WebToy::CLI->new;
+$cli->run_one_command(@ARGV);
+
Added: Prophet/branches/actions/t/WebToy/lib/App/WebToy.pm
==============================================================================
--- (empty file)
+++ Prophet/branches/actions/t/WebToy/lib/App/WebToy.pm Thu Nov 27 13:55:50 2008
@@ -0,0 +1,32 @@
+package App::WebToy;
+use Moose;
+use App::WebToy::Model::WikiPage;
+extends 'Prophet::App';
+
+=head1 NAME
+
+=head1 METHODS
+
+=head1 DESCRIPTION
+
+=cut
+
+=head1 METHODS
+
+=cut
+
+sub set_db_defaults {
+ my $self = shift;
+ $self->SUPER::set_db_defaults(@_);
+ my $record = App::WebToy::Model::WikiPage->new(app_handle => $self);
+ $record->create( props => { title => 'TitleOfPage', content => 'Body!'});
+
+}
+
+
+
+__PACKAGE__->meta->make_immutable;
+no Moose;
+
+1;
+
Added: Prophet/branches/actions/t/WebToy/lib/App/WebToy/CLI.pm
==============================================================================
--- (empty file)
+++ Prophet/branches/actions/t/WebToy/lib/App/WebToy/CLI.pm Thu Nov 27 13:55:50 2008
@@ -0,0 +1,16 @@
+package App::WebToy::CLI;
+use Moose;
+extends 'Prophet::CLI';
+
+use App::WebToy;
+
+has 'app_class' => (
+ default => 'App::WebToy',
+);
+
+
+__PACKAGE__->meta->make_immutable;
+no Moose;
+
+1;
+
Added: Prophet/branches/actions/t/WebToy/lib/App/WebToy/Collection/WikiPage.pm
==============================================================================
--- (empty file)
+++ Prophet/branches/actions/t/WebToy/lib/App/WebToy/Collection/WikiPage.pm Thu Nov 27 13:55:50 2008
@@ -0,0 +1,23 @@
+package App::WebToy::Collection::WikiPage;
+use base 'Prophet::Collection';
+use App::WebToy::Model::WikiPage;
+
+use constant record_class => 'App::WebToy::Model::WikiPage';
+
+
+
+=head1 NAME
+
+=head1 METHODS
+
+=head1 DESCRIPTION
+
+=cut
+
+=head1 METHODS
+
+=cut
+
+
+1;
+
Added: Prophet/branches/actions/t/WebToy/lib/App/WebToy/Model/WikiPage.pm
==============================================================================
--- (empty file)
+++ Prophet/branches/actions/t/WebToy/lib/App/WebToy/Model/WikiPage.pm Thu Nov 27 13:55:50 2008
@@ -0,0 +1,29 @@
+package App::WebToy::Model::WikiPage;
+use Moose;
+extends 'Prophet::Record';
+has type => ( default => 'wikipage');
+
+
+
+sub declared_props {qw(title content tags mood)};
+
+=head1 NAME
+
+=head1 METHODS
+
+=head1 DESCRIPTION
+
+=cut
+
+=head1 METHODS
+
+=cut
+
+
+
+
+__PACKAGE__->meta->make_immutable;
+no Moose;
+
+1;
+
Added: Prophet/branches/actions/t/WebToy/lib/App/WebToy/Server/Dispatcher.pm
==============================================================================
--- (empty file)
+++ Prophet/branches/actions/t/WebToy/lib/App/WebToy/Server/Dispatcher.pm Thu Nov 27 13:55:50 2008
@@ -0,0 +1,25 @@
+package App::WebToy::Server::Dispatcher;
+use Prophet::Server::Dispatcher -base;
+
+on qr'^GET/(.*)$' => sub {show_template($1)->(@_)};
+
+redispatch_to 'Prophet::Server::Dispatcher';
+
+
+sub show_template {
+ if(ref($_[0])) {
+ # called in oo context. do it now
+ my $self = shift;
+ my $template = shift;
+ $self->server->show_template($template, @_);
+ } else {
+
+ my $template = shift;
+ return sub {
+ my $self = shift;
+ $self->server->show_template($template, @_);
+ };
+ }
+}
+
+1;
Added: Prophet/branches/actions/t/WebToy/lib/App/WebToy/Server/View.pm
==============================================================================
--- (empty file)
+++ Prophet/branches/actions/t/WebToy/lib/App/WebToy/Server/View.pm Thu Nov 27 13:55:50 2008
@@ -0,0 +1,37 @@
+package App::WebToy::Server::View;
+use base 'Prophet::Server::View';
+use Template::Declare::Tags;
+use Prophet::Server::ViewHelpers;
+use App::WebToy::Collection::WikiPage;
+
+=head1 NAME
+
+=head1 METHODS
+
+=head1 DESCRIPTION
+
+=cut
+
+=head1 METHODS
+
+=cut
+
+
+template 'abc' => sub {
+ my $self = shift;
+ my $c = App::WebToy::Collection::WikiPage->new(app_handle => $self->app_handle);
+ $c->matching(sub { return 1});
+ my $r = $c->items->[0];
+ h1 { $r->prop('title')};
+ form {
+ function( record => $r, action => 'update');
+ widget( record => $r, prop => 'title');
+
+ input {attr { label => 'save', type => 'submit'}};
+ }
+
+};
+
+
+1;
+
More information about the Bps-public-commit
mailing list