Simple, composable static site generator built on top of the Boot. Inspired by Boot task model and Metalsmith. Perun is a collection of boot tasks that you can chain together and build something custom that suits your needs.
Clojurians slack (join) has a channel #perun for talk about Perun.
Check SPEC.md for documentation about metadata keys used by built-in tasks.
perun.base.edn
:draft
flag:ttr
key):word-count
key):slug
key):data-build
to global meta and each file metaThere are plenty of Boot plugins that can be useful in the when you are using perun:
We use Clojure 1.7.0 and Boot 2.5.0. You should have those versions in order to use perun.
Everything in perun is build like independent task. The simplest blog engine will look like:
(deftask build
"Build blog."
[]
(comp (markdown)
(render :renderer renderer)))
But if you want to make permalinks, generate sitemap and rss feed, hide unfinished posts, add time to read to each post then you will do:
(deftask build
"Build blog."
[]
(comp (markdown)
(draft)
(ttr)
(slug)
(permalink)
(render :renderer renderer)
(sitemap :filename "sitemap.xml")
(rss :site-title "Hashobject" :site-description "Hashobject blog" :base-url "http://blog.hashobject.com")
(atom-feed :site-title "Hashobject" :site-description "Hashobject blog" :base-url "http://blog.hashobject.com")
(notify)))
You can also chain this with standard boot tasks. E.x. if you want to upload generated files to Amazon S3 you might use boot-s3 plugin.
Then your code might look like this:
(deftask build
"Build blog."
[]
(comp (markdown)
(render :renderer renderer)
(s3-sync)))
Following sites were created with perun and Boot:
Also check out examples folder.
Perun works in the following steps:
(:metadata (meta fileset)
with all meta information available for all tasks/pluginsPerun embraces Boot task model. Fileset is the main abstraction and the most important thing you should care about. When you use perun you need to create custom task that is a composition of standard and 3d party tasks/plugins/functions. Perun takes set of files as input (e.x. source markdown files for your blog) and produces another set of files as output (e.x. generated deployable html for your blog).
Fileset passed to every task has metadata (:metadata (meta fileset)
. This metadata contains accumulated information from each task. More info about structure of this metadata is coming.
[perun "0.3.0"]
Create build.boot
file with similar content. For each task please specify your own options.
See documentation for each task to find all supported options for each plugin.
(set-env!
:source-paths #{"src"}
:resource-paths #{"resources"}
:dependencies '[[org.clojure/clojure "1.7.0"]
[hiccup "1.0.5"]
[perun "0.2.0-SNAPSHOT"]
[clj-time "0.9.0"]
[hashobject/boot-s3 "0.1.2-SNAPSHOT"]
[jeluard/boot-notify "0.1.2" :scope "test"]])
(task-options!
pom {:project 'blog.hashobject.com
:version "0.2.0"}
s3-sync {
:bucket "blog.hashobject.com"
:source "resources/public/"
:access-key (System/getenv "AWS_ACCESS_KEY")
:secret-key (System/getenv "AWS_SECRET_KEY")
:options {"Cache-Control" "max-age=315360000, no-transform, public"}})
(require '[io.perun :refer :all])
(require '[hashobject.boot-s3 :refer :all])
(require '[jeluard.boot-notify :refer [notify]])
(defn renderer [{global :meta posts :entries post :entry}] (:name post))
(defn index-renderer [{global :meta files :entries}]
(let [names (map :name files)]
(clojure.string/join "\n" names)))
(deftask build
"Build blog."
[]
(comp (markdown)
(draft)
(ttr)
(slug)
(permalink)
(render :renderer renderer)
(collection :renderer index-renderer :page "index.html")
(sitemap :filename "sitemap.xml")
(rss :site-title "Hashobject" :site-description "Hashobject blog" :base-url "http://blog.hashobject.com")
(s3-sync)
(notify)))
After you created build
task simply do:
boot build
To see more detailed output from each task (useful for debugging) please use
--verbose
boot flag. E.x. boot --verbose dev
Perun is static site generator. So usually you'd use it by just running boot build
which will generate your static site.
This process is robust and great for production but it's slow and lacks fast feedback when you're developing your site locally.
In order to solve this problem we recommend following setup:
build-dev
and build
.build.boot
file. This will enable serving your site using web server.dev
that will call build-dev
on any change to your source files: (deftask dev
[]
(comp (watch)
(build-dev)
(serve :resource-root "public")))
boot dev
In such setup you will have http web server serving your generated content that would be regenerated every time you change
your source files. So you'd be able to preview your changes almost immediately.It's quite easy to setup automatic static site deployment.
E.x. you have GitHub repo for your blog and you are using boot-s3
to sync files to Amazon S3.
In this case it's possible to setup flow in a way that every commit to GitHub would be built on Heroku using perun and deployed to AWS S3.
Assuming you have setup similar to example in order to achieve this you need to:
build.boot
filebuild.boot
has build
task that has tasks build and deploy tasksAWS_ACCESS_KEY
and AWS_SECRET_KEY
envs. They are mandatory for the boot-s3
plugin).heroku buildpacks:add https://github.com/hashobject/heroku-buildpack-perun
Similar auto deployment can be configured using CircleCI too.
We love contributions. Please submit your pull requests.
Copyright © 2013-2016 Hashobject Ltd (team@hashobject.com).
Distributed under the Eclipse Public License.
Can you improve this documentation? These fine people already did:
Anton Podviaznikov, Juho Teperi, Alan Dipert, Daemian Mack, Martin Klepsch & Tommi ReimanEdit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close