Plack Middleware for your iPhone

I started playing with HTML5 iPhone apps this week, and as a result there is a new piece of Plack middleware sitting on CPAN called Plack::Middleware::iPhone. It’s a (borderline ACME) module that rewrites html on the fly to make it play nicer with iPhones.

Here’s a silly example:


# A Perl one-liner for the iPhone generation
plackup -MPlack::App::Directory -e 'builder {enable iPhone; Plack::App::Directory->new}'

That makes your current directory browsable as a web app, with some special iPhone meta tags injected so that the viewport is appropriately resized & fullscreen mode is enabled when you launch your “app” from your Home Screen.

Here’s a slightly more usable one – your own personal mobile.search.cpan.org:


plackup -MPlack::App::Proxy -e 'builder {enable iPhone; Plack::App::Proxy->new(remote => "http://search.cpan.org/") }'

You can customise things too:

# app.psgi
use Plack::Builder;
use Plack::App::Proxy;
builder {
    enable "iPhone",
        statusbar => 'black-translucent', # transparent status bar
        startup_image => 'loading.png', # displayed as the app loads
        icon => 'icon.png'; # cutom app shortcut icon
    Plack::App::Proxy->new(remote => "http://search.cpan.org/");
};

Here’s an actual app that I have running on my phone to display the New York subway map (images courtesy of the MTA website):

<!-- index.html -->
<html>
    <head>
        <title>NYC Map</title>
        <style>
            body, img { margin: 0; padding: 0; }
        </style>
    </head>
    <body>
        <script>
            window.scrollTo(300, 700); // Initially zoom in on my local area
        </script>
        <img src="sub1a.gif">
        <img src="sub2a.gif">
    </body>
</html>
# app.psgi
use Plack::App::Directory;
builder {
    enable "iPhone",
        icon => 'icon.png',
        manifest => 1,
        viewport => 'initial-scale = 1, maximum-scale = 1.5, width = device-width',
        statusbar => 'black-translucent',
        startup_image => 'loading.png';
    Plack::App::Directory->new;
};

Use plackup to run the site on your local network, connect via Safari on your iPhone (via wifi) and then use the “Add to Home Screen” option to add an app shortcut to it on your phone. Your 57×57 icon.png image will be used as the app icon, and your 320×460 loading image will appear as the app loads. The viewport string sets the initial zoom scale and limits how far in the user can zoom. Nice and shiny.

With the manifest option enabled, Plack::Middleware::iPhone automatically generates a manifest file and injects the appropriate html to enable HTML5 offline web app caching on your iPhone. This means that your app keeps working once you Ctrl-C the plackup server and walk out your front door. And it keeps on working when you’re stuck in the New York subway system without phone reception, trying to figure out what train you’re supposed to catch to get home.

If you’ve just started exploring how to build iPhone apps with web technologies, I suggest you check out Jonathan Stark’s book “Building iPhone Apps with HTML, CSS, and JavaScript” (online here).

PerlSharedHosting

