]> git.decadent.org.uk Git - maypole.git/blob - lib/Maypole.pm
Reorganised pod in Maypole.pm, finished doc roadmap, various minor pod updates, moved...
[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 =item redirect_request
701
702 Sets output headers to redirect based on the arguments provided
703
704 Accepts either a single argument of the full url to redirect to, or a hash of
705 named parameters :
706
707 $r->redirect_request('http://www.example.com/path');
708
709 or
710
711 $r->redirect_request(protocol=>'https', domain=>'www.example.com', path=>'/path/file?arguments', status=>'302', url=>'..');
712
713 The named parameters are protocol, domain, path, status and url
714
715 Only 1 named parameter is required but other than url, they can be combined as
716 required and current values (from the request) will be used in place of any
717 missing arguments. The url argument must be a full url including protocol and
718 can only be combined with status.
719
720 =cut
721
722 sub redirect_request {
723   die "redirect_request is a virtual method. Do not use Maypole directly; use Apache::MVC or similar";
724 }
725
726 =item redirect_internal_request 
727
728 =cut
729
730 sub redirect_internal_request {
731
732 }
733
734 =back
735
736 =head2 Path processing and manipulation
737
738 =over 4
739
740 =item path
741
742 Returns the request path
743
744 =item parse_path
745
746 Parses the request path and sets the C<args>, C<action> and C<table>
747 properties. Calls C<preprocess_path> before parsing path and setting properties.
748
749 =cut
750
751 sub parse_path 
752 {
753     my ($self) = @_;
754     
755     # Previous versions unconditionally set table, action and args to whatever 
756     # was in @pi (or else to defaults, if @pi is empty).
757     # Adding preprocess_path(), and then setting table, action and args 
758     # conditionally, broke lots of tests, hence this:
759     $self->$_(undef) for qw/action table args/;
760     
761     $self->preprocess_path;
762
763     $self->path || $self->path('frontpage');
764     
765     my @pi = grep {length} split '/', $self->path;
766     
767     $self->table  || $self->table(shift @pi);
768     $self->action || $self->action( shift @pi or 'index' );
769     $self->args   || $self->args(\@pi);
770 }
771
772 =item preprocess_path
773
774 Sometimes when you don't want to rewrite or over-ride parse_path but
775 want to rewrite urls or extract data from them before it is parsed.
776
777 This method is called after parse_location has populated the request
778 information and before parse_path has populated the model and action
779 information, and is passed the request object.
780
781 You can set action, args or table in this method and parse_path will
782 then leave those values in place or populate them if not present
783
784 =cut
785
786 sub preprocess_path { };
787
788 =item make_path( %args or \%args or @args )
789
790 This is the counterpart to C<parse_path>. It generates a path to use
791 in links, form actions etc. To implement your own path scheme, just override
792 this method and C<parse_path>.
793
794     %args = ( table      => $table,
795               action     => $action,        
796               additional => $additional,    # optional - generally an object ID
797               );
798               
799     \%args = as above, but a ref
800     
801     @args = ( $table, $action, $additional );   # $additional is optional
802
803 C<id> can be used as an alternative key to C<additional>.
804
805 C<$additional> can be a string, an arrayref, or a hashref. An arrayref is
806 expanded into extra path elements, whereas a hashref is translated into a query
807 string. 
808
809 =cut
810
811 sub make_path
812 {
813     my $r = shift;
814     
815     my %args;
816     
817     if (@_ == 1 and ref $_[0] and ref $_[0] eq 'HASH')
818     {
819         %args = %{$_[0]};
820     }
821     elsif ( @_ > 1 and @_ < 4 )
822     {
823         $args{table}      = shift;
824         $args{action}     = shift;
825         $args{additional} = shift;
826     }
827     else
828     {
829         %args = @_;
830     }
831     
832     do { die "no $_" unless $args{$_} } for qw( table action );    
833
834     my $additional = $args{additional} || $args{id};
835     
836     my @add = ();
837     
838     if ($additional)
839     {
840         # if $additional is a href, make_uri() will transform it into a query
841         @add = (ref $additional eq 'ARRAY') ? @$additional : ($additional);
842     }    
843     
844     my $uri = $r->make_uri($args{table}, $args{action}, @add);
845     
846     return $uri->as_string;
847 }
848
849
850
851 =item make_uri( @segments )
852
853 Make a L<URI> object given table, action etc. Automatically adds
854 the C<uri_base>. 
855
856 If the final element in C<@segments> is a hash ref, C<make_uri> will render it
857 as a query string.
858
859 =cut
860
861 sub make_uri
862 {
863     my ($r, @segments) = @_;
864
865     my $query = (ref $segments[-1] eq 'HASH') ? pop(@segments) : undef;
866     
867     my $base = $r->config->uri_base; 
868     $base =~ s|/$||;
869     
870     my $uri = URI->new($base);
871     $uri->path_segments($uri->path_segments, grep {length} @segments);
872     
873     my $abs_uri = $uri->abs('/');
874     $abs_uri->query_form($query) if $query;
875     return $abs_uri;
876 }
877
878 =item parse_args
879
880 Turns post data and query string paramaters into a hash of C<params>.
881
882 You should only need to define this method if you are writing a new Maypole
883 backend.
884
885 =back
886
887 =head2 Request properties
888
889 =over 4
890
891 =item model_class
892
893 Returns the perl package name that will serve as the model for the
894 request. It corresponds to the request C<table> attribute.
895
896
897 =item objects
898
899 Get/set a list of model objects. The objects will be accessible in the view
900 templates.
901
902 If the first item in C<$self-E<gt>args> can be C<retrieve()>d by the model
903 class, it will be removed from C<args> and the retrieved object will be added to
904 the C<objects> list. See L<Maypole::Model> for more information.
905
906 =item template_args
907
908     $self->template_args->{foo} = 'bar';
909
910 Get/set a hash of template variables.
911
912 =item stash
913
914 A place to put custom application data. Not used by Maypole itself. 
915
916 =item template
917
918 Get/set the template to be used by the view. By default, it returns
919 C<$self-E<gt>action>
920
921
922 =item error
923
924 Get/set a request error
925
926 =item output
927
928 Get/set the response output. This is usually populated by the view class. You
929 can skip view processing by setting the C<output>.
930
931 =item table
932
933 The table part of the Maypole request path
934
935 =item action
936
937 The action part of the Maypole request path
938
939 =item args
940
941 A list of remaining parts of the request path after table and action
942 have been
943 removed
944
945 =item headers_in
946
947 A L<Maypole::Headers> object containing HTTP headers for the request
948
949 =item headers_out
950
951 A L<HTTP::Headers> object that contains HTTP headers for the output
952
953 =item document_encoding
954
955 Get/set the output encoding. Default: utf-8.
956
957 =item content_type
958
959 Get/set the output content type. Default: text/html
960
961 =item get_protocol
962
963 Returns the protocol the request was made with, i.e. https
964
965 =cut
966
967 sub get_protocol {
968   die "get_protocol is a virtual method. Do not use Maypole directly; use Apache::MVC or similar";
969 }
970
971 =back
972
973 =head2 Request parameters
974
975 The source of the parameters may vary depending on the Maypole backend, but they
976 are usually populated from request query string and POST data.
977
978 Maypole supplies several approaches for accessing the request parameters. Note
979 that the current implementation (via a hashref) of C<query> and C<params> is
980 likely to change in a future version of Maypole. So avoid direct access to these
981 hashrefs:
982
983     $r->{params}->{foo}      # bad
984     $r->params->{foo}        # better
985
986     $r->{query}->{foo}       # bad
987     $r->query->{foo}         # better
988
989     $r->param('foo')         # best
990
991 =over 4
992
993 =item param
994
995 An accessor (get or set) for request parameters. It behaves similarly to
996 CGI::param() for accessing CGI parameters, i.e.
997
998     $r->param                   # returns list of keys
999     $r->param($key)             # returns value for $key
1000     $r->param($key => $value)   # returns old value, sets to new value
1001
1002 =cut
1003
1004 sub param 
1005
1006     my ($self, $key) = (shift, shift);
1007     
1008     return keys %{$self->params} unless defined $key;
1009     
1010     return unless exists $self->params->{$key};
1011     
1012     my $val = $self->params->{$key};
1013     
1014     if (@_)
1015     {
1016         my $new_val = shift;
1017         $self->params->{$key} = $new_val;
1018     }
1019     
1020     return ref $val ? @$val : ($val) if wantarray;
1021         
1022     return ref $val ? $val->[0] : $val;
1023 }
1024
1025
1026 =item params
1027
1028 Returns a hashref of request parameters. 
1029
1030 B<Note:> Where muliple values of a parameter were supplied, the C<params> value
1031 will be an array reference.
1032
1033 =item query
1034
1035 Alias for C<params>.
1036
1037 =item make_random_id
1038
1039 returns a unique id for this request can be used to prevent or detect repeat
1040 submissions.
1041
1042 =cut
1043
1044 # Session and Repeat Submission Handling
1045 sub make_random_id {
1046     use Maypole::Session;
1047     return Maypole::Session::generate_unique_id();
1048 }
1049
1050 =back
1051
1052 =head1 SEE ALSO
1053
1054 There's more documentation, examples, and a information on our mailing lists
1055 at the Maypole web site:
1056
1057 L<http://maypole.perl.org/>
1058
1059 L<Maypole::Application>, L<Apache::MVC>, L<CGI::Maypole>.
1060
1061 =head1 AUTHOR
1062
1063 Maypole is currently maintained by Aaron Trevena
1064
1065 =head1 AUTHOR EMERITUS
1066
1067 Simon Cozens, C<simon#cpan.org>
1068
1069 Sebastian Riedel, C<sri#oook.de> maintained Maypole from 1.99_01 to 2.04
1070
1071 =head1 THANKS TO
1072
1073 Sebastian Riedel, Danijel Milicevic, Dave Slack, Jesse Sheidlower, Jody Belka,
1074 Marcus Ramberg, Mickael Joanne, Randal Schwartz, Simon Flack, Steve Simms,
1075 Veljko Vidovic and all the others who've helped.
1076
1077 =head1 LICENSE
1078
1079 You may distribute this code under the same terms as Perl itself.
1080
1081 =cut
1082
1083 1;