__PACKAGE__->init_done(0);
+=head1 HOOKABLE METHODS
+
+As a framework, Maypole provides a number of B<hooks> - methods that are
+intended to be overridden. Some of these methods come with useful default
+behaviour, others do nothing by default. Likely hooks include:
+
+ Class methods
+ -------------
+ debug
+ setup
+ setup_model
+ load_model_subclass
+ init
+
+ Instance methods
+ ----------------
+ start_request_hook
+ is_model_applicable
+ get_session
+ authenticate
+ exception
+ additional_data
+ preprocess_path
+
=head1 CLASS METHODS
=over 4
+=item debug
+
+ sub My::App::debug {1}
+
+Returns the debugging flag. Override this in your application class to
+enable/disable debugging.
+
+You can also set the C<debug> flag via L<Maypole::Application>.
+
+=cut
+
+sub debug { 0 }
+
=item config
Returns the L<Maypole::Config> object
{
no strict 'refs';
unshift @{ $subclass . "::ISA" }, $config->model;
- $config->model->adopt($subclass)
- if $config->model->can("adopt");
-
- # Load custom model code, if it exists - nb this must happen after the
- # unshift, to allow code attributes to work
- eval "use $subclass";
- die "Error loading $subclass: $@"
- if $@ and $@ !~ /Can\'t locate \S+ in \@INC/;
+
+ # Load custom model code, if it exists - nb this must happen after the
+ # unshift, to allow code attributes to work, but before adopt(),
+ # in case adopt() calls overridden methods on $subclass
+ $class->load_model_subclass($subclass);
+
+ $config->model->adopt($subclass) if $config->model->can("adopt");
+
+# eval "use $subclass";
+# die "Error loading $subclass: $@"
+# if $@ and $@ !~ /Can\'t locate \S+ in \@INC/;
}
}
+=item load_model_subclass($subclass)
+
+This method is called from C<setup_model()>. It attempts to load the
+C<$subclass> package, if one exists. So if you make a customized C<BeerDB::Beer>
+package, you don't need to explicitly load it.
+
+If, perhaps during development, you don't want to load up custom classes, you
+can override this method and load them manually.
+
+=cut
+
+sub load_model_subclass
+{
+ my ($class, $subclass) = @_;
+
+ my $config = $class->config;
+
+ # Load any external files for the model base class or subclasses
+ # (e.g. BeerDB/DBI.pm or BeerDB/Beer.pm) based on code borrowed from
+ # Maypole::Plugin::Loader and Class::DBI.
+ if ( $subclass->require )
+ {
+ warn "Loaded external module for '$subclass'\n" if $class->debug > 1;
+ }
+ else
+ {
+ (my $filename = $subclass) =~ s!::!/!g;
+ die "Loading '$subclass' failed: $@\n"
+ unless $@ =~ /Can\'t locate \Q$filename\E\.pm/;
+ warn "Did not find external module for '$subclass'\n"
+ if $class->debug > 1;
+ }
+}
+
=item init
Loads the view class and instantiates the view object.
Get/set the Maypole::View object
-=item debug
-
- sub My::App::debug {1}
-
-Returns the debugging flag. Override this in your application class to
-enable/disable debugging.
-
-You can also set the C<debug> flag via L<Maypole::Application>.
-
-=cut
-
-sub debug { 0 }
-
-=item get_template_root
-
-Implementation-specific path to template root.
-
-You should only need to define this method if you are writing a new Maypole
-backend. Otherwise, see L<Maypole::Config/"template_root">
-
-=cut
-
-sub get_template_root {'.'}
-
=back
=head1 INSTANCE METHODS
{
my ($self) = @_;
- $self->__load_model;
+ $self->__load_request_model;
my $applicable = $self->is_model_applicable;
return $self->__call_process_view;
}
-sub __load_model
+sub __load_request_model
{
my ($self) = @_;
$self->model_class( $self->config->model->class_of($self, $self->table) );
You should only need to define this method if you are writing a new Maypole
backend.
+=cut
+
+sub parse_args
+{
+ die "parse_args() is a virtual method. Do not use Maypole directly; ".
+ "use Apache::MVC or similar";
+}
+
+=item get_template_root
+
+Implementation-specific path to template root.
+
+You should only need to define this method if you are writing a new Maypole
+backend. Otherwise, see L<Maypole::Config/"template_root">
+
+=cut
+
+sub get_template_root {'.'}
+
=back
=head2 Request properties
=back
+=head1 SEQUENCE DIAGRAMS
+
+See L<Maypole::Manual::Workflow> for a detailed discussion of the sequence of
+calls during processing of a request. This is a brief summary:
+
+ INITIALIZATION
+ Model e.g.
+ BeerDB Maypole::Model::CDBI
+ | |
+ setup | |
+ o-------->|| |
+ || setup_model | setup_database() creates
+ ||------+ | a subclass of the Model
+ |||<----+ | for each table
+ ||| | |
+ ||| setup_database | |
+ |||--------------------->|| 'create' *
+ ||| ||----------> $subclass
+ ||| | |
+ ||| load_model_subclass | |
+ foreach |||------+ ($subclass) | |
+ $subclass ||||<----+ | require |
+ ||||--------------------------------------->|
+ ||| | |
+ ||| adopt($subclass) | |
+ |||--------------------->|| |
+ | | |
+ | | |
+ |-----+ init | |
+ ||<---+ | |
+ || | new | view_object: e.g
+ ||---------------------------------------------> Maypole::View::TT
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+ | | | |
+
+
+
+ HANDLING A REQUEST
+
+
+ BeerDB Model $subclass view_object
+ | | | |
+ handler | | | |
+ o-------->| new | | |
+ |-----> r:BeerDB | | |
+ | | | | |
+ | | | | |
+ | || | | |
+ | ||-----+ parse_location | | |
+ | |||<---+ | | |
+ | || | | |
+ | ||-----+ start_request_hook | | |
+ | |||<---+ | | |
+ | || | | |
+ | ||-----+ get_session | | |
+ | |||<---+ | | |
+ | || | | |
+ | ||-----+ handler_guts | | |
+ | |||<---+ | | |
+ | ||| class_of($table) | | |
+ | |||------------------------->|| | |
+ | ||| $subclass || | |
+ | |||<-------------------------|| | |
+ | ||| | | |
+ | |||-----+ is_model_applicable| | |
+ | ||||<---+ | | |
+ | ||| | | |
+ | |||-----+ call_authenticate | | |
+ | ||||<---+ | | |
+ | ||| | | |
+ | |||-----+ additional_data | | |
+ | ||||<---+ | | |
+ | ||| process | | fetch_objects
+ | |||--------------------------------->||-----+ |
+ | ||| | |||<---+ |
+ | ||| | || |
+ | ||| | || $action
+ | ||| | ||-----+ |
+ | ||| | |||<---+ |
+ | ||| | | |
+ | ||| process | | |
+ | |||------------------------------------------->|| template
+ | ||| | | ||-----+
+ | ||| | | |||<---+
+ | ||| | | |
+ | || send_output | | |
+ | ||-----+ | | |
+ | |||<---+ | | |
+ $status | || | | |
+ <------------------|| | | |
+ | | | | |
+ | X | | |
+ | | | |
+ | | | |
+ | | | |
+
+
+
=head1 SEE ALSO
There's more documentation, examples, and a information on our mailing lists