Bitbucket is a code hosting site with unlimited public and private repositories. We're also free for small teams!

Close

Small Stories

http://smallstories.org
The code for a growing collection of very short stories on the web.

Overview

Small Stories is built using a custom static site generator written in Haskell. It is modeled in many ways after Yesod.

Stories

If you are just looking for the text of the stories, they can be found in the stories directory. The stories are written in Markdown and parsed with Pandoc.

Motivation

Why build yet another static site generator? I had a few motivations:

  • Most of the other static site generators out there are basically nicer versions of Make. I didn't feel like an input → transform → output approach made much sense for the design I had in mind.1
  • I wanted to play around with Yesod but found it unsuitable for static sites (believe me, I tried).
  • I'm an intermediate Haskeller and I wanted a project to hack on.

Templating

Small Stories uses the Shakespearean templates, just like Yesod. All of the templates are in submodules of SmallStories.Component.

Components

Components are Small Stories's take on Yesod's Widgets. They present a composable, simple abstraction around a small bit of HTML and CSS. Like Yesod's Widgets, components compose cleanly within caret brackets in Hamlet and we offer a toComponent function and accompanying typeclass that behaves much like Yesod's toWidget.

The biggest differences from Widgets:

  • While Components themselves are monadic in nature, they do not need to be run in any special monad to produce a value. Widgets are tied to Yesod's Handler monad.
  • Components are not as featureful as Widgets (yet). The two biggest omissions currently are a lack of support for Julius/JavaScript (should be extremely straightforward to add) and no way for components to set the contents of the <title> tag.

Also there is the fact that Small Stories is a static site generator and Yesod is designed to handle individual requests, so Components have a slightly different feel in that respect.

See the SmallStories.Component module for the implementation.

Static Pages

Much like Yesod, Small Stories compiles all templates and static assests directly into the binary, making it totally relocatable. In the SmallStories.Static module there is an implementation similar to Yesod's Data.FileEmbed and Yesod.Static.

We provide Template Haskell to embed all files in a particular directory. Note that the files are read at compile time, so the smallstories binary depends on only the text of the stories as input.

More Architecture Details

Small Stories is as a UNIX executable with a fairly simple set of command line flags. Command line parsing is driven by CmdArgs. The SmallStories.Main module handles this as well as assembling the pages to output.

Pages

For the moment there is a Page data type which (now) serves little purpose but to hold arguments to be passed to the fooComponent functions. It will be going away soon, hopefully. The corresponding module is SmallStories.Page.

Routes

The other main data type not already discussed above are the routing data type. Like Yesod, Small Stories leverages the Shakespearean templates to provide type safe URLs. This means that there's no way to write a link in a template that's a 404!

The SmallStories.Route module itself is not particularly interesting, but do note how the Component type is parameterized over the route type, which should make it highly reusable.


  1. The design came first before I started implementing; I prototyped it in HTML. 

Recent activity

Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.