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');
39 (my $name = $app_package) =~ s/::/\//g;
40 $INC{"${name}.pm"} = 'Set by "use Web::Simple;" invocation';
45 Web::Simple - A quick and easy way to build simple web applications
49 This is really quite new. If you're reading this from git, it means it's
50 really really new and we're still playing with things. If you're reading
51 this on CPAN, it means the stuff that's here we're probably happy with. But
52 only probably. So we may have to change stuff.
54 If we do find we have to change stuff we'll add a section explaining how to
55 switch your code across to the new version, and we'll do our best to make it
56 as painless as possible because we've got Web::Simple applications too. But
57 we can't promise not to change things at all. Not yet. Sorry.
63 use Web::Simple 'HelloWorld';
70 [ 200, [ 'Content-type', 'text/plain' ], [ 'Hello world!' ] ]
73 [ 405, [ 'Content-type', 'text/plain' ], [ 'Method not allowed' ] ]
78 HelloWorld->run_if_script;
80 If you save this file into your cgi-bin as hello-world.cgi and then visit
82 http://my.server.name/cgi-bin/hello-world.cgi/
84 you'll get the "Hello world!" string output to your browser. For more complex
85 examples and non-CGI deployment, see below.
89 While I originally wrote Web::Simple as part of my Antiquated Perl talk for
90 Italian Perl Workshop 2009, I've found that having a bare minimum system for
91 writing web applications that doesn't drive me insane is rather nice.
93 The philosophy of Web::Simple is to keep to an absolute bare minimum, for
94 everything. It is not designed to be used for large scale applications;
95 the L<Catalyst> web framework already works very nicely for that and is
96 a far more mature, well supported piece of software.
98 However, if you have an application that only does a couple of things, and
99 want to not have to think about complexities of deployment, then Web::Simple
100 might be just the thing for you.
102 The Antiquated Perl talk can be found at L<http://www.shadowcat.co.uk/archive/conference-video/>.
106 The only public interface the Web::Simple module itself provides is an
109 use Web::Simple 'NameOfApplication';
111 This imports 'strict' and 'warnings FATAL => "all"' into your code as well,
112 so you can skip the usual
117 provided you 'use Web::Simple' at the top of the file. Note that we turn
118 on *fatal* warnings so if you have any warnings at any point from the file
119 that you did 'use Web::Simple' in, then your application will die. This is,
120 so far, considered a feature.
122 Calling the import also makes NameOfApplication isa Web::Simple::Application
123 - i.e. does the equivalent of
126 package NameOfApplication;
127 use base qw(Web::Simple::Application);
130 It also exports the following subroutines:
137 dispatch [ sub (...) { ... }, ... ];
139 filter_response { ... };
141 redispatch_to '/somewhere';
143 and creates the $self global variable in your application package, so you can
144 use $self in dispatch subs without violating strict (Web::Simple::Application
145 arranges for dispatch subroutines to have the correct $self in scope when
150 $INC{"NameOfApplication.pm"} = 'Set by "use Web::Simple;" invocation';
152 so that perl will not attempt to load the application again even if
154 require NameOfApplication;
156 is encountered in other code.
158 =head1 EXPORTED SUBROUTINES
160 =head2 default_config
164 another_key => 'bar',
169 $self->config->{one_key} # 'foo'
171 This creates the default configuration for the application, by creating a
173 sub _default_config {
174 return (one_key => 'foo', another_key => 'bar');
177 in the application namespace when executed. Note that this means that
178 you should only run default_config once - a second run will cause a warning
179 that you are override the _default_config method in your application, which
180 under Web::Simple will of course be fatal.
186 [ 200, [ 'Content-type', 'text/plain' ], [ 'Hello world!' ] ]
189 [ 405, [ 'Content-type', 'text/plain' ], [ 'Method not allowed' ] ]
193 The dispatch subroutine calls NameOfApplication->_setup_dispatchables with
194 the subroutines passed to it, which then create's your Web::Simple
195 application's dispatcher from these subs. The prototype of the subroutine
196 is expected to be a Web::Simple dispatch specification (see
197 L</DISPATCH SPECIFICATIONS> below for more details), and the body of the
198 subroutine is the code to execute if the specification matches. See
199 L</DISPATCH STRATEGY> below for details on how the Web::Simple dispatch
200 system uses the return values of these subroutines to determine how to
201 continue, alter or abort dispatch.
203 Note that _setup_dispatchables creates a
206 return (<dispatchable objects here>);
209 method in your class so as with default_config, calling dispatch a second time
210 will result in a fatal warning from your application.
212 =head2 response_filter
215 # Hide errors from the user because we hates them, preciousss
216 if (ref($_[1]) eq 'ARRAY' && $_[1]->[0] == 500) {
217 $_[1] = [ 200, @{$_[1]}[1..$#{$_[1]}] ];
222 The response_filter subroutine is designed for use inside dispatch subroutines.
224 It creates and returns a response filter object to the dispatcher,
225 encapsulating the block passed to it as the filter routine to call. See
226 L</DISPATCH STRATEGY> below for how a response filter affects dispatch.
228 =head1 DISPATCH STRATEGY
230 =head2 Description of the dispatcher object
232 Web::Simple::Dispatcher objects have three components:
236 =item * match - an optional test if this dispatcher matches the request
238 =item * call - a routine to call if this dispatcher matches (or has no match)
240 =item * next - the next dispatcher to call
244 When a dispatcher is invoked, it checks its match routine against the
245 request environment. The match routine may provide alterations to the
246 request as a result of matching, and/or arguments for the call routine.
248 If no match routine has been provided then Web::Simple treats this as
249 a success, and supplies the request environment to the call routine as
252 Given a successful match, the call routine is now invoked in list context
253 with any arguments given to the original dispatch, plus any arguments
254 provided by the match result.
256 If this routine returns (), Web::Simple treats this identically to a failure
259 If this routine returns a Web::Simple::Dispatcher, the environment changes
260 are merged into the environment and the new dispatcher's next pointer is
261 set to our next pointer.
263 If this routine returns anything else, that is treated as the end of dispatch
264 and the value is returned.
266 On a failed match, Web::Simple invokes the next dispatcher with the same
267 arguments and request environment passed to the current one. On a successful
268 match that returned a new dispatcher, Web::Simple invokes the new dispatcher
269 with the same arguments but the modified request environment.
271 =head2 How Web::Simple builds dispatcher objects for you
273 In the case of the Web::Simple L</dispatch> export the match is constructed
274 from the subroutine prototype - i.e.
276 sub (<match specification>) {
280 and the 'next' pointer is populated with the next element of the array,
281 expect for the last element, which is given a next that will throw a 500
282 error if none of your dispatchers match. If you want to provide something
283 else as a default, a routine with no match specification always matches, so -
286 [ 404, [ 'Content-type', 'text/plain' ], [ 'Error: Not Found' ] ]
289 will produce a 404 result instead of a 500 by default. You can also override
290 the L<Web::Simple::Application/_build_final_dispatcher> method in your app.
292 Note that the code in the subroutine is executed as a -method- on your
293 application object, so if your match specification provides arguments you
294 should unpack them like so:
296 sub (<match specification>) {
297 my ($self, @args) = @_;
301 =head2 Web::Simple match specifications
303 =head3 Method matches
307 A match specification beginning with a capital letter matches HTTP requests
308 with that request method.
314 A match specification beginning with a / is a path match. In the simplest
315 case it matches a specific path. To match a path with a wildcard part, you
319 $self->handle_user($_[1])
321 This will match /user/<anything> where <anything> does not include a literal
322 / character. The matched part becomes part of the match arguments. You can
323 also match more than one part:
326 my ($self, $user_1, $user_2) = @_;
328 sub (/domain/*/user/*) {
329 my ($self, $domain, $user) = @_;
331 and so on. To match an arbitrary number of parts, use -
335 This will result in an element per /-separated part so matched. Note that
338 sub (/page/**/edit) {
340 to match an arbitrary number of parts up to but not including some final
343 =head3 Extension matches
347 will match and strip .html from the path (assuming the subroutine itself
348 returns something, of course). This is normally used for rendering - e.g.
351 filter_response { $self->render_html($_[1]) }
354 =head3 Combining matches
356 Matches may be combined with the + character - e.g.
360 Note that for legibility you are permitted to use whitespace -
364 but it will be ignored.