X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=lib%2FMaypole.pm;h=858437e39fadc75d1a4ab6ea3543ab5be58f513d;hb=8e96ebeddb37ef30d2e215f935e136a9170576cd;hp=03205a61486545dde470811213440cfc9e09adb6;hpb=8d3f7b6c5612270c10042d8e0a9e52ad4ad54a46;p=maypole.git diff --git a/lib/Maypole.pm b/lib/Maypole.pm index 03205a6..858437e 100644 --- a/lib/Maypole.pm +++ b/lib/Maypole.pm @@ -1,4 +1,5 @@ package Maypole; +use Class::C3; use base qw(Class::Accessor::Fast Class::Data::Inheritable); use UNIVERSAL::require; use strict; @@ -12,7 +13,7 @@ use URI::QueryParam; use NEXT; use File::MMagic::XS qw(:compat); -our $VERSION = '2.11_pre4'; +our $VERSION = '2.12'; our $mmagic = File::MMagic::XS->new(); # proposed privacy conventions: @@ -35,6 +36,9 @@ The canonical example used in the Maypole documentation is the beer database: # choose a frontend, initialise the config object, and load a plugin use Maypole::Application qw/Relationship/; + + # set everything up + __PACKAGE__->setup("dbi:SQLite:t/beerdb.db"); # get the empty config object created by Maypole::Application my $config = __PACKAGE__->config; @@ -62,8 +66,8 @@ The canonical example used in the Maypole documentation is the beer database: date => [ qw/date/], ); - # set everything up - __PACKAGE__->setup("dbi:SQLite:t/beerdb.db"); + # note : set up model before calling this method + BeerDB::Beer->required_columns([qw/name/]); 1; @@ -180,7 +184,7 @@ __PACKAGE__->mk_classdata($_) for qw( config init_done view_object model_classes __PACKAGE__->mk_accessors( qw( params query objects model_class template_args output path args action template error document_encoding content_type table - headers_in headers_out stash status parent) + headers_in headers_out stash status parent build_form_elements) ); __PACKAGE__->config( Maypole::Config->new() ); @@ -296,14 +300,10 @@ sub setup_model { # among other things, this populates $config->classes $config->model->setup_database($config, $class, @_); - foreach my $subclass ( @{ $config->classes } ) { - next if $subclass->isa("Maypole::Model::Base"); - no strict 'refs'; - unshift @{ $subclass . "::ISA" }, $config->model; - } + $config->model->add_model_superclass($config); # Load custom model code, if it exists - nb this must happen after the - # unshift, to allow code attributes to work, but before adopt(), + # adding the model superclass, to allow code attributes to work, but before adopt(), # in case adopt() calls overridden methods on $subclass foreach my $subclass ( @{ $config->classes } ) { $class->load_model_subclass($subclass) unless ($class->model_classes_loaded()); @@ -381,13 +381,12 @@ sub new config => $class->config, }, $class; - $self->stash({}); - $self->params({}); - $self->query({}); - $self->template_args({}); - $self->args([]); - $self->objects([]); - + $self->stash({}); + $self->params({}); + $self->query({}); + $self->template_args({}); + $self->args([]); + $self->objects([]); return $self; } @@ -477,7 +476,6 @@ sub component { $self->get_user; my $url = URI->new($path); - warn "path : $path\n"; $self->{path} = $url->path; $self->parse_path; $self->params( $url->query_form_hash ); @@ -537,15 +535,13 @@ sub __call_hook This is the main request handling method and calls various methods to handle the request/response and defines the workflow within Maypole. -B. - =cut # The root of all evil sub handler_guts { my ($self) = @_; - + $self->build_form_elements(1); $self->__load_request_model; my $applicable = $self->is_model_applicable == OK; @@ -678,6 +674,29 @@ sub __call_process_view { return $status; } +=item warn + +$r->warn('its all gone pete tong'); + +Warn must be implemented by the backend, i.e. Apache::MVC +and warn to stderr or appropriate logfile. + +You can also over-ride this in your Maypole driver, should you +want to use something like Log::Log4perl instead. + +=cut + +sub warn { } + +=item build_form_elements + +$r->build_form_elements(0); + +Specify whether to build HTML form elements and populate +the cgi element of classmetadata. + +=cut + =item get_request You should only need to define this method if you are writing a new @@ -795,9 +814,9 @@ sub is_model_applicable { if (not $ok) { - warn "We don't have that table ($table).\n" + $self->warn ("We don't have that table ($table).\n" . "Available tables are: " - . join( ",", keys %$ok_tables ) + . join( ",", keys %$ok_tables )) if $self->debug and not $ok_tables->{$table}; return DECLINED; @@ -807,7 +826,7 @@ sub is_model_applicable { my $action = $self->action; return OK if $self->model_class->is_public($action); - warn "The action '$action' is not applicable to the table '$table'" + $self->warn("The action '$action' is not applicable to the table '$table'") if $self->debug; return DECLINED; @@ -966,10 +985,13 @@ sub parse_path # conditionally, broke lots of tests, hence this: $self->$_(undef) for qw/action table args/; $self->preprocess_path; - $self->path || $self->path('frontpage'); - my @pi = grep {length} split '/', $self->path; + # use frontpage template for frontpage + unless ($self->path && $self->path ne '/') { + $self->path('frontpage'); + } + my @pi = grep {length} split '/', $self->path; $self->table || $self->table(shift @pi); $self->action || $self->action( shift @pi or 'index' ); @@ -1151,6 +1173,11 @@ sub object { Get/set a hash of template variables. +Maypole reserved words for template variables will over-ride values in template_variables. + +Reserved words are : r, request, object, objects, base, config and errors, as well as the +current class or object name. + =item stash A place to put custom application data. Not used by Maypole itself.