Recently Written · git

coleslaw

Emacs mode for the "Coleslaw" site generator written in Common Lisp.

git clone https://github.com/equwal/coleslaw

Log | Files | Refs


docs/themes.md (7967 bytes)

1 # Themes
2 
3 The theming support in coleslaw is very flexible and relatively easy
4 to use. However it does require some knowledge of HTML, CSS, and how
5 coleslaw processes content.
6 
7 To understand how coleslaw works, a look at the [hacking][hck]
8 documentation will prove useful. This document focuses mainly on the
9 template engine and how you can influence the resulting HTML.
10 
11 ## High-Level Overview
12 
13 Themes are written using [Closure Templates][clt]. Those templates are
14 then compiled into functions that Lisp calls with the blog data to get
15 HTML. Since the Lisp code to use theme functions is already written,
16 your theme must follow a few rules.
17 
18 Every theme **must** be in a folder under "themes/" named after the
19 theme. The theme's templates must start with a namespace declaration
20 like so: `{namespace coleslaw.theme.$MY-THEME-NAME}`.
21 
22 A theme must have three templates which take *specific arguments*
23 (to be described later).
24 1. Base
25 2. Post
26 3. Index
27 
28 ## Two types of pages
29 
30 Coleslaw generates two types of pages: `index` pages and `post` pages.
31 Every page other than those in the `posts/` directory is an `index`.
32 
33 **Every** page uses the `base.tmpl` and fills in the content using
34 either the `post` or `index` templates. No important logic should be
35 in *any* template, they are only used to provide a consistent layout.
36 
37 *  `base.tmpl` This template generates the outer shell of the HTML.
38    It keeps a consistent look and feel for all pages in the blog. The
39    actual content (i.e., not header/footer/css) comes from other templates.
40 
41 *  `index.tmpl` This template generates the content of the `index` pages.
42    That is, any page with more than one content object, e.g. the homepage.
43 
44 *  `post.tmpl` This templates generates content for the individual posts.
45 
46 Here's a visual example to make things clearer:
47 ```
48 INDEX HTML FILES                    INDIVIDUAL POST HTML FILES
49 |-------------------------|         |-------------------------|
50 | base.tmpl               |         | base.tmpl               |
51 |                         |         |                         |
52 |  |-------------------|  |         | |------------------|    |
53 |  |  index.tmpl       |  |         | | post.tmpl        |    |
54 |  |                   |  |         | |                  |    |
55 |  |-------------------|  |         | |------------------|    |
56 |                         |         |                         |
57 |-------------------------|         |-------------------------|
58 ```
59 
60 ## Note on Style Sheets (css)
61 
62 If you only want to change the way the blog is styled, it is probably
63 simplest to either modify the existing default theme, `hyde`, or copy
64 it in entirety and then tweak only the CSS of your new theme. A large
65 amount of visual difference can be had with a minimum of (or no)
66 template hacking. There is plenty of advice on CSS styling on the web.
67 I'm no expert but feel free to send pull requests modifying a theme's
68 CSS or improving this section, perhaps by recommending a CSS resource.
69 
70 ## Creating a Theme from Scratch (with code)
71 
72 ### Step 1. Create the directory.
73 
74 A theme name must be a valid lisp symbol. For this example, we'll use
75 `trivial`, so create a `themes/trivial` directory in the *coleslaw* repo.
76 
77 ### Step 2. Create the templates.
78 
79 As described above, we need 3 template files `base.tmpl`, `post.tmpl`
80 and `index.tmpl`. Initially, let's just create the simplest theme that
81 compiles correctly.
82 
83 base.tmpl:
84 ```
85 {namespace coleslaw.theme.trivial}
86 {template base}
87 {/template}
88 ```
89 post.tmpl:
90 ```
91 {namespace coleslaw.theme.trivial}
92 {template post}
93 {/template}
94 ```
95 index.tmpl:
96 ```
97 {namespace coleslaw.theme.trivial}
98 {template index}
99 {/template}
100 ```
101 
102 This will create three template functions that coleslaw can find, named
103 `base`, `post`, and `index`.
104 
105 ### Step 3. Use it in your config.
106 
107 At this point, you can change the `:theme` in your `.coleslawrc` to
108 `trivial` and then generate your blog with `(coleslaw:main)`. However,
109 all the HTML files will be empty because our templates are empty!
110 
111 ### Intermezzo I, The Templating Language
112 
113 The templating language is documented [elsewhere][clt].
114 However as a short primer:
115 
116 *  Everything is output literally, except template commands.
117 *  Template commands are enclosed in `{` and `}`.
118 *  Variables, which are provided by coleslaw, can be referenced
119    inside a template command. So to use a variable you have to say
120    `{$variable}` or `{$variable.key}`.
121    **WARNING**: At present, cl-closure-template does not have great debugging.
122    If you typo this, e.g. `${variable}`, you will receive an *uninformative*
123    and apparently unrelated error. Also, attempted access of non-existent keys
124    fails silently. We are exploring options for making debugging easier in a
125    future release.
126 *  If statements are written as `{if ...} ... {else} ... {/if}`.
127    Typical examples are: `{if $injections.body} ... {/if}` or
128    `{if not isLast($link)} ... {/if}`.
129 *  Loops can be written as `{foreach $var in $sequence} ... {/foreach}`.
130 
131 ### Intermezzo II, Variables provided by Coleslaw
132 
133 The variable that should be available to all templates is:
134 - **config**       This contains the `.coleslawrc` content.
135 
136 #### Base Template Variables
137 
138 - **raw**          HTML generated by a sub template, `index` or `post`.
139 - **content**      The object which was used to generate **raw**.
140 - **pubdate**      A string containing the publication date.
141 - **injections**   A list containing the injections. Injections are used
142                    by plugins mostly to add Javascript to the page.
143 
144 #### Index Template Variables
145 
146 - **tags**         A list containing all the tags, each with keys
147                    `name` and `url`.
148 - **months**       A list of all the content months, each with keys
149                    `name` and `url`.
150 - **index**        This is the meat of the content. This variable has
151                    the following keys:
152    - `content`, a list of content (see below)
153    - `name`,  a name to use in links or href tags
154    - `title`, a title to use in H1 or header tags
155 - **prev**         Nil or the previous index with keys: `url` and `title`.
156 - **next**         Nil or the next index with keys: `url` and `title`.
157 
158 #### Post Template Variable
159 
160 - **prev**
161 - **next**
162 - **post**         All these variables are post objects. **prev** and
163                    **next** are the adjacent posts when put in
164                    chronological order. Each post has the following keys:
165    - `url`, the relative url of the post
166    - `tags`, a list of tags (each with keys `name` and `url`)
167    - `date`, the date of posting
168    - `text`, the HTML of the post's body
169    - `title`, the title of the post
170    - `excerpt`, the excerpt of the post, same as `text` by default
171 
172 ### Step 4. Include the content
173 
174 *NOTE*: We can keep the template engine from escaping raw HTML by
175 adding a `|noAutoescape` clause to commands, like so: `{$raw |noAutoescape}`.
176 
177 Let's now rewrite `base.tmpl` like this:
178 ```
179 {namespace coleslaw.theme.trivial}
180 {template base}
181 <html>
182   <head><title>Trivial Theme For Coleslaw</title></head>
183   <body>
184     <h1>All my pages have this title</h1>
185     {$raw |noAutoescape}
186   </body>
187 </html>
188 {/template}
189 ```
190 
191 A simple `index.tmpl` looks like this:
192 ```
193 {namespace coleslaw.theme.trivial}
194 {template index}
195 {foreach $obj in $index.content}
196 <h1>{$object.title}</h1>
197   {$object.excerpt |noAutoescape}
198 {/foreach}
199 {/template}
200 ```
201 
202 And a simple `post.tmpl` is similarly:
203 ```
204 {namespace coleslaw.theme.trivial}
205 {template post}
206 <h1>{$post.title}</h1>
207   {$post.text |noAutoescape}
208 {/template}
209 ```
210 
211 ### Conclusion
212 
213 All of the files are now populated with content. There are still no links
214 between the pages so navigation is cumbersome but adding links is simple.
215 Just do: `<a href="{$config.domain}/{$object.url}">{$object.name}</a>`.
216 
217 [clt]: https://developers.google.com/closure/templates/
218 [ovr]: https://github.com/redline6561/coleslaw/blob/master/docs/overview.md
219 [hck]: https://github.com/redline6561/coleslaw/blob/master/docs/hacking.md