Added first draft of theme documentation

This commit is contained in:
Willem Rein Oudshoorn 2013-04-26 17:19:22 +02:00 committed by Brit Butler
parent 361316f7b3
commit 77d1881927

377
docs/themes.md Normal file
View file

@ -0,0 +1,377 @@
# 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][clt], 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:
1. Coleslaw read a directory containt `.post` files and processes them
into HTML fragments.
2. 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
3. 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:
1. **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.
2. **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` or `class` 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 the `index` 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:
1. It is a valid lisp symbol name (not containing `:`)
2. 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][clt].
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` or `post.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 rendered
- `posts` 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 keys `name` and `slug`)
- `slug` the slug of the post
- `date` the date of posting
- `text` 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.
[clt]: https://developers.google.com/closure/templates/