2013-04-26 17:19:22 +02:00
|
|
|
# Themes
|
|
|
|
|
2013-04-28 16:12:08 -04:00
|
|
|
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.
|
|
|
|
|
2014-05-02 17:02:31 -04:00
|
|
|
To understand how coleslaw works, a look at the [hacking][hck]
|
|
|
|
documentation will prove useful. This document focuses mainly on the
|
|
|
|
template engine and how you can influence the resulting HTML.
|
2013-04-28 16:12:08 -04:00
|
|
|
|
|
|
|
## High-Level Overview
|
|
|
|
|
|
|
|
Themes are written using [Closure Templates][clt]. 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).
|
|
|
|
1. Base
|
|
|
|
2. Post
|
|
|
|
3. Index
|
|
|
|
|
|
|
|
## Two types of pages
|
|
|
|
|
|
|
|
Coleslaw generates two types of pages: `index` pages and `post` pages.
|
|
|
|
Every page other than those in the `posts/` directory is an `index`.
|
2014-05-02 17:02:31 -04:00
|
|
|
|
2013-04-28 16:12:08 -04:00
|
|
|
**Every** page uses the `base.tmpl` and fills in the content using
|
2014-05-02 17:02:31 -04:00
|
|
|
either the `post` or `index` templates. No important logic should be
|
2014-09-05 17:05:43 -04:00
|
|
|
in *any* template, they are only used to provide a consistent layout.
|
2013-04-28 16:12:08 -04:00
|
|
|
|
|
|
|
* `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 | |
|
|
|
|
| | | | | | | |
|
|
|
|
| |-------------------| | | |------------------| |
|
|
|
|
| | | |
|
|
|
|
|-------------------------| |-------------------------|
|
|
|
|
```
|
|
|
|
|
|
|
|
## Note on Style Sheets (css)
|
|
|
|
|
|
|
|
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.
|
2014-09-05 17:05:43 -04:00
|
|
|
I'm no expert but feel free to send pull requests modifying a theme's
|
2014-05-02 17:02:31 -04:00
|
|
|
CSS or improving this section, perhaps by recommending a CSS resource.
|
2013-04-26 17:19:22 +02:00
|
|
|
|
|
|
|
## Creating a Theme from Scratch (with code)
|
|
|
|
|
2013-04-28 16:12:08 -04:00
|
|
|
### Step 1. Create the directory.
|
2013-04-26 17:19:22 +02:00
|
|
|
|
2013-04-28 16:12:08 -04:00
|
|
|
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.
|
2013-04-26 17:19:22 +02:00
|
|
|
|
2013-04-28 16:12:08 -04:00
|
|
|
### Step 2. Create the templates.
|
2013-04-26 17:19:22 +02:00
|
|
|
|
2013-04-28 16:12:08 -04:00
|
|
|
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.
|
2013-04-26 17:19:22 +02:00
|
|
|
|
|
|
|
base.tmpl:
|
2013-04-28 16:12:08 -04:00
|
|
|
```
|
|
|
|
{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`.
|
|
|
|
|
|
|
|
### Step 3. Use it in your config.
|
|
|
|
|
|
|
|
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!
|
2013-04-26 17:19:22 +02:00
|
|
|
|
|
|
|
### Intermezzo I, The Templating Language
|
|
|
|
|
2013-04-28 16:12:08 -04:00
|
|
|
The templating language is documented [elsewhere][clt].
|
2013-04-26 17:19:22 +02:00
|
|
|
However as a short primer:
|
|
|
|
|
2013-04-28 16:12:08 -04:00
|
|
|
* Everything is output literally, except template commands.
|
2014-09-05 17:05:43 -04:00
|
|
|
* Template commands are enclosed in `{` and `}`.
|
2013-04-28 16:12:08 -04:00
|
|
|
* Variables, which are provided by coleslaw, can be referenced
|
|
|
|
inside a template command. So to use a variable you have to say
|
|
|
|
`{$variable}` or `{$variable.key}`.
|
2014-09-05 17:05:43 -04:00
|
|
|
**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.
|
2013-04-28 16:12:08 -04:00
|
|
|
* If statements are written as `{if ...} ... {else} ... {/if}`.
|
|
|
|
Typical examples are: `{if $injections.body} ... {/if}` or
|
|
|
|
`{if not isLast($link)} ... {/if}`.
|
|
|
|
* Loops can be written as `{foreach $var in $sequence} ... {/foreach}`.
|
2013-04-26 17:19:22 +02:00
|
|
|
|
2013-04-28 16:12:08 -04:00
|
|
|
### Intermezzo II, Variables provided by Coleslaw
|
2013-04-26 17:19:22 +02:00
|
|
|
|
2014-05-02 17:02:31 -04:00
|
|
|
The variable that should be available to all templates is:
|
2013-04-28 16:12:08 -04:00
|
|
|
- **config** This contains the `.coleslawrc` content.
|
2013-04-26 17:19:22 +02:00
|
|
|
|
|
|
|
#### Base Template Variables
|
|
|
|
|
2013-04-28 16:12:08 -04:00
|
|
|
- **raw** HTML generated by a sub template, `index` or `post`.
|
|
|
|
- **content** The object which was used to generate **raw**.
|
|
|
|
- **pubdate** A string containing the publication date.
|
|
|
|
- **injections** A list containing the injections. Injections are used
|
|
|
|
by plugins mostly to add Javascript to the page.
|
2013-04-26 17:19:22 +02:00
|
|
|
|
|
|
|
#### Index Template Variables
|
|
|
|
|
2013-04-28 16:12:08 -04:00
|
|
|
- **tags** A list containing all the tags, each with keys
|
2014-09-05 17:05:43 -04:00
|
|
|
`name` and `url`.
|
|
|
|
- **months** A list of all the content months, each with keys
|
|
|
|
`name` and `url`.
|
2013-04-28 16:12:08 -04:00
|
|
|
- **index** This is the meat of the content. This variable has
|
2014-05-02 17:02:31 -04:00
|
|
|
the following keys:
|
2014-06-03 11:42:17 -04:00
|
|
|
- `content`, a list of content (see below)
|
2014-09-05 17:05:43 -04:00
|
|
|
- `name`, a name to use in links or href tags
|
|
|
|
- `title`, a title to use in H1 or header tags
|
|
|
|
- **prev** Nil or the previous index with keys: `url` and `title`.
|
|
|
|
- **next** Nil or the next index with keys: `url` and `title`.
|
2013-04-26 17:19:22 +02:00
|
|
|
|
|
|
|
#### Post Template Variable
|
|
|
|
|
2013-04-28 16:12:08 -04:00
|
|
|
- **prev**
|
|
|
|
- **next**
|
|
|
|
- **post** All these variables are post objects. **prev** and
|
|
|
|
**next** are the adjacent posts when put in
|
|
|
|
chronological order. Each post has the following keys:
|
2014-09-05 17:05:43 -04:00
|
|
|
- `url`, the relative url of the post
|
|
|
|
- `tags`, a list of tags (each with keys `name` and `url`)
|
2013-04-28 16:12:08 -04:00
|
|
|
- `date`, the date of posting
|
|
|
|
- `text`, the HTML of the post's body
|
|
|
|
- `title`, the title of the post
|
2017-03-22 18:53:24 +01:00
|
|
|
- `excerpt`, the excerpt of the post, same as `text` by default
|
2013-04-28 16:12:08 -04:00
|
|
|
|
|
|
|
### Step 4. Include the content
|
|
|
|
|
|
|
|
*NOTE*: 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}
|
2014-06-03 11:42:17 -04:00
|
|
|
{foreach $obj in $index.content}
|
2014-09-05 17:05:43 -04:00
|
|
|
<h1>{$object.title}</h1>
|
2017-03-22 18:53:24 +01:00
|
|
|
{$object.excerpt |noAutoescape}
|
2013-04-28 16:12:08 -04:00
|
|
|
{/foreach}
|
|
|
|
{/template}
|
|
|
|
```
|
|
|
|
|
|
|
|
And a simple `post.tmpl` is similarly:
|
|
|
|
```
|
|
|
|
{namespace coleslaw.theme.trivial}
|
|
|
|
{template post}
|
|
|
|
<h1>{$post.title}</h1>
|
|
|
|
{$post.text |noAutoescape}
|
|
|
|
{/template}
|
|
|
|
```
|
|
|
|
|
|
|
|
### Conclusion
|
|
|
|
|
|
|
|
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.
|
2014-09-05 17:05:43 -04:00
|
|
|
Just do: `<a href="{$config.domain}/{$object.url}">{$object.name}</a>`.
|
2013-04-26 17:19:22 +02:00
|
|
|
|
|
|
|
[clt]: https://developers.google.com/closure/templates/
|
2013-04-28 16:12:08 -04:00
|
|
|
[ovr]: https://github.com/redline6561/coleslaw/blob/master/docs/overview.md
|
2014-04-14 17:10:03 -04:00
|
|
|
[hck]: https://github.com/redline6561/coleslaw/blob/master/docs/hacking.md
|