Project documentation with Sculpin

Posted on by Matthias Noback

Recently I've been reading the book Living documentation by Cyrille Martraire. I can warmly recommend this book to you. It basically provides a solution for the age-old problem of creating and maintaining accurate, up-to-date and useful project documentation. One of the key ideas is to generate documentation instead of writing it. This should help prevent duplication and outdated information that is not trust-worthy and would therefore be neglected. I'm currently looking for ways to technically accomplish such a thing with PHP projects. This should result in reusable tools which will make it easier and more fun to document future projects while writing the code.

The first thing I was looking for was some kind of framework for any number of tools that would analyze a project and generate a documentation site for it, consisting of diagrams, texts, maps, etc. All in one place, all easily navigable and searchable. I was immediately reminded of Sculpin, a static site generator created by Beau Simensen. I've used it for years as the engine behind this blog. You could say that this blog is a "Sculpin project", which is the standard way to use Sculpin. However, I wanted to use Sculpin to document another project, the main project.

So I started figuring out how to run Sculpin and generate a static subsite (not a blog) based on files in a subdirectory of another project. It wasn't all that hard, but I'll share the steps here anyway.

Use Sculpin to generate a static website in a subdirectory of your project

Run the following commands in the root of the project you're creating a subsite for. Assuming you have the Composer executable available as composer and your project already has a composer.json file, and the files for your subsite should be located in doc/, run:

composer require sculpin/sculpin
mkdir doc
vendor/bin/sculpin generate --project-dir=doc

Define the homepage for the site by creating a new file: doc/source/ Put some minimal Markdown content in it, to test if it works:

title: Home

# Documentation for project X

Before the Markdown content you will find the so-called frontmatter which could contain any relevant metadata. The value of the title key will be available later on when rendering the page as the variable page.title.

Now, run:

vendor/bin/sculpin generate --server --project-dir=doc

In your browser, go to localhost:8000, and you should see the homepage (which shows the parsed version of

From here on, everything is optional and just a suggestion to get started.

Create a new file: app/config/sculpin_site.yml. Now you can configure the title of the site:

# in sculpin_site.yml

title: Documentation for project X

Create a directory doc/source/_layouts. This will contain any layout file for the Twig formatter. Create a default layout in doc/source/_layouts/default.html.twig, something like:

<!DOCTYPE html>
    <title>{{ page.title }} &mdash; {{ site.title }}</title>
    {% block content %}{% endblock %}

You need at least a content block for the content from the page to be rendered.

Now modify the frontmatter of (the part that has Yaml-formatted content in it) to look like this:

layout: default
title: Home

The layout key will cause Sculpin to look for the default.html.twig file.

To preview the generated site, you could run:

vendor/bin/sculpin generate --project-dir=doc --server --watch

Open localhost:8000 again (or refresh the page) and you should see a very simple HTML page (take a look at the page source to find out if the full HTML document has been rendered according to your layout file). The --watch flag is optional and will keep regenerating the site upon file changes (not all of them though; I find myself regularly restarting the server).


Looking at the doc/ directory you can see that we have only a very small amount of files. It should be no problem at all to copy this basic setup into new projects whenever you need a documentation platform.

The files you may want to reuse are layout files and other template-related files, and static assets. You could easily create a reusable (and overridable) package for this. You only need to create a Composer page of type 'sculpin-theme' for it. Take a look at the Bootstrap 3 theme for more clues on how to accomplish this.

Next up

In a next post I'll share with you an easy way to let Sculpin generate "virtual" pages and assets (which are different from both custom content types and generators).

PHP Sculpin documentation