Static site generation on the JVM with JBake

Hi everyone, my talk today is called "Static site generation on the JVM with JBake". Before I start can I ask if anyone here has used a static site generator before?

Talk

Introduction

Let me start by introducing myself...
I'm employed as a developer by CGG, who are a French geoscience company - I work at their Conwy office in North Wales.
I'm the original creator of JBake and current maintainer of the project.
I'm also an Open Uni student studying for a Masters in Software Engineering.

What is baking?

So what is baking?

Building a static web site from simple text files ...

It's building a static web site from simple text files. The term 'bake' is often used to describe this process of building a static site. The earliest mention of the term I'm aware of was by the late Aaron Swartz back in 2002.

... a popular alternative to frying a web site using a database.

It's a popular alternative to frying a web site using a database. Where you construct the output dynamically for each request... like most of the popular CMS/blog engines such as Wordpress etc.

So why bake?

Benefits

Serving out static files is always going to be quicker than content dynamically generated as there is less processing required.
You don't have to worry about vulnerabilities in your CMS or blog engine and staying up to date.
You aren't tied into any platform, you can use whatever web server you like - even use AWS or GitHub.
Your sites content can then be version controlled just like code is.
You can use any IDE or text editor you like or prefer - and work offline.
Static sites can also be very easy to deploy.

On to JBake

Background

...just a hobby, won't be big and professional...
I started the project back in early 2013 - originally to scratch my own itch.
I had been using Wordpress for my own simple site but the performance of it wasn't great on small VM I was using at the time and I hardly used any of the features in Wordpress.
Around the same time I came across the article by Tom Preston-Werner (one of the founders of GitHub) about the reasons he created Jekyll and it struck a chord with me.
So I looked about for a Java static generator and couldn't find one so I decided to create my own.

Features

JBake is written in Java so takes advantage of the benefits the JVM provides: excellent x platform support and speed.
Open source project - the source is available on GitHub under the MIT license.
You can organise your content in any folder structure you like.
It supports content in the following formats: Markdown, AsciiDoc and raw HTML.
Can I just ask the audience how many people have used or heard of Markdown? How many have used or heard of AsciiDoc?
I do recommend you look into AsciiDoc if your using Markdown.

Features

JBake is blog aware and can generate an RSS feed, a sitemap, and tag link pages etc.
Allows you to see what a draft post looks like before being published and included on other pages such as sitemaps.
And you're free to use any front-end framework you like... Twitter's Bootstrap or Zurb Foundation or your own created from scratch.

Templates

JBake uses templates to enable features like content reuse - say you have a menu template you can include this into other templates for multiple pages.
The templates also provide dynamic features such as conditional output or loops.
Support is there for Freemarker, Groovy's 3 template engines: Simple, Xml and the Markup Engine, Timeleaf and Jade.
Content is exposed to the templates via a data model.
This data model can be persisted to disk so subsequent executions only render what has been added or changed - incremental output.

Installation

A binary distribution is avaiable on jbake.org and contains everything you need.
It's also available through SDKMAN - a SDK manager that manages parallel versions of sdks on Unix like systems.
It's also available through Homebrew for OS X users.
Artefacts are also available on Maven Central as well as Bintrays JCenter.
The distribution only requires a JRE to run (1.6 and above).

Usage Options

There is a command line interface allowing various functions to be performed.
init - initialises a web site or project folder with example templates of your choice and sample content.
bake - generates your site
serve - runs the built in web server to enable local testing
There is also build plugins available for Maven and Gradle.
Alternatively you can use the Java API directly in your own code.

Example sites

I'll just go through some sample sites so you can see what's possible with JBake...
Clojure is one of the many alternative JVM languages and the team used JBake to generate their new site.
Crash by Exo provides a shell for the JVM platform - one of the earliest users of JBake.
Codename One is a project by a number of ex-Oracle staff to provide cross-platform mobile native development using Java.
The expert group behind the Java Specification Request for Money and Currency used JBake for their site.
Griffon is a desktop application dev platform for the JVM, inspired by Grails and uses Groovy.
Hawkular is an open source monitoring solution developed by JBoss.
The Apache Roller project powers the blogs.oracle.com site and uses JBake to create their project site.
Cedric works for Gradle and is a core Groovy developer - he uses JBake for his blog and was an early contributor to JBake.

How it works

How the "oven" works

This image gives you an visual overview of how the generation pipeline works.
(explain stages...)

Site/Project layout

	├── assets
	│   ├── css
	│   ├── img
	│   └── js
	├── content
	│   ├── changelog.md
	│   ├── news
	│   │   ├── index.md
	│   │   └── jbake-v2-1-released.md
	│   └── sites.md
	├── templates
	│   ├── index.ftl
	│   ├── page.ftl
	│   └── post.ftl
	└── jbake.properties
	

Content file - Markdown


title=Changelog
date=2013-03-30
type=page
status=published
~~~~~~

### v2.1

*2013-04-30*

* Added unit tests
* Added post baking stats
* Command line arguments are now optional
...

Template file - Freemarker


  <#include "header.ftl">
  
  <#include "menu.ftl">

  <div class="page-header">
    <h1>Blog</h1>
  </div>
    <#list posts as post>
      <#if (post.status == "published")>
        <a href="${post.uri}"><h1>
          <#escape x as x?xml>${post.title}</#escape>
        </h1></a>
        <p>${post.date?string("dd MMMM yyyy")}</p>
        <p>${post.body}</p>
      </#if>
    </#list>

Template file - Jade


 doctype html
 html
  include header.jade
  body(onload="prettyPrint()")
    div#wrap
      include menu.jade
        div.page-header
          h1 Blog
          each post in published_posts
            a(href="#{post.uri}")
              h1 #{post.title}
            p #{formatter.format(post.date,
            		"dd MMMM yyyy")}
            p !{post.body}

Config file


  site.host=http://jbake.org
  render.tags=false
  render.sitemap=true
  template.masterindex.file=index.jade
  template.archive.file=archive.jade
  template.tag.file=tags.jade
  template.sitemap.file=sitemap.jade
  template.post.file=post.jade
  template.page.file=page.jade
  template.feed.file=feed.jade

Time for the Demonstration

Further Reading

Thanks any questions..?