ETOOBUSY 🚀 minimal blogging for the impatient
xmpl - the API for browsers
TL;DR
We will take a closer look at the implementation for the API available to the browsers in xmpl. This post is part of a series.
In previous post xmpl - the key/value API we took a look at the basic API provided by xmpl, that is mainly geared at being consumed in a machine to machine way.
An example application, though, is also something useful to look at from
the browser, which means generating HTML pages and leveraging GET
and
POST
methods “only” (at least if we want to avoid using Javascript to
keep things simple).
The GET
verb is addressed by a function that gets all the key/value
pairs as a hash and calls the render
method, which will transform
these data into a page according to the template provided by the
function template_index
:
get '/' => sub ($c) {
my %args = (inline => template_index(), kvstore => kvstore()->origin);
if (! ($args{kv} = eval { kvstore()->as_hash })) {
$args{kv} = {};
$args{error} = 'could not read key/value pairs from store';
}
$c->render(%args);
};
We will not get into the details of the template, you an take a look at it here.
The POST
verb is overloaded with two sub-actions, one for adding (or
modifying) a key/value pair, one for deleting it. This is tracked via
parameter sub-action
:
post '/' => sub ($c) {
eval {
my $sub_action = $c->param('sub-action');
if ($sub_action eq 'delete') {
kvstore()->remove($c->param('key'));
$c->flash(info => 'element removed');
}
else {
kvstore()->set($c->param('key'), $c->param('value'));
$c->flash(info => 'element added');
}
1;
} or $c->flash(error => 'action failed');
$c->redirect_to('/');
};
This always redirects to the GET
, so that we keep it simple.
The last part is the overriding of the favicon.ico
icon, to add some
sugar (the favicon
function can be seen here):
get '/favicon.ico' => sub ($c) {
$c->render(
status => 200,
data => favicon(),
format => 'png',
);
};
Except that… this does not work.
Mojolicious generats a favicon by itself, and the request never gets to hit the route above (which is somehow weird, in my opinion). The solution is to explicitly get rid of the internally generated one:
delete app->static->extra->{'favicon.ico'};
That’s it! An ugly, bare-bones, very 90-esque page that is shown in a real browser!