on master help sign in
All ready for the 4.3 release!
a591b16Jasper Van der Jeugt
data/example/posts/2012-10-07-rosa-rosa-rosam.markdown+1
@@ -1,5 +1,6 @@
1---
1---
2title: Rosa Rosa Rosam
2title: Rosa Rosa Rosam
3+author: Ovidius
3---
4---
4
5
5Suspendisse pharetra ullamcorper sem et auctor. Suspendisse vitae tellus eu
6Suspendisse pharetra ullamcorper sem et auctor. Suspendisse vitae tellus eu
data/example/posts/2012-12-07-tu-quoque.markdown+1
@@ -1,5 +1,6 @@
1---
1---
2title: Tu Quoque
2title: Tu Quoque
3+author: Julius
3---
4---
4
5
5Vestibulum leo turpis, dignissim quis ultrices sit amet, iaculis ac ligula.
6Vestibulum leo turpis, dignissim quis ultrices sit amet, iaculis ac ligula.
data/example/templates/post.html+6−1
@@ -1,3 +1,8 @@
1−<div class="info">Posted on $date$</div>
1+<div class="info">
2+ Posted on $date$
3+ $if(author)$
4+ by $author$
5+ $endif$
6+</div>
2
7
3$body$
8$body$
web/releases.markdown+25
@@ -4,6 +4,31 @@ title: Releases
4
4
5# Releases
5# Releases
6
6
7+## Hakyll 4.3.0.0
8+
9+- Add conditionals, partials and for loops to the template system (includes a
10+ contribution by Ivan N. Veselov)
11+
12+- Improvements to the preview functionality on windows (contribution by Jorge
13+ Israel Peña)
14+
15+- Add pagination support (contribution by Anton Dubovik)
16+
17+- Slight speedup for the Hakyll cache (contribution by justnoxx)
18+
19+- Add teaser functionality (contribution by Ivan N. Veselov)
20+
21+- Make `./site check` work with scheme-relative URLs (contribution by Simonas
22+ Kazlauskas)
23+
24+- The `./site deploy` command can now be customized with Haskell code
25+ (contribution by Samuel Tardieu)
26+
27+- Use `hsnotify` for proper polling instead of sleep loop on all platforms
28+ (contribution by Simonas Kazlauskas)
29+
30+- More useful debug info available
31+
7## Hakyll 4.2.2.0
32## Hakyll 4.2.2.0
8
33
9- Fix issue with `Alternative` instance of `Compiler`
34- Fix issue with `Alternative` instance of `Compiler`
web/tutorials/04-compilers.markdown+114−14
@@ -145,25 +145,108 @@ compile $
145 pandocCompiler >>= loadAndApplyTemplate "templates/post.html" postCtx
145 pandocCompiler >>= loadAndApplyTemplate "templates/post.html" postCtx
146```
146```
147
147
148+Control flow in templates
149+-------------------------
150+
151+Sometimes string interpolation does not suffice, and you want a little more
152+control over how your templates are layed out. Hakyll provides a few control
153+structures for this. The syntax for these structures was based on the syntax
154+used in pandoc templates, since Hakyll already has tight integration with
155+pandoc.
156+
157+### Conditionals
158+
159+In `templates/post.html` of the example site we generated using `hakyll-init`,
160+we see an example of a conditional:
161+
162+```html
163+<div class="info">
164+ Posted on $date$
165+ $if(author)$
166+ by $author$
167+ $endif$
168+</div>
169+```
170+
171+This example should be pretty straightforward. One important thing to notice is
172+that `$if(foo)$` **does not** check the truth value of `$foo$`: it merely checks
173+if such a key is present.
174+
175+Note that an if-else form is supported as well:
176+
177+```html
178+<div class="info">
179+ Posted on $date$
180+ $if(author)$
181+ by $author$
182+ $else$
183+ by some unknown author
184+ $endif$
185+</div>
186+```
187+
188+### Partials
189+
190+Partials allow you to [DRY] up your templates by putting repetitive actions into
191+separate template files. You can then include them using
192+`$partial("filename.html")$.
193+
194+[DRY]: http://en.wikipedia.org/wiki/Don%27t_repeat_yourself
195+
196+An example can be found in `templates/archive.html`:
197+
198+```html
199+Here you can find all my previous posts:
200+$partial("templates/post-list.html")$
201+```
202+
203+This partial is just another template and uses the same syntax. Note that in
204+order to use something like this, we also need to load the partial template in
205+our `site.hs`:
206+
207+```haskell
208+match "templates/post-list.html" $ compile templateCompiler
209+```
210+
211+Fortunately, we usually don't need to add this since we already have:
212+
213+```haskell
214+match "templates/*" $ compile templateCompiler
215+```
216+
148−## Producing a list of items
217+### Producing a list of items: for
149
218
150At this point, everything in the example site we generated should be clear to
219At this point, everything in the example site we generated should be clear to
151you, except for how we produce the list of posts in `archive.html` and
220you, except for how we produce the list of posts in `archive.html` and
152−`index.html`.
221+`index.html`. Let's look at the `templates/post-list.html` template:
222+
223+```html
224+<ul>
225+ $for(posts)$
226+ <li>
227+ <a href="$url$">$title$</a> - $date$
228+ </li>
229+ $endfor$
230+</ul>
231+```
153
232
154−However, this really isn't hard and just uses the things we saw before: loading
233+This uses the `$for(foo)$` construct. This construct allows you loop over a
155−other items and applying templates.
234+list, in this case, `$posts$`. Inside the body of this for loop, all fields
235+refer to the current post, e.g.: `$url$`, `$title$` and `$date$`.
156
236
157−We can reproduce a list of items in the archive using the following code:
237+Of course, $posts$ does not magically appear. We have to specify this in
238+`site.hs`. Let's look at how `archive.html` is generated:
158
239
159```haskell
240```haskell
160−compile $ do
161− posts <- recentFirst =<< loadAll "posts/*"
241+posts <- recentFirst =<< loadAll "posts/*"
162− itemTpl <- loadBody "templates/post-item.html"
242+let archiveCtx =
163− list <- applyTemplateList itemTpl postCtx posts
243+ listField "posts" postCtx (return posts) `mappend`
164− makeItem list
244+ constField "title" "Archives" `mappend`
245+ defaultContext
165```
246```
166
247
248+We discussed `loadAll` earlier in this tutorial.
249+
167`recentFirst` sorts items by date. This relies on the convention that posts are
250`recentFirst` sorts items by date. This relies on the convention that posts are
168always named `YYYY-MM-DD-title.extension` in Hakyll -- or that the date must be
251always named `YYYY-MM-DD-title.extension` in Hakyll -- or that the date must be
169present in the metadata.
252present in the metadata.
@@ -172,7 +255,24 @@ present in the metadata.
172recentFirst :: [Item a] -> Compiler [Item a]
255recentFirst :: [Item a] -> Compiler [Item a]
173```
256```
174
257
175−After loading and sorting the items, we load a template for the posts.
258+After loading and sorting the items, we use `listField` to create the `$posts$`
176−`applyTemplateList` applies this template to every post and concatenates the
259+key.
177−result, which is a simple `String`. After that, we need `makeItem` to wrap the
260+
178−returned `String` to `Item String`.
261+```haskell
262+listField :: String -> Context a -> Compiler [Item a] -> Context b
263+```
264+
265+The first parameter is simply the name of the key (`"posts"`). Secondly we have
266+a `Context` with which all items should be rendered -- for our example site, we
267+already wrote such a `Context` for posts: `postCtx`. Lastly, we have a
268+`Compiler` which loads the items. We already loaded the items so we can just use
269+`return posts`.
270+
271+The following snippet would produce the same result:
272+
273+```haskell
274+let archiveCtx =
275+ listField "posts" postCtx (recentFirst =<< loadAll "posts/*") `mappend`
276+ constField "title" "Archives" `mappend`
277+ defaultContext
278+```