]> git.decadent.org.uk Git - maypole.git/blobdiff - lib/Maypole.pm
Added Maypole::Manual::Inheritance and Maypole::Manual::Terminology. Renamed Maypole...
[maypole.git] / lib / Maypole.pm
index 36f085880f02f11b1f523ebdf577510eb2d8870e..53732c480dfdfa0aa5e8aa819f475f739cb07ba7 100644 (file)
@@ -6,6 +6,7 @@ use warnings;
 use Maypole::Config;
 use Maypole::Constants;
 use Maypole::Headers;
+use URI();
 
 our $VERSION = '2.11';
 
@@ -19,7 +20,7 @@ __PACKAGE__->mk_classdata($_) for qw( config init_done view_object );
 __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)
+        headers_in headers_out stash session)
 );
 __PACKAGE__->config( Maypole::Config->new() );
 __PACKAGE__->init_done(0);
@@ -118,10 +119,11 @@ sub handler_guts
     my $applicable = $self->is_model_applicable;
     
     $self->__setup_plain_template unless $applicable;
+
+    $self->session($self->call_get_session);
     
-    # We authenticate every request, needed for proper session management
     my $status;
-    
+
     eval { $status = $self->call_authenticate };
     
     if ( my $error = $@ ) 
@@ -284,9 +286,6 @@ sub is_model_applicable
     return 0;
 }
 
-# *only* intended for translating the return code from is_applicable()
-sub __to_boolean { $_[0] == OK ? 1 : 0 }
-
 sub call_authenticate 
 {
     my ($self) = @_;
@@ -302,6 +301,11 @@ sub call_authenticate
     return $self->authenticate($self);   
 }
 
+sub call_get_session {
+   my ($self) = @_;
+   return $self->get_session($self);
+}
+
 sub call_exception 
 {
     my ($self, $error) = @_;
@@ -341,23 +345,86 @@ sub additional_data { }
 
 sub authenticate { return OK }
 
+sub get_session { }
+
 sub exception { return ERROR }
 
+sub preprocess_path { };
+
 sub parse_path 
 {
     my ($self) = @_;
     
+    $self->preprocess_path;
+
     $self->path || $self->path('frontpage');
     
     my @pi = grep {length} split '/', $self->path;
     
-    $self->table(shift @pi);
+    $self->table || $self->table(shift @pi);
     
-    $self->action( shift @pi or 'index' );
+    $self->action || $self->action( shift @pi or 'index' );
     
-    $self->args(\@pi);
+    $self->args || $self->args(\@pi);
 }
 
+
+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;
+}
+
+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;
+}
+
+
 # like CGI::param(), but read only 
 sub param 
 { 
@@ -421,16 +488,39 @@ Maypole is a Perl web application framework similar to Java's struts. It is
 essentially completely abstracted, and so doesn't know anything about
 how to talk to the outside world.
 
-To use it, you need to create a package which represents your entire
+To use it, you need to create a driver  package which represents your entire
 application. In our example above, this is the C<BeerDB> package.
 
 This needs to first use L<Maypole::Application> which will make your package
 inherit from the appropriate platform driver such as C<Apache::MVC> or
-C<CGI::Maypole>, and then call setup.  This sets up the model classes and
+C<CGI::Maypole>. Then, the driver calls C<setup>.  This sets up the model classes and
 configures your application. The default model class for Maypole uses
 L<Class::DBI> to map a database to classes, but this can be changed by altering
 configuration. (B<Before> calling setup.)
 
+
+=head1 DOCUMENTATION ROADMAP
+
+The primary documentation is the Maypole manual. This lives in the 
+C<Maypole::Manual> pod documents included with the distribution. 
+
+
+=head1 DEMOS
+
+A couple of demos are available, usually with source code and configs. 
+
+=over4 
+
+=item beerdb.riverside-cms.co.uk
+
+Looks to be down at the moment. 
+
+=item beerfb.riverside-cms.co.uk
+
+A demo of L<Maypole::FormBuilder>. This site is running on the set of Mason 
+templates included in the L<Maypole::FormBuilder> distribution. See the 
+synopsis of L<Maypole::Plugin::FormBuilder> for an example driver
+
 =head2 CLASS METHODS
 
 =head3 config
@@ -485,8 +575,49 @@ Returns the request path
 
 =head3 parse_path
 
-Parses the request path and sets the C<args>, C<action> and C<table> 
-properties
+Parses the request path and sets the C<args>, C<action> and C<table>
+properties. Calls preprocess_path before parsing path and setting properties.
+
+=head3 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. 
+
+=head3 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
+
+=head3 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.
 
 =head3 table
 
@@ -688,6 +819,8 @@ 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.
 
+=head3 redirect_internal_request 
+
 =head3 handler
 
 This method sets up the class if it's not done yet, sets some
@@ -711,7 +844,7 @@ L<Maypole::Application>, L<Apache::MVC>, L<CGI::Maypole>.
 
 =head1 AUTHOR
 
-Maypole is currently maintained by Simon Flack C<simonflk#cpan.org>
+Maypole is currently maintained by Aaron Trevena
 
 =head1 AUTHOR EMERITUS