I made a static site generator in PHP (and it's fast)
Tags: webdev, programming, opensource, php
Published: 2024-01-27 01:15:19

I published an async [Resonance PHP framework](https://github.com/distantmagic/resonance). I decided also to implement a static site generator to create elaborate documentation or static pages:

![Docs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xylfzqyquxf7z89v6hc4.png)


## Why?

I aimed to solve a few issues:
1. I wanted to use something other than Docusaurus because its build times are generally slow: https://github.com/facebook/docusaurus/discussions/3132. I made performance my priority
2. I wanted to use the same tech stack as the core framework, and no major Static Site Generators in PHP were ready to use.
3. I wanted to use something other than React. Instead, I opted for [Stimulus](https://stimulus.hotwired.dev/) + [Turbo](https://turbo.hotwired.dev/), which is a much lighter approach.

## Design Choices

### Front-Matter

I borrowed the idea of [Front-Matter](https://jekyllrb.com/docs/front-matter/) from [Jekyll](https://jekyllrb.com/docs/front-matter/), but I made some adjustments, 

Jekyll's front-matter is pretty loose - you can input any properties you want in [Resonance](https://resonance.distantmagic.com/docs/features/generating-static-sites/). I used a strict validation for the sake of consistency:

```yaml
---
collections: 
    - documents
draft: true
layout: dm:document
parent: docs/features/index
title: Machine Learning
description: >
    Learn how to incorporate Machine Learning features into your application.
---
```

Front matter is used to render metadata like `<meta name="description">` and various hints in the documentation.

### Consistency Above All

It's possible to link documents in a wiki-like fashion by using `{{` and `}}` and pointing to the linked file. For example, if you have a file in `docs/features/test.md,`, you can create an `<a>` link to that file with `{{docs/features/test}}.` All the links are checked while rebuilding the documentation to ensure each is valid.

### Ordering of Documents

Instead of some global index of documents, I ordered them by references. You can use fields like `next` or `parent` in the front matter to order them relatively to each other:

```yaml
---
collections: 
    - documents
layout: dm:document
next: docs/features/asset-bundling-esbuild/preloading-assets
parent: docs/features/asset-bundling-esbuild/index
title: Cache Busting
description: >
    Prevent unwanted caching with esbuild features.
---
```

Thanks to that, maintaining the documentation is more straightforward than maintaining another global list of pages with their ordering rules.

### Custom Layouts

You can create your custom layouts and reference them in the front matter, making it easy to have shared layouts across multiple pages.

### Collections

You can add pages to collections to put them into the site's primary navigation or side menus:

```yaml
---
collections: 
    - documents
    - name: primary_navigation
      next: tutorials/index
description: docs
layout: dm:document
title: Documentation
---
```

## Summary

I hope this generator will be helpful to you. Feel free to reach out if you have any questions, and leave me a star if you would like it. Good luck!

You can find documentation and installation instructions here: https://resonance.distantmagic.com/docs/features/generating-static-sites/