]> git.decadent.org.uk Git - maypole.git/blob - lib/Maypole.pm
Fixed pod test failure
[maypole.git] / lib / Maypole.pm
1 package Maypole;
2 use base qw(Class::Accessor::Fast Class::Data::Inheritable);
3 use UNIVERSAL::require;
4 use strict;
5 use warnings;
6 use Maypole::Config;
7 use Maypole::Constants;
8 use Maypole::Headers;
9 use URI();
10
11 our $VERSION = '2.11';
12
13 # proposed privacy conventions:
14 # - no leading underscore     - public to custom application code and plugins
15 # - single leading underscore - private to the main Maypole stack - *not*
16 #     including plugins
17 # - double leading underscore - private to the current package
18
19 =head1 NAME
20
21 Maypole - MVC web application framework
22
23 =head1 SYNOPSIS
24
25 See L<Maypole::Application>.
26
27 =head1 DESCRIPTION
28
29 This documents the Maypole request object. See the L<Maypole::Manual>, for a
30 detailed guide to using Maypole.
31
32 Maypole is a Perl web application framework similar to Java's struts. It is 
33 essentially completely abstracted, and so doesn't know anything about
34 how to talk to the outside world.
35
36 To use it, you need to create a driver package which represents your entire
37 application. This is the C<BeerDB> package used as an example in the manual.
38
39 This needs to first use L<Maypole::Application> which will make your package
40 inherit from the appropriate platform driver such as C<Apache::MVC> or
41 C<CGI::Maypole>. Then, the driver calls C<setup>.  This sets up the model classes and
42 configures your application. The default model class for Maypole uses
43 L<Class::DBI> to map a database to classes, but this can be changed by altering
44 configuration (B<before> calling setup.)
45
46
47 =head1 DOCUMENTATION AND SUPPORT
48
49 Note that some details in some of these resources may be out of date.
50
51 =over 4 
52
53 =item The Maypole Manual
54
55 The primary documentation is the Maypole manual. This lives in the 
56 C<Maypole::Manual> pod documents included with the distribution. 
57
58 =item Embedded POD
59
60 Individual packages within the distribution contain (more or less) detailed
61 reference documentation for their API.
62
63 =item Mailing lists
64
65 There are two mailing lists - maypole-devel and maypole-users - see
66 http://maypole.perl.org/?MailingList
67
68 =item The Maypole Wiki
69
70 The Maypole wiki provides a useful store of extra documentation -
71 http://maypole.perl.org
72
73 In particular, there's a FAQ (http://maypole.perl.org/?FAQ) and a cookbook
74 (http://maypole.perl.org/?Cookbook). Again, certain information on these pages
75 may be out of date.
76
77 =item Web applications with Maypole
78
79 A tutorial written by Simon Cozens for YAPC::EU 2005 -
80 http://www.droogs.org/perl/maypole/maypole-tutorial.pdf [228KB].
81
82 =item A Database-Driven Web Application in 18 Lines of Code
83
84 By Paul Barry, published in Linux Journal, March 2005.
85
86 http://www.linuxjournal.com/article/7937
87
88 "From zero to Web-based database application in eight easy steps".
89
90 Maypole won a 2005 Linux Journal Editor's Choice Award
91 (http://www.linuxjournal.com/article/8293) after featuring in this article. 
92
93 =item Build Web apps with Maypole
94
95 By Simon Cozens, on IBM's DeveloperWorks website, May 2004.
96
97 http://www-128.ibm.com/developerworks/linux/library/l-maypole/
98
99 =item Rapid Web Application Deployment with Maypole
100
101 By Simon Cozens, on O'Reilly's Perl website, April 2004.
102
103 http://www.perl.com/pub/a/2004/04/15/maypole.html
104
105 =item Authentication
106
107 Some notes written by Simon Cozens. A little bit out of date, but still 
108 very useful: http://www.droogs.org/perl/maypole/authentication.html
109
110 =item CheatSheet
111
112 There's a refcard for the Maypole (and Class::DBI) APIs on the wiki -
113 http://maypole.perl.org/?CheatSheet. Probably a little out of date now - it's a
114 wiki, so feel free to fix any errors!
115
116 =item Plugins and add-ons
117
118 There are a large and growing number of plugins and other add-on modules
119 available on CPAN - http://search.cpan.org/search?query=maypole&mode=module
120
121 =item del.icio.us
122
123 You can find a range of useful Maypole links, particularly to several thoughtful
124 blog entries, starting here: http://del.icio.us/search/?all=maypole
125
126 =item CPAN ratings
127
128 There are a couple of short reviews here:
129 http://cpanratings.perl.org/dist/Maypole
130
131 =back
132
133 =head1 DEMOS
134
135 A couple of demos are available, sometimes with source code and configs. 
136
137 =over 4 
138
139 =item http://maypole.perl.org/beerdb/
140
141 The standard BeerDB example, using the TT factory templates supplied in the
142 distribution.
143
144 =item beerdb.riverside-cms.co.uk
145
146 The standard BeerDB example, running on Mason, using the factory templates
147 supplied in the L<MasonX::Maypole> distribution.
148
149 =item beerfb.riverside-cms.co.uk
150
151 A demo of L<Maypole::FormBuilder>. This site is running on the set of Mason 
152 templates included in the L<Maypole::FormBuilder> distribution. See the 
153 synopsis of L<Maypole::Plugin::FormBuilder> for an example driver
154
155 =back
156
157 =cut
158
159 __PACKAGE__->mk_classdata($_) for qw( config init_done view_object );
160
161 __PACKAGE__->mk_accessors(
162     qw( params query objects model_class template_args output path
163         args action template error document_encoding content_type table
164         headers_in headers_out stash session)
165 );
166
167 __PACKAGE__->config( Maypole::Config->new() );
168
169 __PACKAGE__->init_done(0);
170
171 =head1 CLASS METHODS
172
173 =over 4
174
175 =item config
176
177 Returns the L<Maypole::Config> object
178
179 =item setup
180
181     My::App->setup($data_source, $user, $password, \%attr);
182
183 Initialise the Maypole application and plugins and model classes - see
184 L<Maypole::Manual::Plugins>.
185
186 If your model is based on L<Maypole::Model::CDBI>, the C<\%attr> hashref can 
187 contain options that are passed directly to L<Class::DBI::Loader>, to control 
188 how the model hierarchy is constructed. 
189
190 Your application should call this B<after> setting up configuration data via
191 L<"config">.
192
193 =cut
194
195 sub setup
196 {
197     my $class = shift;
198     
199     $class->setup_model(@_);    
200 }
201
202 =item setup_model
203
204 Called by C<setup>. This method builds the Maypole model hierarchy. 
205
206 A likely target for over-riding, if you need to build a customised model.
207
208 =cut
209
210 sub setup_model 
211 {
212     my $calling_class = shift;
213     
214     $calling_class = ref $calling_class if ref $calling_class;
215     
216     my $config = $calling_class->config;
217     
218     $config->model || $config->model('Maypole::Model::CDBI');
219     
220     $config->model->require or die sprintf 
221         "Couldn't load the model class %s: %s", $config->model, $@;
222     
223     $config->model->setup_database($config, $calling_class, @_);
224     
225     foreach my $subclass ( @{ $config->classes } ) 
226     {
227         no strict 'refs';
228         unshift @{ $subclass . "::ISA" }, $config->model;
229         $config->model->adopt($subclass)
230           if $config->model->can("adopt");
231         
232         # TODO: I think we should also load these classes, in case there is any 
233         # custom code. It would save the developer from needing to put 
234         # lots of use MyApp::SomeTable statements in the driver, and should 
235         # help eliminate some of those annoying silent errors if there's a 
236         # syntax error.
237     }
238 }
239
240 =item init
241
242 Loads the view class and instantiates the view object.
243
244 You should not call this directly, but you may wish to override this to add
245 application-specific initialisation - see L<Maypole::Manual::Plugins>.
246
247 =cut
248
249 sub init 
250 {
251     my $class  = shift;
252     my $config = $class->config;
253     $config->view || $config->view("Maypole::View::TT");
254     $config->view->require;
255     die "Couldn't load the view class " . $config->view . ": $@" if $@;
256     $config->display_tables
257       || $config->display_tables( $class->config->tables );
258     $class->view_object( $class->config->view->new );
259     $class->init_done(1);
260 }
261
262 =item new
263
264 Constructs a very minimal new Maypole request object.
265
266 =cut
267
268 sub new
269 {
270     my ($class) = @_;
271     
272     my $self = bless {
273         template_args => {},
274         config        => $class->config,
275     }, $class;
276     
277     return $self;
278 }
279
280 =item view_object
281
282 Get/set the Maypole::View object
283
284 =item debug
285
286     sub My::App::debug {1}
287
288 Returns the debugging flag. Override this in your application class to
289 enable/disable debugging.
290
291 You can also set the C<debug> flag via L<Maypole::Application>.
292
293 =cut
294
295 sub debug { 0 }      
296
297 =item get_template_root
298
299 Implementation-specific path to template root.
300
301 You should only need to define this method if you are writing a new Maypole
302 backend. Otherwise, see L<Maypole::Config/"template_root">
303
304 =cut
305
306 sub get_template_root {'.'}
307
308 =back
309
310 =head1 INSTANCE METHODS
311
312 =head2 Workflow
313
314 =over 4
315
316 =item handler
317
318 This method sets up the class if it's not done yet, sets some defaults and
319 leaves the dirty work to C<handler_guts>.
320
321 =cut
322
323 # handler() has a method attribute so that mod_perl will invoke
324 # BeerDB->handler() as a method rather than a plain function
325 # BeerDB::handler() and so this inherited implementation will be
326 # found. See e.g. "Practical mod_perl" by Bekman & Cholet for
327 # more information <http://modperlbook.org/html/ch25_01.html>
328 sub handler : method 
329 {
330     # See Maypole::Workflow before trying to understand this.
331     my ($class, $req) = @_;
332     
333     $class->init unless $class->init_done;
334
335     my $self = $class->new;
336     
337     # initialise the request
338     $self->headers_out(Maypole::Headers->new);
339     $self->get_request($req);
340     $self->parse_location;
341     
342     # hook useful for declining static requests e.g. images
343     my $status = $self->start_request_hook;
344     return $status unless $status == Maypole::Constants::OK();
345     
346     $self->session($self->get_session);
347     
348     $status = $self->handler_guts;
349     
350     # moving this here causes unit test failures - need to check why
351     # before committing the move
352     #$status = $self->__call_process_view unless $self->output;
353     
354     return $status unless $status == OK;
355     
356     # TODO: require send_output to return a status code
357     $self->send_output;
358     
359     return $status;
360 }
361
362 =item handler_guts
363
364 This is the main request handling method and calls various methods to handle the
365 request/response and defines the workflow within Maypole.
366
367 B<Currently undocumented and liable to be refactored without warning>.
368
369 =cut
370
371 # The root of all evil
372 sub handler_guts 
373 {
374     my ($self) = @_;
375     
376     $self->__load_model;
377
378     my $applicable = $self->is_model_applicable;
379     
380     $self->__setup_plain_template unless $applicable;
381
382     my $status;
383
384     eval { $status = $self->call_authenticate };
385     
386     if ( my $error = $@ ) 
387     {
388         $status = $self->call_exception($error);
389         
390         if ( $status != OK ) 
391         {
392             warn "caught authenticate error: $error";
393             return $self->debug ? 
394                     $self->view_object->error($self, $error) : ERROR;
395         }
396     }
397     
398     if ( $self->debug and $status != OK and $status != DECLINED ) 
399     {
400         $self->view_object->error( $self,
401             "Got unexpected status $status from calling authentication" );
402     }
403     
404     return $status unless $status == OK;
405
406     # We run additional_data for every request
407     $self->additional_data;
408     
409     if ($applicable) 
410     {
411         eval { $self->model_class->process($self) };
412         
413         if ( my $error = $@ ) 
414         {
415             $status = $self->call_exception($error);
416             
417             if ( $status != OK ) 
418             {
419                 warn "caught model error: $error";
420                 return $self->debug ? 
421                     $self->view_object->error($self, $error) : ERROR;
422             }
423         }
424     }
425     
426     # less frequent path - perhaps output has been set to an error message
427     return OK if $self->output;
428     
429     # normal path - no output has been generated yet
430     return $self->__call_process_view;
431 }
432
433 sub __load_model
434 {
435     my ($self) = @_;
436     $self->model_class( $self->config->model->class_of($self, $self->table) );
437 }
438
439 # is_applicable() returned false, so set up a plain template. Model processing 
440 # will be skipped, but need to remove the model anyway so the template can't 
441 # access it. 
442 sub __setup_plain_template
443 {
444     my ($self) = @_;
445     
446     # It's just a plain template
447     $self->model_class(undef);
448     
449     my $path = $self->path;
450     $path =~ s{/$}{};    # De-absolutify
451     $self->path($path);
452     
453     $self->template($self->path);
454 }
455
456 # The model has been processed or skipped (if is_applicable returned false), 
457 # any exceptions have been handled, and there's no content in $self->output
458 sub __call_process_view
459 {
460     my ($self) = @_;
461     
462     my $status;
463     
464     eval { $status = $self->view_object->process($self) };
465     
466     if ( my $error = $@ ) 
467     {
468         $status = $self->call_exception($error);
469         
470         if ( $status != OK ) 
471         {
472             warn "caught view error: $error" if $self->debug;
473             return $self->debug ? 
474                 $self->view_object->error($self, $error) : ERROR;
475         }
476     }
477     
478     return $status;
479 }
480
481 =item get_request
482
483 You should only need to define this method if you are writing a new
484 Maypole backend. It should return something that looks like an Apache
485 or CGI request object, it defaults to blank.
486
487 =cut
488
489 sub get_request { }
490
491 =item parse_location
492
493 Turns the backend request (e.g. Apache::MVC, Maypole, CGI) into a Maypole
494 request. It does this by setting the C<path>, and invoking C<parse_path> and
495 C<parse_args>.
496
497 You should only need to define this method if you are writing a new Maypole
498 backend.
499
500 =cut
501
502 sub parse_location 
503 {
504     die "parse_location is a virtual method. Do not use Maypole directly; " . 
505                 "use Apache::MVC or similar";
506 }
507
508 =item start_request_hook
509
510 This is called immediately after setting up the basic request. The default
511 method simply returns C<Maypole::Constants::OK>.
512
513 Any other return value causes Maypole to abort further processing of the
514 request. This is useful for filtering out requests for static files, e.g.
515 images, which should not be processed by Maypole or by the templating engine:
516
517     sub start_request_hook
518     {
519         my ($r) = @_;
520         
521         return Maypole::Constants::DECLINED if $r->path =~ /\.jpg$/;
522         return Maypole::Constants::OK;
523     }
524
525 =cut
526
527 sub start_request_hook { Maypole::Constants::OK }
528
529 =item is_applicable
530
531 B<This method is deprecated> as of version 2.11. If you have overridden it,
532 please override C<is_model_applicable> instead, and change the return type
533 from a Maypole:Constant to a true/false value.
534
535 Returns a Maypole::Constant to indicate whether the request is valid.
536
537 =item is_model_applicable
538
539 Returns true or false to indicate whether the request is valid.
540
541 The default implementation checks that C<< $r->table >> is publicly
542 accessible and that the model class is configured to handle the
543 C<< $r->action >>.
544
545 =cut
546
547 sub is_model_applicable 
548 {
549     my ($self) = @_;
550     
551     # cater for applications that are using obsolete version
552     if ($self->can('is_applicable')) 
553     {
554         warn "DEPRECATION WARNING: rewrite is_applicable to the interface ".
555                 "of Maypole::is_model_applicable\n";
556         return $self->is_applicable == OK;
557     }
558
559     # Establish which tables should be processed by the model
560     my $config = $self->config;
561     
562     $config->ok_tables || $config->ok_tables( $config->display_tables );
563     
564     $config->ok_tables( { map { $_ => 1 } @{ $config->ok_tables } } )
565         if ref $config->ok_tables eq "ARRAY";
566         
567     my $ok_tables = $config->ok_tables;
568       
569     # Does this request concern a table to be processed by the model?
570     my $table = $self->table;
571     
572     my $ok = 0;
573     
574     if (exists $ok_tables->{$table}) 
575     {
576         $ok = 1;
577     } 
578
579     if (not $ok) 
580     {
581         warn "We don't have that table ($table).\n"
582             . "Available tables are: "
583             . join( ",", keys %$ok_tables )
584                 if $self->debug and not $ok_tables->{$table};
585                 
586         return 0;
587     }
588     
589     # Is the action public?
590     my $action = $self->action;
591     return 1 if $self->model_class->is_public($action);
592     
593     warn "The action '$action' is not applicable to the table $table"
594         if $self->debug;
595     
596     return 0;
597 }
598
599 =item get_session
600
601 The default method is empty. 
602
603 =cut
604
605 sub get_session { }
606
607 =item call_authenticate
608
609 This method first checks if the relevant model class
610 can authenticate the user, or falls back to the default
611 authenticate method of your Maypole application.
612
613 =cut
614
615 sub call_authenticate 
616 {
617     my ($self) = @_;
618
619     # Check if we have a model class with an authenticate() to delegate to
620     return $self->model_class->authenticate($self) 
621         if $self->model_class and $self->model_class->can('authenticate');
622     
623     # Interface consistency is a Good Thing - 
624     # the invocant and the argument may one day be different things 
625     # (i.e. controller and request), like they are when authenticate() 
626     # is called on a model class (i.e. model and request)
627     return $self->authenticate($self);   
628 }
629
630 =item authenticate
631
632 Returns a Maypole::Constant to indicate whether the user is authenticated for
633 the Maypole request.
634
635 The default implementation returns C<OK>
636
637 =cut
638
639 sub authenticate { return OK }
640
641
642 =item call_exception
643
644 This model is called to catch exceptions, first after authenticate, then after
645 processing the model class, and finally to check for exceptions from the view
646 class.
647
648 This method first checks if the relevant model class
649 can handle exceptions the user, or falls back to the default
650 exception method of your Maypole application.
651
652 =cut
653
654 sub call_exception 
655 {
656     my ($self, $error) = @_;
657
658     # Check if we have a model class with an exception() to delegate to
659     if ( $self->model_class && $self->model_class->can('exception') )
660     {
661         my $status = $self->model_class->exception( $self, $error );
662         return $status if $status == OK;
663     }
664     
665     return $self->exception($error);
666 }
667
668 =item exception
669
670 This method is called if any exceptions are raised during the authentication or
671 model/view processing. It should accept the exception as a parameter and return
672 a Maypole::Constant to indicate whether the request should continue to be
673 processed.
674
675 =cut
676
677 sub exception { return ERROR }
678
679 =item additional_data
680
681 Called before the model processes the request, this method gives you a chance to
682 do some processing for each request, for example, manipulating C<template_args>.
683
684 =cut
685
686 sub additional_data { }
687
688 =item send_output
689
690 Sends the output and additional headers to the user.
691
692 =cut
693
694 sub send_output {
695     die "send_output is a virtual method. Do not use Maypole directly; use Apache::MVC or similar";
696 }
697
698
699
700
701 =back
702
703 =head2 Path processing and manipulation
704
705 =over 4
706
707 =item path
708
709 Returns the request path
710
711 =item parse_path
712
713 Parses the request path and sets the C<args>, C<action> and C<table>
714 properties. Calls C<preprocess_path> before parsing path and setting properties.
715
716 =cut
717
718 sub parse_path 
719 {
720     my ($self) = @_;
721     
722     # Previous versions unconditionally set table, action and args to whatever 
723     # was in @pi (or else to defaults, if @pi is empty).
724     # Adding preprocess_path(), and then setting table, action and args 
725     # conditionally, broke lots of tests, hence this:
726     $self->$_(undef) for qw/action table args/;
727     
728     $self->preprocess_path;
729
730     $self->path || $self->path('frontpage');
731     
732     my @pi = grep {length} split '/', $self->path;
733     
734     $self->table  || $self->table(shift @pi);
735     $self->action || $self->action( shift @pi or 'index' );
736     $self->args   || $self->args(\@pi);
737 }
738
739 =item preprocess_path
740
741 Sometimes when you don't want to rewrite or over-ride parse_path but
742 want to rewrite urls or extract data from them before it is parsed.
743
744 This method is called after parse_location has populated the request
745 information and before parse_path has populated the model and action
746 information, and is passed the request object.
747
748 You can set action, args or table in this method and parse_path will
749 then leave those values in place or populate them if not present
750
751 =cut
752
753 sub preprocess_path { };
754
755 =item make_path( %args or \%args or @args )
756
757 This is the counterpart to C<parse_path>. It generates a path to use
758 in links, form actions etc. To implement your own path scheme, just override
759 this method and C<parse_path>.
760
761     %args = ( table      => $table,
762               action     => $action,        
763               additional => $additional,    # optional - generally an object ID
764               );
765               
766     \%args = as above, but a ref
767     
768     @args = ( $table, $action, $additional );   # $additional is optional
769
770 C<id> can be used as an alternative key to C<additional>.
771
772 C<$additional> can be a string, an arrayref, or a hashref. An arrayref is
773 expanded into extra path elements, whereas a hashref is translated into a query
774 string. 
775
776 =cut
777
778 sub make_path
779 {
780     my $r = shift;
781     
782     my %args;
783     
784     if (@_ == 1 and ref $_[0] and ref $_[0] eq 'HASH')
785     {
786         %args = %{$_[0]};
787     }
788     elsif ( @_ > 1 and @_ < 4 )
789     {
790         $args{table}      = shift;
791         $args{action}     = shift;
792         $args{additional} = shift;
793     }
794     else
795     {
796         %args = @_;
797     }
798     
799     do { die "no $_" unless $args{$_} } for qw( table action );    
800
801     my $additional = $args{additional} || $args{id};
802     
803     my @add = ();
804     
805     if ($additional)
806     {
807         # if $additional is a href, make_uri() will transform it into a query
808         @add = (ref $additional eq 'ARRAY') ? @$additional : ($additional);
809     }    
810     
811     my $uri = $r->make_uri($args{table}, $args{action}, @add);
812     
813     return $uri->as_string;
814 }
815
816
817
818 =item make_uri( @segments )
819
820 Make a L<URI> object given table, action etc. Automatically adds
821 the C<uri_base>. 
822
823 If the final element in C<@segments> is a hash ref, C<make_uri> will render it
824 as a query string.
825
826 =cut
827
828 sub make_uri
829 {
830     my ($r, @segments) = @_;
831
832     my $query = (ref $segments[-1] eq 'HASH') ? pop(@segments) : undef;
833     
834     my $base = $r->config->uri_base; 
835     $base =~ s|/$||;
836     
837     my $uri = URI->new($base);
838     $uri->path_segments($uri->path_segments, grep {length} @segments);
839     
840     my $abs_uri = $uri->abs('/');
841     $abs_uri->query_form($query) if $query;
842     return $abs_uri;
843 }
844
845 =item parse_args
846
847 Turns post data and query string paramaters into a hash of C<params>.
848
849 You should only need to define this method if you are writing a new Maypole
850 backend.
851
852 =back
853
854 =head2 Request properties
855
856 =over 4
857
858 =item model_class
859
860 Returns the perl package name that will serve as the model for the
861 request. It corresponds to the request C<table> attribute.
862
863
864 =item objects
865
866 Get/set a list of model objects. The objects will be accessible in the view
867 templates.
868
869 If the first item in C<$self-E<gt>args> can be C<retrieve()>d by the model
870 class, it will be removed from C<args> and the retrieved object will be added to
871 the C<objects> list. See L<Maypole::Model> for more information.
872
873 =item template_args
874
875     $self->template_args->{foo} = 'bar';
876
877 Get/set a hash of template variables.
878
879 =item stash
880
881 A place to put custom application data. Not used by Maypole itself. 
882
883 =item template
884
885 Get/set the template to be used by the view. By default, it returns
886 C<$self-E<gt>action>
887
888
889 =item error
890
891 Get/set a request error
892
893 =item output
894
895 Get/set the response output. This is usually populated by the view class. You
896 can skip view processing by setting the C<output>.
897
898 =item table
899
900 The table part of the Maypole request path
901
902 =item action
903
904 The action part of the Maypole request path
905
906 =item args
907
908 A list of remaining parts of the request path after table and action
909 have been
910 removed
911
912 =item headers_in
913
914 A L<Maypole::Headers> object containing HTTP headers for the request
915
916 =item headers_out
917
918 A L<HTTP::Headers> object that contains HTTP headers for the output
919
920 =item document_encoding
921
922 Get/set the output encoding. Default: utf-8.
923
924 =item content_type
925
926 Get/set the output content type. Default: text/html
927
928 =item get_protocol
929
930 Returns the protocol the request was made with, i.e. https
931
932 =cut
933
934 sub get_protocol {
935   die "get_protocol is a virtual method. Do not use Maypole directly; use Apache::MVC or similar";
936 }
937
938 =back
939
940 =head2 Request parameters
941
942 The source of the parameters may vary depending on the Maypole backend, but they
943 are usually populated from request query string and POST data.
944
945 Maypole supplies several approaches for accessing the request parameters. Note
946 that the current implementation (via a hashref) of C<query> and C<params> is
947 likely to change in a future version of Maypole. So avoid direct access to these
948 hashrefs:
949
950     $r->{params}->{foo}      # bad
951     $r->params->{foo}        # better
952
953     $r->{query}->{foo}       # bad
954     $r->query->{foo}         # better
955
956     $r->param('foo')         # best
957
958 =over 4
959
960 =item param
961
962 An accessor (get or set) for request parameters. It behaves similarly to
963 CGI::param() for accessing CGI parameters, i.e.
964
965     $r->param                   # returns list of keys
966     $r->param($key)             # returns value for $key
967     $r->param($key => $value)   # returns old value, sets to new value
968
969 =cut
970
971 sub param 
972
973     my ($self, $key) = (shift, shift);
974     
975     return keys %{$self->params} unless defined $key;
976     
977     return unless exists $self->params->{$key};
978     
979     my $val = $self->params->{$key};
980     
981     if (@_)
982     {
983         my $new_val = shift;
984         $self->params->{$key} = $new_val;
985     }
986     
987     return ref $val ? @$val : ($val) if wantarray;
988         
989     return ref $val ? $val->[0] : $val;
990 }
991
992
993 =item params
994
995 Returns a hashref of request parameters. 
996
997 B<Note:> Where muliple values of a parameter were supplied, the C<params> value
998 will be an array reference.
999
1000 =item query
1001
1002 Alias for C<params>.
1003
1004 =back
1005
1006 =head3 Utility methods
1007
1008 =over 4
1009
1010 =item redirect_request
1011
1012 Sets output headers to redirect based on the arguments provided
1013
1014 Accepts either a single argument of the full url to redirect to, or a hash of
1015 named parameters :
1016
1017 $r->redirect_request('http://www.example.com/path');
1018
1019 or
1020
1021 $r->redirect_request(protocol=>'https', domain=>'www.example.com', path=>'/path/file?arguments', status=>'302', url=>'..');
1022
1023 The named parameters are protocol, domain, path, status and url
1024
1025 Only 1 named parameter is required but other than url, they can be combined as
1026 required and current values (from the request) will be used in place of any
1027 missing arguments. The url argument must be a full url including protocol and
1028 can only be combined with status.
1029
1030 =cut
1031
1032 sub redirect_request {
1033   die "redirect_request is a virtual method. Do not use Maypole directly; use Apache::MVC or similar";
1034 }
1035
1036 =item redirect_internal_request 
1037
1038 =cut
1039
1040 sub redirect_internal_request {
1041
1042 }
1043
1044
1045 =item make_random_id
1046
1047 returns a unique id for this request can be used to prevent or detect repeat
1048 submissions.
1049
1050 =cut
1051
1052 # Session and Repeat Submission Handling
1053 sub make_random_id {
1054     use Maypole::Session;
1055     return Maypole::Session::generate_unique_id();
1056 }
1057
1058 =back
1059
1060 =head1 SEE ALSO
1061
1062 There's more documentation, examples, and a information on our mailing lists
1063 at the Maypole web site:
1064
1065 L<http://maypole.perl.org/>
1066
1067 L<Maypole::Application>, L<Apache::MVC>, L<CGI::Maypole>.
1068
1069 =head1 AUTHOR
1070
1071 Maypole is currently maintained by Aaron Trevena
1072
1073 =head1 AUTHOR EMERITUS
1074
1075 Simon Cozens, C<simon#cpan.org>
1076
1077 Sebastian Riedel, C<sri#oook.de> maintained Maypole from 1.99_01 to 2.04
1078
1079 =head1 THANKS TO
1080
1081 Sebastian Riedel, Danijel Milicevic, Dave Slack, Jesse Sheidlower, Jody Belka,
1082 Marcus Ramberg, Mickael Joanne, Randal Schwartz, Simon Flack, Steve Simms,
1083 Veljko Vidovic and all the others who've helped.
1084
1085 =head1 LICENSE
1086
1087 You may distribute this code under the same terms as Perl itself.
1088
1089 =cut
1090
1091 1;