X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=doc%2FRequest.pod;h=fc51d1ba854ea87900250ce5a6f90d83bf96e602;hb=43d50fc6cf12e98c44f485eea46ac35637dcce06;hp=1505d361d9a014b2f0c058e4e9c3f64b7676fb0e;hpb=673e706b0cda16b4dea71d8fe7c430e4e29d78ac;p=maypole.git diff --git a/doc/Request.pod b/doc/Request.pod index 1505d36..fc51d1b 100644 --- a/doc/Request.pod +++ b/doc/Request.pod @@ -40,9 +40,70 @@ You can also use the C module programatically to create test suites for your application. See the Maypole tests themselves or the documentation to C for examples of this. -=head3 Changing how params are parsed +=head3 Changing how URLs are parsed + +You don't like the way Maypole URLs look, and want something that either +fits in with the rest of your site or hides the internal workings of the +system. + +C: So far we've been using the C form +of a URL as though it was "the Maypole way"; well, there is no Maypole +way. Maypole is just a framework and absolutely everything about it is +overridable. + +If we want to provide our own URL handling, the method to override in +the driver class is C. This is responsible for taking +C<$r-E{path}> and filling the C, C and C slots +of the request object. Normally it does this just by splitting the path +on Cs, but you can do it any way you want, including getting the +information from C form parameters or session variables. + +For instance, suppose we want our URLs to be of the form +C, we could provide a C method +like so: + + sub parse_path { + my $r = shift; + $r->{path} ||= "ProductList.html"; + ($r->{table}, $r->{action}) = + ($r->{path} =~ /^(.*?)([A-Z]\w+)\.html/); + $r->{table} = lc $r->{table}; + $r->{action} = lc $r->{action}; + my %query = $r->{ar}->args; + $self->{args} = [ $query{id} ]; + } -=head3 REST +This takes the path, which already has the query parameters stripped off +and parsed, and finds the table and action portions of the filename, +lower-cases them, and then grabs the C from the query. Later methods +will confirm whether or not these tables and actions exist. + +See L for another example of custom URL processing. + +=head3 Maypole for mobile devices + +You want Maypole to use different templates to display on particular +browsers. + +B: There are several ways to do this, but here's the neatest +we've found. Maypole chooses where to get its templates either by +looking at the C config parameter or, if this is not +given, calling the C method to ask the front-end to +try to work it out. We can give the front-end a little bit of help, by +putting this method in our driver class: + + sub get_template_root { + my $r = shift; + my $browser = $r->{ar}->headers_in->get('User-Agent'); + if ($browser =~ /mobile|palm|nokia/i) { + "/home/myapp/templates/mobile"; + } else { + "/home/myapp/templates/desktop"; + } + } + +(Maybe there's a better way to detect a mobile browser, but you get the +idea.) =head2 Content display hacks @@ -99,10 +160,6 @@ a user's page. This hack is so common that it's expected that there'll be a neater way of doing this in the future. -=head3 Maypole for mobile devices - -XXX - =head3 XSLT Here's a hack I've used a number of times. You want to store structured @@ -194,6 +251,47 @@ itself; if your file is stored in the filesystem, but you have a file name or some other pointer in the database, you can still arrange for the data to be fetched and inserted into C<$r-E{output}>. +=head3 REST + +You want to provide a programmatic interface to your Maypole site. + +B: The best way to do this is with C, which uses a +descriptive URL to encode the request. For instance, in L we +describe a social networking system. One neat thing you can do with +social networks is to use them for reputation tracking, and we can use +that information for spam detection. So if a message arrives from +C, we want to know if they're in our network of +friends or not and mark the message appropriately. We'll do this by +having a web agent (say, L or L) request +a URL of the form +C. +Naturally, they'll need to present the appropriate cookie just like a +normal browser, but that's a solved problem. We're just interested in +the REST request. + +The request will return a single integer status code: 0 if they're not +in the system at all, 1 if they're in the system, and 2 if they're our +friend. + +All we need to do to implement this is provide the C +action, and use it to fill in the output in the same way as we did when +displaying a picture. Since C is not the ID of a +row in the user table, it will appear in the C array: + + use URI::Escape; + sub relationship_by_email :Exported { + my ($self, $r) = @_; + my $email = uri_unescape($r->{args}[0]); + $r->{content_type} = "text/plain"; + my $user; + unless (($user) = Flox::User->search(email => $email)) { + $r->{content} = "0\n"; return; + } + + if ($r->{user}->is_friend($user)) { $r->{content} = "2\n"; return; }; + $r->{content} = "1\n"; return; + } + =head3 Component-based Pages You're designing something like a portal site which has a number of