Flexible Lisp Blogware. Fork for personal use. Mirrored from https://github.com/kingcons/coleslaw originally.
The theming support in coleslaw is very flexible and relatively easy to use. However it does require some knowledge of HTML, CSS, and how coleslaw processes content.
To understand how coleslaw works, a look at the hacking documentation will prove useful. This document focuses mainly on the template engine and how you can influence the resulting HTML.
Themes are written using Closure Templates. Those templates are then compiled into functions that Lisp calls with the blog data to get HTML. Since the Lisp code to use theme functions is already written, your theme must follow a few rules.
Every theme must be in a folder under "themes/" named after the
theme. The theme's templates must start with a namespace declaration
like so: {namespace coleslaw.theme.$MY-THEME-NAME}
.
A theme must have three templates which take specific arguments (to be described later).
Coleslaw generates two types of pages: index
pages and post
pages.
Every page other than those in the posts/
directory is an index
.
Every page uses the base.tmpl
and fills in the content using
either the post
or index
templates. No important logic should be
in any template, they are only used to provide a consistent layout.
base.tmpl
This template generates the outer shell of the HTML.
It keeps a consistent look and feel for all pages in the blog. The
actual content (i.e., not header/footer/css) comes from other templates.
index.tmpl
This template generates the content of the index
pages.
That is, any page with more than one content object, e.g. the homepage.
post.tmpl
This templates generates content for the individual posts.
Here's a visual example to make things clearer:
INDEX HTML FILES INDIVIDUAL POST HTML FILES
|-------------------------| |-------------------------|
| base.tmpl | | base.tmpl |
| | | |
| |-------------------| | | |------------------| |
| | index.tmpl | | | | post.tmpl | |
| | | | | | | |
| |-------------------| | | |------------------| |
| | | |
|-------------------------| |-------------------------|
If you only want to change the way the blog is styled, it is probably
simplest to either modify the existing default theme, hyde
, or copy
it in entirety and then tweak only the CSS of your new theme. A large
amount of visual difference can be had with a minimum of (or no)
template hacking. There is plenty of advice on CSS styling on the web.
I'm no expert but feel free to send pull requests modifying a theme's
CSS or improving this section, perhaps by recommending a CSS resource.
A theme name must be a valid lisp symbol. For this example, we'll use
trivial
, so create a themes/trivial
directory in the coleslaw repo.
As described above, we need 3 template files base.tmpl
, post.tmpl
and index.tmpl
. Initially, let's just create the simplest theme that
compiles correctly.
base.tmpl:
{namespace coleslaw.theme.trivial}
{template base}
{/template}
post.tmpl:
{namespace coleslaw.theme.trivial}
{template post}
{/template}
index.tmpl:
{namespace coleslaw.theme.trivial}
{template index}
{/template}
This will create three template functions that coleslaw can find, named
base
, post
, and index
.
At this point, you can change the :theme
in your .coleslawrc
to
trivial
and then generate your blog with (coleslaw:main)
. However,
all the HTML files will be empty because our templates are empty!
The templating language is documented elsewhere. However as a short primer:
{
and }
.{$variable}
or {$variable.key}
.
WARNING: At present, cl-closure-template does not have great debugging.
If you typo this, e.g. ${variable}
, you will receive an uninformative
and apparently unrelated error. Also, attempted access of non-existent keys
fails silently. We are exploring options for making debugging easier in a
future release.{if ...} ... {else} ... {/if}
.
Typical examples are: {if $injections.body} ... {/if}
or
{if not isLast($link)} ... {/if}
.{foreach $var in $sequence} ... {/foreach}
.The variable that should be available to all templates is:
.coleslawrc
content.index
or post
.name
and url
.name
and url
.content
, a list of content (see below)name
, a name to use in links or href tagstitle
, a title to use in H1 or header tagsurl
and title
.url
and title
.url
, the relative url of the posttags
, a list of tags (each with keys name
and url
)date
, the date of postingtext
, the HTML of the post's bodytitle
, the title of the postNOTE: We can keep the template engine from escaping raw HTML by
adding a |noAutoescape
clause to commands, like so: {$raw |noAutoescape}
.
Let's now rewrite base.tmpl
like this:
{namespace coleslaw.theme.trivial}
{template base}
<html>
<head><title>Trivial Theme For Coleslaw</title></head>
<body>
<h1>All my pages have this title</h1>
{$raw |noAutoescape}
</body>
</html>
{/template}
A simple index.tmpl
looks like this:
{namespace coleslaw.theme.trivial}
{template index}
{foreach $obj in $index.content}
<h1>{$object.title}</h1>
{$object.text |noAutoescape}
{/foreach}
{/template}
And a simple post.tmpl
is similarly:
{namespace coleslaw.theme.trivial}
{template post}
<h1>{$post.title}</h1>
{$post.text |noAutoescape}
{/template}
All of the files are now populated with content. There are still no links
between the pages so navigation is cumbersome but adding links is simple.
Just do: <a href="{$config.domain}/{$object.url}">{$object.name}</a>
.