Perl Web Environment (PWE) About PWE ========================== I created PWE out of frustration with the existing Perl tools for generating Web content, and the non-Perl alternatives (mainly PHP). I feel that PHP does some things right[1] and a great many things wrong; the Perl tools, on the other hand, seem to do as little as possible, which is often what we (programmers) want. However, this has always seemed to me an attempt at minimization in the general problem space, rather than being minimal in the Web problem space. [1]: This is why PWE::Templates look a lot like PHP code. PWE is intended to meet the following criteria: * Have a simple, clean, consistent interface * Automaticaly do common Web tasks * Unless asked not to * Platform independence * Simple URL-to-file mapping * User code should mostly be Perl (Corrolary: If we need to make a new language, make it as small and simple as possible) * Simple includes "easy to type" * For now, this only applies to US-101 keyboards Design goals: simple mapping from request path to exec path static resources minimal directory access control cloakable (configuration option to make language/envorinment undetectable - user won't know server is using Perl/PWE) Other Things Named PWE ========================== Political Warfare Executive (WWII British psy-ops dept.) Pro Wrestling Entertainment Penn West Energy Trust, Calgary, Alberta, Canada (NYSE symbol) Pevek Airport, Russia (IATA code) PWE variables for CGI users =========================== STDIN: Still STDIN, but you probably want query_src('BODY') or post_file() STDOUT: Still STDOUT, but may be buffered STDERR: Prints to webserver's log SERVER_SOFTWARE: $server SERVER_NAME: $url_host GATEWAY_INTERFACE: $PWE::VERSION SERVER_PROTOCOL: $req_proto SERVER_PORT: $url_port REQUEST_METHOD: $req_meth PATH_INFO: $query_path or join '/', @query_path ($query_path might be URL-encoded; @query_path will not be) PATH_TRANSLATED: This variable is experimentally deprecated SCRIPT_NAME: $url_path ($script_path has this script's location in the filesystem) QUERY_STRING: $req_query, but you probably want %query or $query REMOTE_HOST: $client_name REMOTE_ADDR: $client_addr CONTENT_TYPE, CONTENT_LENGTH: these headers are accessed the same as the other HTTP headers HTTP_*: $req_head->get('*') or $req_head{*}; you may want %cookie $query is an HTab of the information in $req_query; %query is a hash tied to the HTab. query_src() can be used to change the data source. $req_head is an HTab of the client's headers; %req_head is tied to it. %cookie contains the data from the client's COOKIE headers Versions ========================== A.BBCC A - major version 0: alpha/beta 1: release 1 etc. No major or compatability-breaking changes are allowed within a major version. B - minor version even: release odd: candidate All changes within a release must be fixes. The candidate before the first release of a major version (e.g., 2.0) is (A-1).99 (e.g., 1.99). The candidate is still part of the major version, although there can still be major changes. C - level release: patch (add 1-digit D level for patch candidates?) candidate: revision (can we autocalc this in SVN repo?) We recommend using only one Perl process(?) # Two so the old one can shut down, but make Apa never want to spawn a second? TEMPLATE TAGS -> PERL # any whitespace character works -> print ARGS; -> if (EXPR) { -> } -> print $var; -> { local $_; for (@var) { -> } } -> { local $_; for (my $_k, $_) (each %var) { -> } } SECTIONS __BODY__ implicit unless -c switch is used __CONF__ implicit if -c switch __END__ $e = sprintf(<(); } } print @strings; } while (@cache) { my $item = pop @cache; if (ref $item eq 'ARRAY') { # we're going to assume the array has all the parts for an object or method call my ($obj, $code, @args) = @$item; if ($obj) { my $meth = shift @$item; push @cache, reverse $obj->$meth(@$item); } else { my $code = shift } push @cache, reverse $item( } } shinju JIS: 3F3F 3C6E Client data: %cq # query %cp # path info %cc # cookies %ch # headers $cb # body %cr ( # raw data req # first line of request q # query c # cookies (still slightly parsed) ) htabs: header tables API (methods) new([htab]) # create an htab (duplicated from an older one, if provided) sub exists { } sub fetch { my ($self, $key) = (shift, shift); if (exists $self->{$key}) { return ${$self->{$key}}[0]; } else { return; } } sub store { my ($self, $key) = (shift, shift); if (exists $self->{$key}) { ${$self->{$key}}[0] = $_[0]; } else { $self->{$key} = [ $_[0] ]; } } sub delete { my ($self, $key) = (shift, shift); if (exists $self->{$key}) { unshift @{$self->{$key}}; delete $self->{$key} unless @{$self->{$key}}; } } sub find { my ($self, $key) = (shift, shift); if (!exists $self->{$key}) { return $self->{$key} = [ ]; } return $self->{$key}; } sub each { my $self = shift; }