Latest Web::Simple master (git://git.shadowcat.co.uk/catagits/Web-Simple.git) is now using Plack, the perl web server directly for CGI and FastCGI and I hope do do another release shortly with notes on deploying as both on shared hosts (more specifically Dreamhost but with an invitation to bitch if they don’t work on other budget hosts).

mst,  ”Oh Subdispatch, Oh Subdispatch

Every time someone mentions a cool new web framework like Web::Simple, Dancer or Tatsumaki, my immediate reaction is to start thinking up cool little niche web apps I could build with it. You know, the kind you imagine yourself whipping up during your lunch break, that will probably never get more than 10 curious users but just might turn into the next big thing if only you got it up and running on a public server. And that’s when the second thought immediately arrives: where am I going to run this thing? Do I really think the idea has enough legs to justify paying for a virtual server plan? Can I be bothered going through the pain of figuring out how to deploy it on a shared hosting provider? And normally that’s the point where I sigh wistfully and go back to reading my RSS feeds.

The thing is, with the advent of things like local::lib it’s getting a lot easier to deploy Perl web apps on shared hosting. And with most web frameworks adopting Plack/PSGI, the work required to deploy Perl web apps on budget hosts is converging into a similar sequence of steps.

So this time during my lunch break I started envisaging a centralised, SEO-friendly information source (hello perlsharedhosting.com) that cobbles together all of the currently available information into an easy to digest form to make it ridiculously easy to choose a shared hosting provider, deploy your web app and troubleshoot common problems.

A site that works like this:

  • The front page contains a list of Perl-friendly hosting providers, with a meta-score based on how many features they support (+) and how many unresolved issues they have (-), and maybe user review scores thrown into the mix too
  • Each hosting provider has a page of its own, listing in full which features are supported (used to compute the meta-score). Users can post comments on each of these pages, to leave testimonials (“I am currently running a Web::Simple site that gets x hits per hour on this host”) and note unresolved issues (“module X::Y fails to install on this host”). As issues get solved these become tips.
  • Each technology/feature/technique also gets a page of its own, with links to the official man pages, shared-hosting specific notes and again user comments

I haven’t decided yet what engine would fit best.. MojoMojo is a front-runner, and in fact the Catalyst Friendly Hosting page runs on MojoMojo does a large chunk of what I’ve described above.

The site would be very “cookbook” oriented, since we’re specifically targeting people who can’t be bothered learning the ins and outs of 10 different technologies (not to mention figuring out how to get them to play nicely together) for the sake of deploying toy web applications on cheap shared hosting. Just the essentials: this is what you need, this is how you achieve it. And if you want to learn more, go here.

With that in place, we’d end up with a single, visible, place to research and document the complications of running Perl web apps on shared hosting. And if the site became popular, hosting providers might even take notice and start offering more Perl-friendly shared environments. We could have live demo pages running on different hosts, possibly even donated by hosting providers if they see it as a way of showcasing their Perl-friendliness (mojomojo.dreamhost.perlsharedhosting.com, dancer.resellerzoom.perlsharedhosting.com, etc..).

I got as far as registering the domain name; I was planning on getting a simple MojoMojo prototype up and running, but I got side-tracked researching how to deploy it on my shared hosting account…

Padre::Plugin::Plack

In conjunction with today’s Christmas release of Padre, I’d like to announce my latest Padre plugin: Padre::Plugin::Plack.

As the name suggests, Padre::Plugin::Plack adds Plack awareness to Padre. With the plugin installed, opening *.psgi files causes some special things to happen. PSGI files are really just ordinary Perl files, so Padre does its normal Perl lexing/syntax highlighting magic on them, but the real fun starts with the Plack-specific features that appear in the per-file graphical plackup control panel that shows up. The panel lets you run your web app in a Plack server at the click of a button, view server output, configure plackup options and launch a web browser on the appropriate port.

The great thing about Plack/PSGI is that unlike my previous plugin (Padre::Plugin::WebGUI) which was specific to a single web app (albeit a big one), this plugin can be used for any web app built in a web framework that supports Plack (Catalyst, CGI::Application, HTTP::Engine, etc..). This potential for cross-framework application is one of the motivating factors that makes developing Plack modules (Middleware etc..) so much fun.

The plugin turns on plackup’s “–reload” option by default, which conveniently causes the plack server to reload every time you modify your source files in Padre. This makes for quite a nice, if somewhat minimal “Plack IDE” experience (this is version 0.01 after all).

The plugin integrates all of the Plack example “dot-psgi” files as templates that can be used to create different types of Plack apps straight from the GUI menu.

The pre-populated list of Plack servers and the simple start/stop button makes for a nice way of exploring the Plack server ecosystem. You can use the other panel options to enter a specific port to run on, toggle auto-start mode and pass additional options to plackup (options that start with “–” are passed through to the backend server).

The output panel is similar to the output panel that Padre normally displays when you execute Perl files, except that you get one panel per .psgi file meaning that you can run multiple plack servers simultaneously and independently view their output. The appropriate panel is automatically selected when you click on the corresponding file tab, and running processes are stopped when you close the tab.

It should be really easy to turn Padre::Plugin::Plack into new plugins that involve the same basic ingredients, namely  a file extension and an external command for running those files, with a per-file panel for command options and output. So I encourage anyone who has a similar plugin in mind to steal liberally from Padre::Plugin::Plack (as I did from Padre::Plugin::Catalyst – thanks garu++). Ruby Rack support comes to mind as a trivial example.

Make Padre your domain-specific IDE today :)

Plack helps with Javascript development too

Today I was debugging a Javascript bug in ExtJS + AIR, and I wanted to check rendering in another browser. I created a static html file with the minimal javascript test case embedded in it, but then realised that I needed to load in the ExtJS files from somewhere. With other JS libraries you can use freely available CDNs for this sort of thing, but because ExtJS has funky ideas about licensing, this isn’t an option. What I needed was a quick and easy way to serve up the ExtJS files, which were sitting in a folder on my computer, over http. This sort of thing happens frequently with custom code too, when you attempt to create a static (minimal test case) version of a live site.

Plack has a really neat solution to this problem.

Following a tip from day #5 of Miyagawa’s Plack advent calendar, serving up the current directory over http is as simple as this Perl one-liner:


$ plackup -MPlack::App::Directory -e 'Plack::App::Directory->new

Plack::Server::Standalone: Accepting connections at http://0:5000/
$ plackup -MPlack::App::Directory -e ‘Plack::App::Directory->new’Plack::Server::Standalone: Accepting connections at http://0:5000/$ plackup -MPlack::App::Directory -e ‘Plack::App::Directory->new’
Plack::Server::Standalone: Accepting connections at http://0:5000/
# Or if you need the files over port 80:
$ sudo plackup -MPlack::App::Directory -e ‘Plack::App::Directory->new’ -p 80
Plack::Server::Standalone: Accepting connections at http://0:80/

Or if you need the files served over port 80:


$ sudo plackup -MPlack::App::Directory -e 'Plack::App::Directory->new' -p 80

Plack::Server::Standalone: Accepting connections at http://0:80/