4 use warnings FATAL => 'all';
8 warnings->import(FATAL => 'all');
9 warnings->unimport('syntax');
10 warnings->import(FATAL => qw(
11 ambiguous bareword digit parenthesis precedence printf
12 prototype qw reserved semicolon
14 my ($class, $app_package) = @_;
15 $class->_export_into($app_package);
19 my ($class, $app_package) = @_;
22 *{"${app_package}::dispatch"} = sub {
23 $app_package->_setup_dispatchables(@_);
25 *{"${app_package}::filter_response"} = sub (&) {
26 $app_package->_construct_response_filter($_[0]);
28 *{"${app_package}::redispatch_to"} = sub {
29 $app_package->_construct_redispatch($_[0]);
31 *{"${app_package}::default_config"} = sub {
33 *{"${app_package}::_default_config"} = sub { @defaults };
35 *{"${app_package}::self"} = \${"${app_package}::self"};
36 require Web::Simple::Application;
37 unshift(@{"${app_package}::ISA"}, 'Web::Simple::Application');
43 Web::Simple - A quick and easy way to build simple web applications
47 This is really quite new. If you're reading this from git, it means it's
48 really really new and we're still playing with things. If you're reading
49 this on CPAN, it means the stuff that's here we're probably happy with. But
50 only probably. So we may have to change stuff.
52 If we do find we have to change stuff we'll add a section explaining how to
53 switch your code across to the new version, and we'll do our best to make it
54 as painless as possible because we've got Web::Simple applications too. But
55 we can't promise not to change things at all. Not yet. Sorry.
61 use Web::Simple 'HelloWorld';
68 [ 200, [ 'Content-type', 'text/plain' ], [ 'Hello world!' ] ]
71 [ 405, [ 'Content-type', 'text/plain' ], [ 'Method not allowed' ] ]
76 HelloWorld->run_if_script;
78 If you save this file into your cgi-bin as hello-world.cgi and then visit
80 http://my.server.name/cgi-bin/hello-world.cgi/
82 you'll get the "Hello world!" string output to your browser. For more complex
83 examples and non-CGI deployment, see below.
87 While I originally wrote Web::Simple as part of my Antiquated Perl talk for
88 Italian Perl Workshop 2009, I've found that having a bare minimum system for
89 writing web applications that doesn't drive me insane is rather nice.
91 The philosophy of Web::Simple is to keep to an absolute bare minimum, for
92 everything. It is not designed to be used for large scale applications;
93 the L<Catalyst> web framework already works very nicely for that and is
94 a far more mature, well supported piece of software.
96 However, if you have an application that only does a couple of things, and
97 want to not have to think about complexities of deployment, then Web::Simple
98 might be just the thing for you.
100 The Antiquated Perl talk can be found at L<http://www.shadowcat.co.uk/archive/conference-video/>.
104 The only public interface the Web::Simple module itself provides is an
107 use Web::Simple 'NameOfApplication';
109 This imports 'strict' and 'warnings FATAL => "all"' into your code as well,
110 so you can skip the usual
115 provided you 'use Web::Simple' at the top of the file. Note that we turn
116 on *fatal* warnings so if you have any warnings at any point from the file
117 that you did 'use Web::Simple' in, then your application will die. This is,
118 so far, considered a feature.
120 Calling the import also makes NameOfApplication isa Web::Simple::Application
121 - i.e. does the equivalent of
124 package NameOfApplication;
125 use base qw(Web::Simple::Application);
128 It also exports the following subroutines:
135 dispatch [ sub (...) { ... }, ... ];
137 filter_response { ... };
139 redispatch_to '/somewhere';
141 and creates the $self global variable in your application package, so you can
142 use $self in dispatch subs without violating strict (Web::Simple::Application
143 arranges for dispatch subroutines to have the correct $self in scope when
146 =head1 EXPORTED SUBROUTINES
148 =head2 default_config
152 another_key => 'bar',
157 $self->config->{one_key} # 'foo'
159 This creates the default configuration for the application, by creating a
161 sub _default_config {
162 return (one_key => 'foo', another_key => 'bar');
165 in the application namespace when executed. Note that this means that
166 you should only run default_config once - a second run will cause a warning
167 that you are override the _default_config method in your application, which
168 under Web::Simple will of course be fatal.
174 [ 200, [ 'Content-type', 'text/plain' ], [ 'Hello world!' ] ]
177 [ 405, [ 'Content-type', 'text/plain' ], [ 'Method not allowed' ] ]
181 The dispatch subroutine calls NameOfApplication->_setup_dispatchables with
182 the subroutines passed to it, which then create's your Web::Simple
183 application's dispatcher from these subs. The prototype of the subroutine
184 is expected to be a Web::Simple dispatch specification (see
185 L</DISPATCH SPECIFICATIONS> below for more details), and the body of the
186 subroutine is the code to execute if the specification matches. See
187 L</DISPATCH STRATEGY> below for details on how the Web::Simple dispatch
188 system uses the return values of these subroutines to determine how to
189 continue, alter or abort dispatch.
191 Note that _setup_dispatchables creates a
194 return (<dispatchable objects here>);
197 method in your class so as with default_config, calling dispatch a second time
198 will result in a fatal warning from your application.
200 =head2 response_filter
203 # Hide errors from the user because we hates them, preciousss
204 if (ref($_[1]) eq 'ARRAY' && $_[1]->[0] == 500) {
205 $_[1] = [ 200, @{$_[1]}[1..$#{$_[1]}] ];
210 The response_filter subroutine is designed for use inside dispatch subroutines.
212 It creates and returns a response filter object to the dispatcher,
213 encapsulating the block passed to it as the filter routine to call. See
214 L</DISPATCH STRATEGY> below for how a response filter affects dispatch.
216 =head1 DISPATCH STRATEGY
218 =head2 Description of the dispatcher object
220 Web::Simple::Dispatcher objects have three components:
224 =item * match - an optional test if this dispatcher matches the request
226 =item * call - a routine to call if this dispatcher matches (or has no match)
228 =item * next - the next dispatcher to call
232 When a dispatcher is invoked, it checks its match routine against the
233 request environment. The match routine may provide alterations to the
234 request as a result of matching, and/or arguments for the call routine.
236 If no match routine has been provided then Web::Simple treats this as
237 a success, and supplies the request environment to the call routine as
240 Given a successful match, the call routine is now invoked in list context
241 with any arguments given to the original dispatch, plus any arguments
242 provided by the match result.
244 If this routine returns (), Web::Simple treats this identically to a failure
247 If this routine returns a Web::Simple::Dispatcher, the environment changes
248 are merged into the environment and the new dispatcher's next pointer is
249 set to our next pointer.
251 If this routine returns anything else, that is treated as the end of dispatch
252 and the value is returned.
254 On a failed match, Web::Simple invokes the next dispatcher with the same
255 arguments and request environment passed to the current one. On a successful
256 match that returned a new dispatcher, Web::Simple invokes the new dispatcher
257 with the same arguments but the modified request environment.
259 =head2 How Web::Simple builds dispatcher objects for you
261 In the case of the Web::Simple L</dispatch> export the match is constructed
262 from the subroutine prototype - i.e.
264 sub (<match specification>) {
268 and the 'next' pointer is populated with the next element of the array,
269 expect for the last element, which is given a next that will throw a 500
270 error if none of your dispatchers match. If you want to provide something
271 else as a default, a routine with no match specification always matches, so -
274 [ 404, [ 'Content-type', 'text/plain' ], [ 'Error: Not Found' ] ]
277 will produce a 404 result instead of a 500 by default. You can also override
278 the L<Web::Simple::Application/_build_final_dispatcher> method in your app.
280 Note that the code in the subroutine is executed as a -method- on your
281 application object, so if your match specification provides arguments you
282 should unpack them like so:
284 sub (<match specification>) {
285 my ($self, @args) = @_;
289 =head2 Web::Simple match specifications
291 =head3 Method matches
295 A match specification beginning with a capital letter matches HTTP requests
296 with that request method.
302 A match specification beginning with a / is a path match. In the simplest
303 case it matches a specific path. To match a path with a wildcard part, you
307 $self->handle_user($_[1])
309 This will match /user/<anything> where <anything> does not include a literal
310 / character. The matched part becomes part of the match arguments. You can
311 also match more than one part:
314 my ($self, $user_1, $user_2) = @_;
316 sub (/domain/*/user/*) {
317 my ($self, $domain, $user) = @_;
319 and so on. To match an arbitrary number of parts, use -
323 This will result in an element per /-separated part so matched. Note that
326 sub (/page/**/edit) {
328 to match an arbitrary number of parts up to but not including some final
331 =head3 Extension matches
335 will match and strip .html from the path (assuming the subroutine itself
336 returns something, of course). This is normally used for rendering - e.g.
339 filter_response { $self->render_html($_[1]) }
342 =head3 Combining matches
344 Matches may be combined with the + character - e.g.
348 Note that for legibility you are permitted to use whitespace -
352 but it will be ignored.