Things all developers need to make in their career #17: A static site generator

There’s a sort-of-joke that there’s a bunch of things that all developers are supposed to code from scratch at some point in their career. A blog. A to-do list app. The “canonical” applications. And one of these is a static site generator.

I’ve actually never built any of these things from scratch. But while making Turbo Admin I wanted to make a really simple landing page. I wanted to use TailwindCSS, because I can work quickly with that and use TailwindUI. And to use Tailwind properly you kinda need to have “components”, or at least “template partials”.

So I kinda needed a way to do “HTML includes”. Which is a thing that doesn’t exist.

I put the feelers out for a SUPER simple solution for doing this. Ideally I wanted to avoid a huge node_modules folder, and a tool that would at some point require me to downgrade node by three versions just to update a CSS class or change a hyperlink.

Responses to this were:

  • FlightPHP – Micro-framework. Does routing, but not static output. via Ben Gilbanks.
  • The Gulp-only approach – Needs Gulp. Will probably break at some point. Also via Ben Gilbanks.
  • Jekyll – Tried it before. Didn’t like it. Got confused by all the Ruby stuff. Also via Ben Gilbanks.
  • CodeKit – Looks good, but needs CodeKit. ALSO via Ben Gilbanks.
  • 11ty – Which looks awesome but starts with npm install, and then I looked at the docs and was overwhelmed. So big nope. via Pretty Much Everyone Else.
  • Nunjucks – Which is a “a more sophisticated templating engine for JavaScript”, which meets neither my requirement for something super-simple, nor my desire to avoid JavaScript in the build. It probably needs something like Gulp as well. via Richard Bell and Rich Holman.

Then I started to think: “Hang on a minute. This is a basic function of PHP isn’t it? This is just <?php include('some_partial.php') ?>. Can’t I just run PHP on the command line to transform files? I’ll probably have PHP installed forever anyway, and it’s very unlikely to break. Is PHP not the magic I need?”

Scott Edward Carver backed me up: “I sometimes use a build process which runs php files in the root directory, outputs to an .html of the same name”.


Ryan Chandler (who is literally one of the most helpful and prolific people on the PHP internet) then chipped in with: extract($data); include __DIR__.'/path/to/view.php; // ;)

It turns out Ryan has built a quick-and-dirty vanilla-PHP-based static site generator script in the past. He called his Mink, and describes it as: “It’s disgusting really. Using globals, you can only call extend() at the very end of a template file. You have to define the name of a slot in the stop function.” And he says it’s “for educational purposes (obvs)”

But it turns out that while Ryan was trying to find where he had a lefotver copy of this script so I could see it, I was already building something VERY similar.

And, yeah, I guess it is “disgusting”. But it works a charm and totally fulfills my criteria:

  • Super-simple
  • Constraints that I’m 100% happy with
  • Ability to extend a layout template of your choosing, and pass data to it
  • Ability to include partials and pass data to them
  • Ability to have “environment variables”
  • Simple build process
  • Minimal dependencies

I COULD wrap this up in a fancy command line with Laravel Zero or Erika Heidi‘s Mini CLI. But I don’t need to.

I COULD make this a PHP composer-installable package. But why should I?

I’m probably not going to update it. It’s a “finished” piece of software as far as I’m concerned.

It’s unlikely to stop working in the near future.

So let’s keep it REALLY simple. Like I did with Peekobot.

It’s just 160-odd lines of PHP in a Gist:

Take it. Download it. Use it. Modify it. Make it do what YOU need it to do.

Combined with the new TailwindCSS CLI tool, I can now have simple, static sites, with almost-zero-dependency build processes! Amazing.

So yes, I guess I built a static site generator.

Now…what’s next. Todo app?