X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=lib%2FMaypole.pm;h=dd9ff770a1827ca393dd4361509222461135f1b7;hb=193575767582376e4a70c5d4af176dab84b2b0ee;hp=11fbe52791014fda2e9c0cb6af9abbf187fd1748;hpb=4ab33d12a514e0531e16f3d2812b15258de258c5;p=maypole.git diff --git a/lib/Maypole.pm b/lib/Maypole.pm index 11fbe52..dd9ff77 100644 --- a/lib/Maypole.pm +++ b/lib/Maypole.pm @@ -1,16 +1,17 @@ package Maypole; -use base qw(Class::Accessor Class::Data::Inheritable); +use base qw(Class::Accessor::Fast Class::Data::Inheritable); use attributes (); use UNIVERSAL::require; use strict; use warnings; -our $VERSION = "1.8"; +use Maypole::Config; +our $VERSION = '2.0'; __PACKAGE__->mk_classdata($_) for qw( config init_done view_object ); __PACKAGE__->mk_accessors( - qw( ar params query objects model_class - args action template ) + qw( ar params query objects model_class template_args output path + args action template error document_encoding content_type table) ); -__PACKAGE__->config( {} ); +__PACKAGE__->config( Maypole::Config->new() ); __PACKAGE__->init_done(0); use Maypole::Constants; @@ -27,26 +28,27 @@ sub setup { sub { Maypole::handler( $calling_class, @_ ) }; } my $config = $calling_class->config; - $config->{model} ||= "Maypole::Model::CDBI"; - $config->{model}->require; - die "Couldn't load the model class $config->{model}: $@" if $@; - $config->{model}->setup_database( $config, $calling_class, @_ ); - for my $subclass ( @{ $config->{classes} } ) { + $config->model || $config->model("Maypole::Model::CDBI"); + $config->model->require; + die "Couldn't load the model class $config->model: $@" if $@; + $config->model->setup_database( $config, $calling_class, @_ ); + for my $subclass ( @{ $config->classes } ) { no strict 'refs'; - unshift @{ $subclass . "::ISA" }, $config->{model}; - $config->{model}->adopt($subclass) - if $config->{model}->can("adopt"); + unshift @{ $subclass . "::ISA" }, $config->model; + $config->model->adopt($subclass) + if $config->model->can("adopt"); } } sub init { my $class = shift; my $config = $class->config; - $config->{view} ||= "Maypole::View::TT"; - $config->{view}->require; - die "Couldn't load the view class $config->{view}: $@" if $@; - $config->{display_tables} ||= [ @{ $class->config->{tables} } ]; - $class->view_object( $class->config->{view}->new ); + $config->view || $config->view("Maypole::View::TT"); + $config->view->require; + die "Couldn't load the view class " . $config->view . ": $@" if $@; + $config->display_tables + || $config->display_tables( [ $class->config->tables ] ); + $class->view_object( $class->config->view->new ); $class->init_done(1); } @@ -65,9 +67,10 @@ sub handler { return $status; } +# The root of all evil sub handler_guts { my $r = shift; - $r->model_class( $r->config->{model}->class_of( $r, $r->{table} ) ); + $r->model_class( $r->config->model->class_of( $r, $r->{table} ) ); my $applicable = $r->is_applicable; unless ( $applicable == OK ) { @@ -83,7 +86,7 @@ sub handler_guts { if ( my $error = $@ ) { $status = $r->call_exception($error); if ( $status != OK ) { - warn "caught model error: $error"; + warn "caught authenticate error: $error"; return $r->debug ? $r->view_object->error( $r, $error ) : ERROR; } } @@ -106,7 +109,15 @@ sub handler_guts { } } if ( !$r->{output} ) { # You might want to do it yourself - return $r->view_object->process($r); + eval { $status = $r->view_object->process($r) }; + if ( my $error = $@ ) { + $status = $r->call_exception($error); + if ( $status != OK ) { + warn "caught view error: $error" if $r->debug; + return $r->debug ? $r->view_object->error( $r, $error ) : ERROR; + } + } + return $status; } else { return OK; } } @@ -114,13 +125,13 @@ sub handler_guts { sub is_applicable { my $self = shift; my $config = $self->config; - $config->{ok_tables} ||= $config->{display_tables}; - $config->{ok_tables} = { map { $_ => 1 } @{ $config->{ok_tables} } } - if ref $config->{ok_tables} eq "ARRAY"; + $config->ok_tables || $config->ok_tables( $config->display_tables ); + $config->ok_tables( { map { $_ => 1 } @{ $config->ok_tables } } ) + if ref $config->ok_tables eq "ARRAY"; warn "We don't have that table ($self->{table})" if $self->debug - and not $config->{ok_tables}{ $self->{table} }; - return DECLINED() unless exists $config->{ok_tables}{ $self->{table} }; + and not $config->ok_tables->{ $self->{table} }; + return DECLINED() unless exists $config->ok_tables->{ $self->{table} }; # Does the action method exist? my $cv = $self->model_class->can( $self->{action} ); @@ -210,9 +221,9 @@ for the designers to customize, and then write an Apache handler like this: package ProductDatabase; - use base 'Apache::MVC'; + use base 'Maypole::Application'; __PACKAGE__->set_database("dbi:mysql:products"); - ProductDatabase->config->{uri_base} = "http://your.site/catalogue/"; + ProductDatabase->config->uri_base = "http://your.site/catalogue/"; ProductDatabase::Product->has_a("category" => ProductDatabase::Category); # ... @@ -270,7 +281,7 @@ subclass the model class, and configure your class slightly differently: Then your top-level application package should change the model class: (Before calling C) - ProductDatabase->config->{model} = "ProductDatabase::Model"; + ProductDatabase->config->model("ProductDatabase::Model"); (The C<:Exported> attribute means that the method can be called via the URL C/supersearch/...>.) @@ -294,7 +305,8 @@ You should probably not use Maypole directly. Maypole is an abstract class which does not specify how to communicate with the outside world. The most popular subclass of Maypole is L, which interfaces the Maypole framework to Apache mod_perl; another important one is -L. +L. However, if you just don't care, use Maypole::Application, +and it will choose the right one for you. If you are implementing Maypole subclasses, you need to provide at least the C and C methods. You may also want to @@ -320,7 +332,7 @@ There's more documentation, examples, and a wiki at the Maypole web site: http://maypole.simon-cozens.org/ -L, L. +L,L, L. =head1 MAINTAINER @@ -332,7 +344,8 @@ Simon Cozens, C =head1 THANK YOU -Jesse Scheidlower, Jody Belka, Markus Ramberg, Mickael Joanne, Simon Flack and all the others who've helped. +Danijel Milicevic, Jesse Scheidlower, Jody Belka, Marcus Ramberg, +Mickael Joanne, Simon Flack, Veljko Vidovic and all the others who've helped. =head1 LICENSE