Goldsmith

generator golang goldsmith mit license web

Goldsmith is a fast and easily extensible static website generator written in Go. In contrast to many other generators, Goldsmith does not force any design paradigms or file organization rules on the user, making it possible to generate anything from blogs to image galleries using the same tool.

Tutorial

Goldsmith does not use any configuration files, and all behavior customization happens in code. Goldsmith uses the builder pattern to establish a chain, which modifies files as they pass through it. Although the Goldsmith API is short and (hopefully) easy to understand, it is often best to learn by example:

  1. Start by copying files from a source directory to a destination directory (the simplest possible use case):

    var gs goldsmith.Goldsmith
    gs.Begin(srcDir). // read files from srcDir
        End(dstDir)   // write files to dstDir
    
  2. Now let’s convert any Markdown files to HTML fragments (while still copying the rest), using the Markdown plugin:

    var gs goldsmith.Goldsmith
    gs.Begin(srcDir).          // read files from srcDir
        Chain(markdown.New()). // convert *.md files to *.html files
        End(dstDir)            // write files to dstDir
    
  3. If we have any front matter in our Markdown files, we need to extract it using the, FrontMatter plugin:

    var gs goldsmith.Goldsmith
    gs.Begin(srcDir).             // read files from srcDir
        Chain(frontmatter.New()). // extract frontmatter and store it as metadata
        Chain(markdown.New()).    // convert *.md files to *.html files
        End(dstDir)               // write files to dstDir
    
  4. Next, we should run our barebones HTML through a template to add elements like a header, footer, or a menu; for this we can use the Layout plugin:

    var gs goldsmith.Goldsmith
    gs.Begin(srcDir).             // read files from srcDir
        Chain(frontmatter.New()). // extract frontmatter and store it as metadata
        Chain(markdown.New()).    // convert *.md files to *.html files
        Chain(layout.New()).      // apply *.gohtml templates to *.html files
        End(dstDir)               // write files to dstDir
    
  5. Now, let’s minify our files to reduce data transfer and load times for our site’s visitors using the Minify plugin:

    var gs goldsmith.Goldsmith
    gs.Begin(srcDir).             // read files from srcDir
        Chain(frontmatter.New()). // extract frontmatter and store it as metadata
        Chain(markdown.New()).    // convert *.md files to *.html files
        Chain(layout.New()).      // apply *.gohtml templates to *.html files
        Chain(minify.New()).      // minify *.html, *.css, *.js, etc. files
        End(dstDir)               // write files to dstDir
    
  6. Debugging problems in minified code can be tricky, so let’s use the Condition filter to make minification occur only when we are ready for distribution.

    var gs goldsmith.Goldsmith
    gs.Begin(srcDir).                    // read files from srcDir
        Chain(frontmatter.New()).        // extract frontmatter and store it as metadata
        Chain(markdown.New()).           // convert *.md files to *.html files
        Chain(layout.New()).             // apply *.gohtml templates to *.html files
        FilterPush(condition.New(dist)). // push a dist-only conditional filter onto the stack
        Chain(minify.New()).             // minify *.html, *.css, *.js, etc. files
        FilterPop().                     // pop off the last filter pushed onto the stack
        End(dstDir)                      // write files to dstDir
    
  7. Now that we have all of our plugins chained up, let’s look at a complete example which uses DevServer to bootstrap a complete development sever which automatically rebuilds the site whenever source files are updated.

    package main
    
    import (
        "flag"
        "log"
    
        "git.foosoft.net/alex/goldsmith"
        "git.foosoft.net/alex/goldsmith/devserver"
        "git.foosoft.net/alex/goldsmith/filters/condition"
        "git.foosoft.net/alex/goldsmith/plugins/frontmatter"
        "git.foosoft.net/alex/goldsmith/plugins/layout"
        "git.foosoft.net/alex/goldsmith/plugins/markdown"
        "git.foosoft.net/alex/goldsmith/plugins/minify"
    )
    
    type builder struct {
        dist bool
    }
    
    func (b *builder) Build(srcDir, dstDir, cacheDir string) {
        var gs goldsmith.Goldsmith
        errs := gs.Begin(srcDir).              // read files from srcDir
            Chain(frontmatter.New()).          // extract frontmatter and store it as metadata
            Chain(markdown.New()).             // convert *.md files to *.html files
            Chain(layout.New()).               // apply *.gohtml templates to *.html files
            FilterPush(condition.New(b.dist)). // push a dist-only conditional filter onto the stack
            Chain(minify.New()).               // minify *.html, *.css, *.js, etc. files
            FilterPop().                       // pop off the last filter pushed onto the stack
            End(dstDir)                        // write files to dstDir
    
        for _, err := range errs {
            log.Print(err)
        }
    }
    
    func main() {
        port := flag.Int("port", 8080, "server port")
        dist := flag.Bool("dist", false, "final dist mode")
        flag.Parse()
    
        devserver.DevServe(&builder{*dist}, *port, "content", "build", "cache")
    }
    

Samples

Below are some examples of Goldsmith usage which can used to base your site on:

Components

A growing set of plugins, filters, and other tools are provided to make it easier to get started with Goldsmith.

Plugins

Filters

Other