From 16d02310e69449e9833604224baa81655a5035e4 Mon Sep 17 00:00:00 2001 From: Alex Yatskov Date: Tue, 12 Jan 2016 19:24:19 +0900 Subject: [PATCH] Adding README --- README.md | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..89f3e1a --- /dev/null +++ b/README.md @@ -0,0 +1,129 @@ ++++ +area = "projects" +github = "goldsmith" +tags = ["generator", "golang", "goldsmith", "mit license", "web"] +title = "Goldsmith" ++++ + +Goldsmith is a static website generator developed in Golang with flexibility, extensibility, and performance as primary +design considerations. With Goldsmith you can easily build and deploy any type of site, whether it is a personal blog, +image gallery, or a corporate homepage; the tool no assumptions are made about your layout or file structure. Goldsmith +is trivially extensible via a plugin architecture which makes it simple to perform complex data transformations +concurrently. A growing set of core plugins, [Goldsmith-Plugins](../goldsmith-plugins/), is provided to make it easier +to get started with this tool to generate static websites. + +## Motivation ## + +Why in the world would one create yet another static site generator? At first, I didn't think I needed to; after all, +there is a wide variety of open source tools freely available for use. Surely one of these applications would allow me +to build my portfolio page exactly the way I want right? + +After trying several static generators, namely [Pelican](http://blog.getpelican.com/), [Hexo](https://hexo.io/), and +[Hugo](https://gohugo.io/), I found that although sometimes coming close, no tool gave me exactly what I needed. +Although I hold the authors of these applications in high regard and sincerely appreciate their contribution to the open +source community, everyone seemed overly eager to make assumptions about content organization and presentation. + +Many of the static generators I've used feature extensive configuration files to support customization. Nevertheless, I +was disappointed to discovered that even though I could approach my planned design, I could never realize it. There was +always some architectural limitation preventing me from doing something with my site which seemed like basic +functionality. + +* Blog posts can be tagged, but static pages cannot. +* Image files cannot be stored next to content files. +* Navbar item activated when viewing blog, but not static pages. +* Auto-generated pages behave differently from normal ones. + +Upon asking on community forms, I learned that most users were content to live with such design decisions, with some +offering workarounds that would get me halfway to where I wanted to go. As I am not one to make compromises, I kept +hopping from one static site generator to another, until I discovered [Metalsmith](http://www.metalsmith.io/). Finally, +it seemed like I found a tool that gets out of my way, and lets me build my website the way I want to. After using this +tool for almost a year, I began to see its limits. + +* The extension system is complicated; it's difficult to write and debug plugins. +* Quality of existing plugins varies greatly; I found many subtle issues. +* No support for parallel processing (this is a big one if you process images). +* A full [Node.js](https://nodejs.org/) is stack (including dependencies) is required to build sites. + +Rather than making do with what I had indefinitely, I decided to use the knowledge I've obtained from using various +static site generators to build my own. The *Goldsmith* name is a reference to both the *Go* programming language I've +selected for this project, as well as to *Metalsmith*, my inspiration for what an static site generator could be. + +The motivation behind Goldsmith can be described by the following principles: + +* Keep the core small and simple. +* Enable efficient, multi-core processing. +* Add new features via user plugins. +* Customize behavior through user code. + +I originally built this tool to generate my personal homepage, but I believe it can be of use to anyone who wants to +enjoy the freedom of building a static site from ground up, especially users of Metalsmith. Why craft metal when you can +be crafting gold? + +## Usage ## + +Goldsmith is at it's core, a pipeline-based file processor. Files are loaded from the source directory, processed by any +number of plugins, and are finally output to the destination directory. Rather than explaining the process in detail +conceptually, I will show some code samples which show how this tool can be used in practice. + +* Start by copying files from a source directory to a destination directory (simplest possible use case): + ``` + goldsmith.Begin(srcDir). + End(dstDir) + ``` + +* Now let's also convert our [Markdown](https://daringfireball.net/projects/markdown/) files to HTML using the + [markdown plugin](../goldsmith-plugins/markdown): + ``` + goldsmith.Begin(srcDir). + Chain(markdown.NewCommon()). + End(dstDir) + ``` + +* If we are using *front matter* in our Markdown files, we can easily extract it by using the + [frontmatter plugin](../goldsmith-plugins/frontmatter): + ``` + goldsmith.Begin(srcDir). + Chain(frontmatter.New()). + Chain(markdown.NewCommon()). + End(dstDir) + ``` + +* Next we want to run our generated HTML through a template to add a header, footer, and a menu; for this we + can use the [layout plugin](../goldsmith-plugins/layout): + ``` + goldsmith.Begin(srcDir). + Chain(frontmatter.New()). + Chain(markdown.NewCommon()). + Chain(layout.New( + layoutFiles, // array of paths for files containing template definitions + templateNameVar, // metadata variable that contains the name of the template to use + contentStoreVar, // metadata variable configured in template to insert content + defTemplateName, // name of a default template to use if one is not specified + userFuncs, // mapping of functions which can be executed from templates + )). + End(dstDir) + ``` + +* Finally, let's [minify](https://en.wikipedia.org/wiki/Minification_(programming)) our files to reduce data transfer + and load times for our site's visitors using the [minify plugin](../goldsmith-plugins/minify). + ``` + goldsmith.Begin(srcDir). + Chain(frontmatter.New()). + Chain(markdown.NewCommon()). + Chain(layout.New(layoutFiles, templateNameVar, contentStoreVar, defTemplateName, userFuncs)). + Chain(minify.New()). + End(dstDir) + ``` + +I hope this simple example effectively illustrates the conceptual simplicity of the Goldsmith pipeline-based processing +method. Files are injected into the stream at Goldsmith initialization, processed in parallel through a series of +plugins, and are finally written out to disk upon completion. + +Files are guaranteed to flow through Goldsmith plugins in the same order, but not necessarily in the same sequence +relative to each other. Timing differences can cause certain files to finish ahead of others; fortunately this, along +with other threading characteristics of the tool is abstracted from the user. The execution, while appearing to be a +mere series chained methods, will process files using all of your system's cores. + +## License ## + +MIT