published on in web tech php

Introducing PISS, a PHP KISS static page generator

There are lots of static page generators, I personally used Hugo and there like 100 others. But I had a project where I wanted something even simpler, and had a few requirements. I wanted to

  1. Write raw HTML/CSS
  2. Update things in one place only (e.g. don’t copy paste the menu to each html file).

For 1, you don’t need anything other than an editor. 2 is where you need something more than HTML.

I recently came across a project that promised to do more or less exactly what I wanted, xm

But it was written in node/javascript, so I went to look for something else.1

After not finding anything similar, I decided to to do it myself in the 4th most dislike programming language, PHP.

PHP is ubiquitous on Linux servers, and it’s great at generating HTML. The downside for using it as a static page generator is… that it’s not static.

Each time you request a .php page, php will compile and interpret the code and return the output.

The first and obvious solution is to just store the output as html, and you turned it in to a static page generator. Like so

php page.php > page.html

This might get tedious though, and although you can just do a build system which does it, I got curious if it would be possible to do it “on-demand”.

And as a challenge to myself, I wanted to see if it would be possible if I could make it small enough to fit in a tweet2 and without any other dependencies than PHP.

And without further ado, I present to you,

PHP keep It Stupid Simple, in short PISS.

<?php
ob_start(
    function($output) {
        $t = substr(__FILE__, 0, -4) . '.html';
        ($f = fopen($t, 'w')) || header("HTTP/1.1 500") && exit(1);
        fwrite($f, $output);
        header("Location: " . substr($_SERVER['REQUEST_URI'], 0, -4 ) . ".html");
    }
);
?>

Because this is a Real-Serious-Project™ it’s available on GitHub with an issue tracker and all other features that a Real-Serious-Project™ needs.


  1. Mostly because I am not familiar with node/js, but also because xm had 125 dependencies so it failed my requirement of keeping it simple. [return]
  2. The modern variant of 280 characters, not 140, I’m not that good at this. [return]