on master help sign in
Updated tutorial about categoryblog.
commit193dc6d3d8d7bca76efd30270bd34ca81a676bf2 authorJasper Van der Jeugt <jaspervdj@gmail.com> dateWed 31 Mar 2010, 13:51 (17 years ago) parentd108263
5 files changed+105−2
examples/hakyll/images/tutorial6-categories.png → examples/hakyll/images/tutorial8-categories.png examples/hakyll/images/tutorial6-tags.png → examples/hakyll/images/tutorial8-tags.png examples/hakyll/tutorials/part07.markdown+6 examples/hakyll/tutorials/part08.markdown+97 src/Text/Hakyll/HakyllAction.hs+2−2
examples/hakyll/images/tutorial6-categories.png → examples/hakyll/images/tutorial8-categories.pngrenamed

Binary file not shown.

examples/hakyll/images/tutorial6-tags.png → examples/hakyll/images/tutorial8-tags.pngrenamed

Binary file not shown.

examples/hakyll/tutorials/part07.markdown+6
@@ -58,3 +58,9 @@ A few examples:
5858
5959The benefit of this is simply prettier URL's. That is, if you consider
6060`example.com/about` prettier than `example.com/about.html`.
61+
62+## The gist of it
63+
64+- Auto-compilation is handy, but a rebuild is recommended before deploying your
65+ site.
66+- You can enable pretty URL's in Hakyll. It is, however, not the default.
examples/hakyll/tutorials/part08.markdownnew file+97
@@ -0,0 +1,97 @@
1+---
2+title: CategoryBlog
3+what: explains how to use categories instead of tags
4+---
5+
6+## Categories
7+
8+Most people familiar with "tags" will also know the concept "categories".
9+
10+![Tags illustration]($root/images/tutorial8-tags.png)
11+
12+In fact, tags are harder to implement because they have to be represented as a
13+many-to-many relation, and categories are a simple 1-to-many relation.
14+
15+![Tags illustration]($root/images/tutorial8-categories.png)
16+
17+This is also the reason you can "simulate" categories using tags. In this
18+tutorial we will adapt the blog to use categories instead of tags. Here is
19+[a zip file](examples/categoryblog.zip) containing the files used in this
20+tutorial.
21+
22+## About category support
23+
24+Categories are simpler, but they are usually used in custom ways. That's why
25+Hakyll provides less "standard" functions to deal with them. But this gives us
26+another chance to learn some of the things we can do with Hakyll.
27+
28+## Reading Categories
29+
30+Tags are located in the `tags` metadata field. Since one post can only belong
31+in one category, a different approach was chosen here. The category of a post
32+is determined by the subfolder it is in. Here you see the directory layout for
33+our posts using categories:
34+
35+ posts
36+ |-- coding
37+ | |-- 2009-11-05-a-first-post.markdown
38+ | |-- 2009-11-28-a-third-post.markdown
39+ | `-- 2009-12-04-this-blog-aint-dead.markdown
40+ `-- random
41+ |-- 2009-11-10-another-post.markdown
42+ `-- 2009-12-23-almost-christmas.markdown
43+
44+Because we find all our posts in different subdirectories, sorting them is a
45+little harder: we still want them sorted by date, so it boils down to sorting
46+them by "base name". I hope it does not surprise you Hakyll provides a function
47+for that:
48+
49+~~~~~{.haskell}
50+postPaths <- liftM (reverse . sortByBaseName)
51+ (getRecursiveContents "posts")
52+~~~~~
53+
54+We reverse them again, because we want the most recent posts first. Now, we can
55+use the `readCategoryMap` function instead of `readTagMap`, which has the same
56+signature, but assigns categories based on the folders the posts are in.
57+
58+~~~~~{.haskell}
59+categoryMap <- readCategoryMap "categoryMap" renderablePosts
60+~~~~~
61+
62+The rest of the `hakyll.hs` is very similar to the one in the previous
63+tutorial, except we want to render a category list instead of a tag cloud.
64+
65+## Rendering a category list
66+
67+Because rendering a category list is quite easy, and it would be hard to
68+write a "general" function for this, hakyll does not provide such a function --
69+but it is not hard to write. First, we write an auxiliary function that produces
70+a list item for one category:
71+
72+~~~~~{.haskell}
73+categoryListItem category posts =
74+ "<li>" ++ link category (categoryToUrl category)
75+ ++ " - " ++ show (length posts) ++ " items.</li>"
76+~~~~~
77+
78+This is nothing more that some basic string concatenation to create a `li` HTML
79+element. The function that applies this on every element in the `TagMap` is more
80+interesting:
81+
82+~~~~~{.haskell}
83+categoryList :: HakyllAction TagMap String
84+categoryList = arr $ uncurry categoryListItem <=< toList
85+~~~~~
86+
87+This function might seem a little harder to understand if you are not familiar
88+with the `<=<` operator -- but it's just right-to-left monad composition in the
89+list monad. `uncurry categoryListItem <=< toList` is a pure function we want to
90+execute on the `TagMap`. But this is not possible in Hakyll[^1]. We need to make
91+an arrow of this function. The `arr` function solves this problem easily.
92+
93+[^1]: This is a feature, not a bug. It helps dependency handling.
94+
95+We then add this to our index page, and we are done. Feel free to hack around
96+with the source code. If you still have questions, feel free to ask them at the
97+[google discussion group](http://groups.google.com/group/hakyll).
src/Text/Hakyll/HakyllAction.hs+2−2
@@ -70,8 +70,8 @@ runHakyllActionIfNeeded action = do
7070-- | Chain a number of @HakyllAction@ computations.
7171chain :: [HakyllAction a a] -- ^ Actions to chain.
7272 -> HakyllAction a a -- ^ Resulting action.
73−chain [] = id
74−chain list@(_:_) = foldl1 (>>>) list
73+chain [] = id
74+chain list = foldl1 (>>>) list
7575
7676instance Category HakyllAction where
7777 id = HakyllAction