]> git.decadent.org.uk Git - maypole.git/blob - lib/Apache/MVC.pm
added rewrite_path()
[maypole.git] / lib / Apache / MVC.pm
1 package Apache::MVC;
2
3 use strict;
4 use warnings;
5
6 use base 'Maypole';
7 use mod_perl;
8
9 use constant APACHE2 => $mod_perl::VERSION >= 1.99;
10
11 if (APACHE2) {
12     require Apache2;
13     require Apache::RequestRec;
14     require Apache::RequestUtil;
15     require APR::URI;
16 }
17 else { require Apache }
18 require Apache::Request;
19
20 our $VERSION = "0.4";
21
22 sub get_request {
23     my ( $self, $r ) = @_;
24     $self->{ar} = Apache::Request->new($r);
25 }
26
27 sub parse_location {
28     my $self = shift;
29     $self->{path} = $self->{ar}->uri;
30     my $loc = $self->{ar}->location;
31     no warnings 'uninitialized';
32     $self->{path} =~ s/^($loc)?\///;
33     $self->rewrite_path;
34     $self->parse_path;
35     $self->parse_args;
36 }
37
38 sub parse_args {
39     my $self = shift;
40     $self->{params} = { $self->_mod_perl_args( $self->{ar} ) };
41     $self->{query}  = { $self->_mod_perl_args( $self->{ar} ) };
42 }
43
44 sub send_output {
45     my $r = shift;
46     $r->{ar}->content_type(
47         $r->{content_type} . "; encoding=" . $r->{document_encoding} );
48     $r->{ar}->headers_out->set( "Content-Length" => length $r->{output} );
49     APACHE2 || $r->{ar}->send_http_header;
50     $r->{ar}->print( $r->{output} );
51 }
52
53 sub get_template_root {
54     my $r = shift;
55     $r->{ar}->document_root . "/" . $r->{ar}->location;
56 }
57
58 sub _mod_perl_args {
59     my ( $self, $apr ) = @_;
60     my %args;
61     foreach my $key ( $apr->param ) {
62         my @values = $apr->param($key);
63         $args{$key} = @values == 1 ? $values[0] : \@values;
64     }
65     return %args;
66 }
67
68 1;
69
70 =head1 NAME
71
72 Apache::MVC - Apache front-end to Maypole
73
74 =head1 SYNOPSIS
75
76     package BeerDB;
77     use base 'Apache::MVC';
78     BeerDB->setup("dbi:mysql:beerdb");
79     BeerDB->config->uri_base("http://your.site/");
80     BeerDB->config->display_tables([qw[beer brewery pub style]]);
81     # Now set up your database:
82     # has-a relationships
83     # untaint columns
84
85     1;
86
87 =head1 DESCRIPTION
88
89 Maypole is a Perl web application framework to Java's struts. It is 
90 essentially completely abstracted, and so doesn't know anything about
91 how to talk to the outside world. C<Apache::MVC> is a mod_perl based
92 subclass of Maypole.
93
94 To use it, you need to create a package which represents your entire
95 application. In our example above, this is the C<BeerDB> package.
96
97 This needs to first inherit from C<Apache::MVC>, and then call setup.
98 This will give your package an Apache-compatible C<handler> subroutine,
99 and then pass any parameters onto the C<setup_database> method of the
100 model class. The default model class for Maypole uses L<Class::DBI> to 
101 map a database to classes, but this can be changed by messing with the
102 configuration. (B<Before> calling setup.)
103
104 Next, you should configure your application through the C<config>
105 method. Configuration parameters at present are:
106
107 =over
108
109 =item uri_base
110
111 You B<must> specify this; it is the base URI of the application, which
112 will be used to construct links.
113
114 =item display_tables
115
116 If you do not want all of the tables in the database to be accessible,
117 then set this to a list of only the ones you want to display
118
119 =item rows_per_page
120
121 List output is paged if you set this to a positive number of rows.
122
123 =back
124
125 You should also set up relationships between your classes, such that,
126 for instance, calling C<brewery> on a C<BeerDB::Beer> object returns an
127 object representing its associated brewery.
128
129 For a full example, see the included "beer database" application.
130
131 =head1 INSTALLATION
132
133 Create a driver module like the one above.
134
135 Put the following in your Apache config:
136
137     <Location /beer>
138         SetHandler perl-script
139         PerlHandler BeerDB
140     </Location>
141
142 Copy the templates found in F<templates/factory> into the
143 F<beer/factory> directory off the web root. When the designers get
144 back to you with custom templates, they are to go in
145 F<beer/custom>. If you need to do override templates on a
146 database-table-by-table basis, put the new template in
147 F<beer/I<table>>. 
148
149 This will automatically give you C<add>, C<edit>, C<list>, C<view> and
150 C<delete> commands; for instance, a list of breweries, go to 
151
152     http://your.site/beer/brewery/list
153
154 For more information about how the system works and how to extend it,
155 see L<Maypole>.
156
157 =head1 AUTHOR
158
159 Simon Cozens, C<simon@cpan.org>
160 Marcus Ramberg, C<marcus@thefeed.no>
161 Screwed up by Sebastian Riedel, C<sri@oook.de>
162
163 =head1 LICENSE
164
165 You may distribute this code under the same terms as Perl itself.