Skip to content

Clojure powered blogging with Cryogen

Practicalli Clojure Logo

A blog website shouldnt need a complex content management system. A simple and lightweight static website generator can create engaging websites that are simple to manage with Git.

Cryogen is a static site generator written in Clojure, allowing content to be written in either markdown or asciidoc. Posts and pages are configured with Clojure hash-maps to manage the meta-data and layout information for each post.

Cryogen seems very quick to generate a site and a local server can be run to automatically generate an updated website when changes to posts and pages are saved.

practicalli/blog-cryogen contains all the content and configuration used to create the Practicalli blog website.

Markdown tables not supported

Limitation/bug cryogen does not support tables in markdown posts.

The issue seem to reside in cryogen-markdown library

Requirementsλ︎

Clojure CLI and clj-new template to create and manage a Cryogen project

A Java virtual Machine is a dependency for Clojure CLI, eg. Temurin from Adoptium.net

Install Clojure - Practicalli Clojure book(target=_blank .md-button)

Create a new siteλ︎

Use the cryogen template for Leiningen to create a new project

Here we create a project called practicalli-blog using the template

Create a Cryogen project

clojure -T:project/new :template cryogen :name practicalli/blog

Change into the project directory and use Leiningen to run the project

Start Cryogen local server

clojure -X:serve

A server will now start and generate the sample posts provided by the Cryogen template.

The web browser automatically open a new browser tab/window at http://localhost:3000/blog

Changing files in the project will trigger a new compilation of the website. Manually refresh the browser page if kept open.

Configure the siteλ︎

The configuration defines the site title (banner heading), author (copyright message), description (not sure where this is used).

content/config.edn is the configuration file for the generated site

Practicalli Blog Cryogen config

 :site-title           "Practicalli"
 :author               "Practicalli"
 :description          "Discovering the fun in Functional Programming with Clojure"
 :site-url             "http://practical.li/"

Enable live evaluation with Klipseλ︎

Make your sample code executable and interactive to the user by enabling Klipse in Cryogen. Klipse provides live evaluation for a number of programming language.

Enable Klipse by defining a specific CSS selector and use that name when defining a code block, e.g. klipse-clj

Cryogen Klipse config

 :klipse               {:settings {:selector         ".klipse-clj"
                                   :selector-reagent ".klipse-reagent"}}

Example config.edn file from the practicalli/blog-content GitHub repository

Version controlλ︎

A .gitignore file is created when using the cryogen template to create a project.

This contains the /public/ pattern to exclude the generated website, as well as the common patterns for a Leiningen project.

Writing postsλ︎

Posts can be written in either markdown or asciidoc. Markdown is the default and all posts should be placed inthe content/md/ directory.

The filename can be prefixed with the date of the post, however, I find it more flexible to specify the date in the post metadata header as if you change the date then the URL of the post will remain the same. This is really handy if you need to update the post and need to reflect that in the date, or if you had planned to publish the post a few weeks in the future and then realise its ready sooner.

Post header - metadataλ︎

The start of each post is a Clojure hash-map, {} containing metadata for the specific blog

:title and :layout are mandatory keys, the rest are optional. You can also define your own custom keys which can be used in the selma templates, for example :topic

  • :title The h1 title used for the blog post
  • :layout A keyword corresponding to an HTML file under themes/{theme}/html.
  • :date The published date of the blog (future blogs can be hidden)
  • :author The name of the post author as a string, displayed at the top of the post in the default theme.
  • :tags Tags associated with the blog, as a vector of strings e.g. ["clojure" "cryogen"]
  • :klipse Enable live evaluation of code in the post (see live evaluation with Klipse)
  • :toc Include a table of contents at the top of the page, with links to all the headings in the post
  • :draft? true will skip this post from the static site generation
  • :topic A custom key I use to manage a topic image displayed on each post (theme development will be covered in a future post)

Deploying the site to GitHub pagesλ︎

Automate publish with GitHub workflow

Automate Cryogent blog publishing describes how to build and deploy a Cryogen blog with a GitHub CI workflow.

GitHub pages is a free static site hosting service and we can deploy the cryogen website by a git push.

Create a repository in either a user account or GitHub organisation (eg. using the GitHub website).

An unsophisticated script is used to deploy the generated website. The script creates a Git repository in the public directory, all files are committed with a generic message, a remote repository added and the content pushed.

cd public/blog && \
rm -rf .git && git init && git add . && \
git commit -m "publish blog" && \
git branch -m master gh-pages && \ 
git remote add practicalli git@github.com:practicalli/blog.git && \
git push -f practicalli gh-pages

Edit the deploy-to-gh-pages script and update the URL of the GitHub repository created to host the website.

If the website is not displayed, check the GitHub repository settings and ensure the gh-pages is set.

Serve GitHub Pages from docs directory

Set the docs directory as the source of GitHub pages source for the, especially when supporting a software project or library.

Prevent GitHub pages Jekyll compilationλ︎

A Jekyll process runs every time a change is pushed to a GitHub pages branch. As Cryogen generates the finished website Jekyll processing is not required and it can be switch it off.

Add an empty file called .nojekyll to the content directory.

Edit the config.edn configuration file and add the .nojekyll file to the resources. This ensures the .nojekyll file is copied over to the generated website in the public directory.

Disable Jekyll

 :resources            ["images" ".nojekyll"]

Thank you.

🌐 Practical.li Website

Practical.li GitHub Org practicalli-johnny profile

@practicalli@clj.social @practical_li