@@ -0,0 +1,87 @@
2+title: Tutorial (Part VI)
3+what: explains how to use categories instead of tags
8+Most people familiar with "tags" will also know the concept "categories".
10+
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.
15+
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
24+Tags are located in the `tags` metadata field. Since one post can only belong
25+in one category, a different approach was chosen here. The category of a post
26+is determined by the subfolder it is in. Here you see the directory layout for
27+our posts using categories:
31+ | |-- 2009-11-05-a-first-post.markdown
32+ | |-- 2009-11-28-a-third-post.markdown
33+ | `-- 2009-12-04-this-blog-aint-dead.markdown
35+ |-- 2009-11-10-another-post.markdown
36+ `-- 2009-12-23-almost-christmas.markdown
38+Because we find all our posts in different subdirectories, sorting them is a
39+little harder: we still want them sorted by date, so it boils down to sorting
40+them by "base name". I hope it does not surprise you Hakyll provides a function
44+postPaths <- liftM (reverse . sortByBaseName)
45+ (getRecursiveContents "posts")
48+Now, we can use the `readCategoryMap` function instead of `readTagMap`, which
49+has the same signature, but assigns categories based on the folders the posts
53+categoryMap <- readCategoryMap "categoryMap" renderablePosts
56+The rest of the `hakyll.hs` is very similar to the one in the previous
57+tutorial, except we want to render a category list instead of a tag cloud.
59+## Rendering a category list
61+Because rendering a category list is quite easy, and it would be hard to
62+write a "general" function for this, hakyll does not provide such a function -
63+but it is not hard to write. First, we write an auxiliary function that produces
64+a list item for one category:
67+categoryListItem category posts =
68+ "<li>" ++ link category (categoryToURL category)
69+ ++ " - " ++ show (length posts) ++ " items.</li>"
72+This is nothing more that some string concatenation. The function that applies
73+this on every element in the `TagMap` is more interesting:
76+categoryList :: TagMap -> String
77+categoryList = uncurry categoryListItem <=< toList
80+This function might seem a little harder to understand, and figuring out how it
81+works is left as an exercise for the reader[^1].
83+[^1]: Hint: `>>=` is `concatMap` in the list monad.
85+We then add this to our index page, and we are done. Feel free to hack around
86+with the source code. If you still have questions, feel free to ask them at the
87+[google discussion group](http://groups.google.com/group/hakyll).