Home

Awesome

gostatic

Gostatic is a static site generator. It tracks file changes during compilation, which is why it works reasonably fast. Also it provides framework for configuration akin to Make, which makes it easy to understand and to write custom configurations.

Features include:

And all in all, it works nicely for me, so it may work for you!

Installation

Just download a binary from releases page.

If you need to automate downloading latest release, I use this script (change 64-linux to the type you need):

URL=$(curl -s https://api.github.com/repos/piranha/gostatic/releases | awk '/download_url.*64-linux/ { print $2; exit }')
curl -Lso gostatic $(URL)
chmod +x gostatic

When downloading in Macos, your file will be quarantined and to use it you'll have to assure Macos you know what you're doing:

xattr -r -d com.apple.quarantine gostatic

Obviously, go get https://github.com/piranha/gostatic also works, if you want to compile from source.

Quick Start

Run gostatic -i my-site to generate basic site in directory my-site. It will have a basic config file, which you should edit to put relevant variables at the top - it also contains description of how files in your src directory are treated.

src directory obviously contains sources of your site (name of this directory can be changed in config). You can follow general idea of this directory to create new blog posts or new pages. All files, which are not mentioned in config, are just copied over. Run gostatic -fv config to see how your src is processed.

site.tmpl is a file that defines templates your are able to use for your pages. You can see those templates mentioned in config.

And, finally, there is a Makefile, just for convenience. Run make to build your site once or make w to run watcher and server, to see your site changes in real time.

Also, you could look at my site for an example of advanced usage.

Good luck! And remember, your contributions either to gostatic or to documentation (even if it's just this README.md) are always very welcome!

Documentation index:

Also, see wiki - and feel free to add more information there!

Approach

Each given file is processed through a pipeline of filters, which modify the file state and then rendered on disk. Single input file corresponds to a single output file, but filters can generate virtual input files (like tag files).

File is rendering in those cases:

All files are sorted by date. This date is taken in their config or, in case if date in config is absent or dates there are equal, by file modification time.

Speed

BoxPagesFullNoopSingle post
Macbook Air '15 (i7)630450ms100ms160ms (93 pages)
Macbook Air '15 (i7)250180msn/an/a
Macbook Air '20 (M1)486185ms39ms140ms (97 pages)
Hetzner CX21 (2 vCPU/4GB)486502ms89ms414ms (97 pages)

This are results of forced full site rebuild, then checking there are no modification, and then re-rendering a single changed page (along with pages which depend on this page).

Also note that if you're using various external post-processors (like uglifyjs or sassc) they tend to slow down things a bit (for my specific use case both uglifyjs and sassc add another 0.25s when files they process change).

To reproduce numbers, download hyperfine, download gostatic, clone solovyov.net, comment out :google-closure-compiler in config and then run:

External resources

Configuration

Config syntax is Makefile-inspired with some simplifications, look at the example:

TEMPLATES = site.tmpl templates-folder
SOURCE = src
OUTPUT = site

# this is a comment
*.md:
    config
    ext .html
    directorify
    tags tags/*.tag
    markdown
    template page # yeah, this is a comment as well

index.md: blog/*.md
    config
    ext .html
    inner-template
    markdown
    template page

*.tag: blog/*.md
    ext .html
    directorify
    template tag
    markdown
    template page

Here we have constants declaration (first three lines), a comment and then three rules. One for any markdown file, one specifically for index.md and one for generated tags.

Specific rules override generic matching rules, but logic is not exactly very smart, and there is no real precedence defined, so if you have several matches for a single file you could end up with any of them. Note that there is some order: exact path match, exact name match, glob path match, glob name match. NOTE: this may change in future.

Rules consist of path/match, list of dependencies (also paths and matches, the ones listed after colon) and commands.

Each command consists of a name of processor and (possibly) some arguments. Arguments are separated by spaces.

Note: if a file has no rules whatsoever, it will be copied to exactly same location at destination as it was in source without being read into memory. So heavy images etc shouldn't be a problem.

Constants

There are three configuration constants:

You can also use arbitrary names for constants to access later from templates - just use any other name (AUTHOR could be one).

All constants can also be accessed from the config itself, using $(CONSTANT_NAME) syntax, just like in Makefile.

Page Config

Page config is only processed if you specify config processor for a page. It's format is name: value, for example:

title: This is a page
tags: test
date: 2013-01-05

Parsed properties:

You can also define any other property you like, it's value will be treated as a string and it's key is capitalized and put on the .Other page property.

Processors

You can always check list of available processors with gostatic --processors.

Template API Reference

Templating is provided using Go templates. See link for documentation on syntax.

Each template is executed in context of a page. This means it has certain properties and methods it can output or call to generate content, i.e. {{ .Content }} will output page content in place.

Global functions

Go template system provides some convenient functions, and gostatic expands on that a bit:

Page interface




Paginator interface

Page list interface



Site interface

Extensibility

Obviously, the easiest way to extend gostatic's functionality is to use external processor. It makes you able to process files in the way you want, but is more or less limited to that. There is no API right now to create pages on the fly (like tags processor does) using this method, for example.

But gostatic itself is a library, and you can write your own static site generator using this library. See gostatic.go for an example of one.