12 KiB
Themes
The theming support in coleslaw is very flexible, and relatively easy to use. However it does require some knowledge of HTML, CSS and Closure Templates, and of course how coleslaw converts posts into a collection of HTML files.
This document will focus mainly on the part of how coleslaw converts posts into a blog, and how you can influence the resulting HTML.
Overall Structure
Conceptually the process of creating a blog with coleslaw is the following:
-
Coleslaw read a directory containt
.post
files and processes them into HTML fragments. -
The HTML fragments of the posts are processed with the templating engine, to produce different HTML files.
And for theming purposes, an important final step
- A browser renders the generated HTML and styles it with CSS.
The first step, the translation from markdown to HTML fragments is fixed, you cannot really influence that in a (theming) meaningful way.
The theming is done in the last two steps, the templating and the CSS.
Now both steps have a different role:
-
Templating, this determines the file structure of the generated HTML. This part inserts headers, footers, include the CSS stylesheets and other resources.
This is also the place where you can add for example a table of contents of the posts, or where the list of tags will be inserted etc.
Also, very importantly, by generating the right HTML
<div>
elements it will make it easy to style the resulting HTML with CSS. -
CSS, this is the part which will determine the look of all the components. For example the font and font size of the titles and sub titles.
But CSS is very well covered in the literature and we will not cover how to use CSS in this document. But it is good to remember that if you are struggling to achieve a certain effect with CSS, it might be easy to solve by modifying the template. Either by changing the structure of the document or by adding the right
id
orclass
attributes.
NOTE It is not possible to change the generated file names or the generated file structure on disk. The templating/theming support allows changing the resulting HTML but nothing more.
What Files are generated anyway?
Before we dive into the templating itself, it is important to know the directory structure of the generated content, because when writing a template you need to be aware of how coleslaw lays out the blog on disk.
The toplevel looks like this:
index.html
posts/
tags/
date/
static/
css/
index.html
This file is the front page of the blog. It contains a list of the most recent posts and has links to the different archives.
posts directory
This directory contains an .html
file per post. The name of the file
is the slug
of the post.
tags directory
This directory contains an .html
file per tag. Such a file contains
all posts which contain the tag. The name of a tag file is the slug
of the tag.
date directory
This directory contains files of the form yyyy-mm.html
with yyyy
the year as a 4 digit number and mm
as a two digit month number.
These files contain all the posts of the indicated month.
static directory
This directory is a copy of the static/
directory of the source folder of coleslaw.
css directory
This directory is a copy of the css/
folder of the theme.
Two type of HTML files
Coleslaw generate two types of HTML files: index
files and post
files.
Except for the files in the posts/
directory all files are index
files.
The HTML files, as mentioned before, are created by filling in the [Closure Templates] clt. And to generate all the HTML files there are three templates relevant:
-
base.tmpl
This template generates the outer shell of the HTML. This is used to generate a consist look and feel and structure for all pages in the blog.The actual content (besides fixed headers and footers etc.) is generated by one of the other two templates
-
index.tmpl
This template generates the content of theindex
files, remember, these are all files containing more than one post, so including the front page. -
post.tmpl
This generates the HTML files for the individual posts. Remember that Coleslaw already converts the content of the individual post to HTML by using markdown (or ReST). So this template is NOT used to format or convert an individual post. This template is used to create the HTML containing that post
Visual it might be clearer this way:
INDEX HTML FILES INDIVIDUAL POST HTML FILES
|-------------------------| |-------------------------|
| base.tmpl | | base.tmpl |
| | | |
| |-------------------| | | |------------------| |
| | index.tmpl | | | | post.tmpl | |
| | | | | | | |
| |-------------------| | | |------------------| |
| | | |
|-------------------------| |-------------------------|
Creating a Theme from Scratch (with code)
Step 1. Pick a name
A theme name should satisfy two conditions:
- It is a valid lisp symbol name (not containing
:
) - It is a valid directory name.
So for this example lets pick trivial
.
Step 2. Create the right directory
Now we need to create a directory containing the theme files.
In the coleslaw system directory should be a directory called themes/
.
The directory for the theme files is a sub directory of the themes/
directory,
named after the theme name we picked in step 1.
So in our case, we have to create the directory themes/trivial/
.
Step 3. Create the 3 template files
As described above, we need the 3 template files base.tmpl
, post.tmpl
and index.tmpl
.
Before we customize them, create the with the following content:
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}
The first line in these files, declares the namespace of the template. The namespace must be
coleslaw.theme.
followed by the theme name.
The remaining two lines {template ...}{/template ...}
create the empty templates.
Step 4. Test
This is enough to make coleslaw happy. You can now use the new trivial
theme in coleslaw
by changing the :theme
in .coleslawrc
file to trivial
.
If you do this and generate the blog with (coleslaw:main "")
, coleslaw will not complain
and generate all the post files, tag files and front page files as normal. Except that all
these files are empty.
The HTML files are empty because the templates are empty.
Step 5. Generating valid HTML
The base.tmpl
generates all the HTML pages, so if we change the base template to:
{namespace coleslaw.theme.trivial}
{template base}
<html>
<head><title>Trivial Theme For Coleslaw</title></head>
<body>
<h1>All my pages have this title</h1>
</body>
</html>
{/template}
We will generate valid HTML. Of course every page is still the same, but at least it shows that the templating engine works.
Intermezzo I, The Templating Language
The templating language is documented at Google closure templates. However as a short primer:
-
Everyting is outputed literally, except template commands
-
Template commands are enclosed in
{
and}
-
Variables, which are provided by coleslaw are referenced as
$variable.key
inside a template command. So to insert a variable you have to use{$variable.key}
.Variables are either simple variables, which are referenced as
{$var}
Or are indexed by a key and written as{$var.key}
. -
If statements are written as
{if ...} ... {else} ... {/if}
Typical examples are:
{if $injections.body} ... {/fi}
Or
{if not isLast($link)} ... {/fi}
-
Loops are typically written as
{foreach $var in $index.posts} ... {/foreach}
Intermezzo II, Variables provided by coleslaw
The variable that is available in all templates is:
- config This contains the .coleslawrc content
Base Template Variables
- raw the HTML generated by the sub templates,
index.tmpl
orpost.tmpl
- content the data which was used to generate raw HTML.
- pubdate A string containing the publication date
- injections A list containg all injections. Injections are for the plugins to communicate additional content to be included.
Index Template Variables
- tags A list containing all the tags, A tag has values
.name
and.slug
. - months A list of all months for which there are posts. This is a list
of strings. The strings are formatted as
yyyy-mm
. - index This is the meat of the content. This variable has as keys
id
, the name of the page that will be renderedposts
a list of posts (see below)title
The title under which this index is know. This should be used to display a title for the user.- prev If this index file is part of a chain, the
id
of the previous index html in the chain. If this is the first file, the value will be empty. - next If this index file is part of a chain, the
id
of the next index html in the chain. If this is the last file, the value will be empty.
Post Template Variable
- prev
- next
- post All these variables are of the same type, they represent a post.
The prev and next are the post before this one, or the one
after this one when put in chronological order.
These variables have the following keys
tags
a list of tags (a tag has keysname
andslug
)slug
the slug of the postdate
the date of postingtext
the HTML version of the posts body.title
The title of the post
Step 6. Including the content
We improve the base.tmpl
to include the content generated by the sub templates.
This is done by adding the line {$raw |noAutoescape}
to the template in the body section.
The |noAutoescape
is added because the $raw
variable is already html and we do
not want the templating engine to escape the html.
So the base.tmpl
now looks 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}
If we run this through coleslaw we do not see any difference and this is because
we have not modified the index.tmpl
and the post.tmpl
.
A simple index.tmpl
looks like this
{namespace coleslaw.theme.trivial}
{template index}
{foreach $post in $index.posts}
<h1>{$post.title}</h1>
{$post.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}
Wrapup of Example
Basically all the files are now populated with content. There are a few huge gaps still, for example there is no linking between the pages. So although the archives are fully populated, you cannot get there from the front page, but if you know the URL it is there.
However linking is not very difficult see next section.
Note on adding links
As mentioned in the beginning, most files have a file name which is a slug of some sort. So if you want to create a link to a tag file you should do something like this:
<a href="${config.domain}/tags/$tag.slug">$tag.name</a>
Note on adding style sheets
Style sheets are nothing special. In order to get them to work, you
have to add a css
folder in your theme folder. The content of this folder
will be copied to the css
folder at the place where the html
is generated.
Now to actual use them, you have to include in the head section of the html
(which is in the base.tmpl
) a link to include the CSS.