+The named parameters are protocol, domain, path, status and url
+
+Only 1 named parameter is required but other than url, they can be combined as
+required and current values (from the request) will be used in place of any
+missing arguments. The url argument must be a full url including protocol and
+can only be combined with status.
+
+=cut
+
+sub redirect_request {
+ die "redirect_request is a virtual method. Do not use Maypole directly; use Apache::MVC or similar";
+}
+
+=item redirect_internal_request
+
+=cut
+
+sub redirect_internal_request {
+
+}
+
+=back
+
+=head2 Path processing and manipulation
+
+=over 4
+
+=item path
+
+Returns the request path
+
+=item parse_path
+
+Parses the request path and sets the C<args>, C<action> and C<table>
+properties. Calls C<preprocess_path> before parsing path and setting properties.
+
+=cut
+
+sub parse_path
+{
+ my ($self) = @_;
+
+ # Previous versions unconditionally set table, action and args to whatever
+ # was in @pi (or else to defaults, if @pi is empty).
+ # Adding preprocess_path(), and then setting table, action and args
+ # 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;
+
+ $self->table || $self->table(shift @pi);
+ $self->action || $self->action( shift @pi or 'index' );
+ $self->args || $self->args(\@pi);
+}
+
+=item preprocess_path
+
+Sometimes when you don't want to rewrite or over-ride parse_path but
+want to rewrite urls or extract data from them before it is parsed.
+
+This method is called after parse_location has populated the request
+information and before parse_path has populated the model and action
+information, and is passed the request object.
+
+You can set action, args or table in this method and parse_path will
+then leave those values in place or populate them if not present
+
+=cut
+
+sub preprocess_path { };
+
+=item make_path( %args or \%args or @args )
+
+This is the counterpart to C<parse_path>. It generates a path to use
+in links, form actions etc. To implement your own path scheme, just override
+this method and C<parse_path>.
+
+ %args = ( table => $table,
+ action => $action,
+ additional => $additional, # optional - generally an object ID
+ );
+
+ \%args = as above, but a ref
+
+ @args = ( $table, $action, $additional ); # $additional is optional
+
+C<id> can be used as an alternative key to C<additional>.
+
+C<$additional> can be a string, an arrayref, or a hashref. An arrayref is
+expanded into extra path elements, whereas a hashref is translated into a query
+string.
+
+=cut
+
+sub make_path
+{
+ my $r = shift;
+
+ my %args;
+
+ if (@_ == 1 and ref $_[0] and ref $_[0] eq 'HASH')
+ {
+ %args = %{$_[0]};
+ }
+ elsif ( @_ > 1 and @_ < 4 )
+ {
+ $args{table} = shift;
+ $args{action} = shift;
+ $args{additional} = shift;
+ }
+ else
+ {
+ %args = @_;
+ }
+
+ do { die "no $_" unless $args{$_} } for qw( table action );
+
+ my $additional = $args{additional} || $args{id};
+
+ my @add = ();
+
+ if ($additional)
+ {
+ # if $additional is a href, make_uri() will transform it into a query
+ @add = (ref $additional eq 'ARRAY') ? @$additional : ($additional);
+ }
+
+ my $uri = $r->make_uri($args{table}, $args{action}, @add);
+
+ return $uri->as_string;
+}
+
+
+
+=item make_uri( @segments )
+
+Make a L<URI> object given table, action etc. Automatically adds
+the C<uri_base>.
+
+If the final element in C<@segments> is a hash ref, C<make_uri> will render it
+as a query string.
+
+=cut
+
+sub make_uri
+{
+ my ($r, @segments) = @_;
+
+ my $query = (ref $segments[-1] eq 'HASH') ? pop(@segments) : undef;
+
+ my $base = $r->config->uri_base;
+ $base =~ s|/$||;
+
+ my $uri = URI->new($base);
+ $uri->path_segments($uri->path_segments, grep {length} @segments);
+
+ my $abs_uri = $uri->abs('/');
+ $abs_uri->query_form($query) if $query;
+ return $abs_uri;
+}
+
+=item parse_args
+
+Turns post data and query string paramaters into a hash of C<params>.
+
+You should only need to define this method if you are writing a new Maypole
+backend.
+
+=back
+
+=head2 Request properties
+
+=over 4
+
+=item model_class
+
+Returns the perl package name that will serve as the model for the
+request. It corresponds to the request C<table> attribute.
+
+
+=item objects
+
+Get/set a list of model objects. The objects will be accessible in the view
+templates.
+
+If the first item in C<$self-E<gt>args> can be C<retrieve()>d by the model
+class, it will be removed from C<args> and the retrieved object will be added to
+the C<objects> list. See L<Maypole::Model> for more information.
+
+=item template_args
+
+ $self->template_args->{foo} = 'bar';
+
+Get/set a hash of template variables.
+
+=item stash
+
+A place to put custom application data. Not used by Maypole itself.
+
+=item template
+
+Get/set the template to be used by the view. By default, it returns
+C<$self-E<gt>action>
+
+
+=item error
+
+Get/set a request error
+
+=item output
+
+Get/set the response output. This is usually populated by the view class. You
+can skip view processing by setting the C<output>.
+
+=item table
+
+The table part of the Maypole request path
+
+=item action
+
+The action part of the Maypole request path
+
+=item args
+
+A list of remaining parts of the request path after table and action
+have been
+removed
+
+=item headers_in
+
+A L<Maypole::Headers> object containing HTTP headers for the request
+
+=item headers_out
+
+A L<HTTP::Headers> object that contains HTTP headers for the output
+
+=item document_encoding
+
+Get/set the output encoding. Default: utf-8.
+
+=item content_type
+
+Get/set the output content type. Default: text/html
+
+=item get_protocol
+
+Returns the protocol the request was made with, i.e. https
+
+=cut
+
+sub get_protocol {
+ die "get_protocol is a virtual method. Do not use Maypole directly; use Apache::MVC or similar";
+}
+
+=back
+
+=head2 Request parameters
+
+The source of the parameters may vary depending on the Maypole backend, but they
+are usually populated from request query string and POST data.
+
+Maypole supplies several approaches for accessing the request parameters. Note
+that the current implementation (via a hashref) of C<query> and C<params> is
+likely to change in a future version of Maypole. So avoid direct access to these
+hashrefs:
+
+ $r->{params}->{foo} # bad
+ $r->params->{foo} # better
+
+ $r->{query}->{foo} # bad
+ $r->query->{foo} # better
+
+ $r->param('foo') # best
+
+=over 4
+
+=item param
+
+An accessor (get or set) for request parameters. It behaves similarly to
+CGI::param() for accessing CGI parameters, i.e.
+
+ $r->param # returns list of keys
+ $r->param($key) # returns value for $key
+ $r->param($key => $value) # returns old value, sets to new value
+
+=cut
+
+sub param
+{
+ my ($self, $key) = (shift, shift);
+
+ return keys %{$self->params} unless defined $key;
+
+ return unless exists $self->params->{$key};
+
+ my $val = $self->params->{$key};
+
+ if (@_)
+ {
+ my $new_val = shift;
+ $self->params->{$key} = $new_val;
+ }
+
+ return ref $val ? @$val : ($val) if wantarray;
+
+ return ref $val ? $val->[0] : $val;
+}
+
+
+=item params
+
+Returns a hashref of request parameters.
+
+B<Note:> Where muliple values of a parameter were supplied, the C<params> value
+will be an array reference.
+
+=item query
+
+Alias for C<params>.
+
+=item make_random_id
+
+returns a unique id for this request can be used to prevent or detect repeat
+submissions.
+
+=cut
+
+# Session and Repeat Submission Handling
+sub make_random_id {
+ use Maypole::Session;
+ return Maypole::Session::generate_unique_id();
+}
+
+=back
+
+=head1 SEE ALSO
+
+There's more documentation, examples, and a information on our mailing lists
+at the Maypole web site:
+
+L<http://maypole.perl.org/>
+
+L<Maypole::Application>, L<Apache::MVC>, L<CGI::Maypole>.