From 193dc6d3d8d7bca76efd30270bd34ca81a676bf2 Mon Sep 17 00:00:00 2001 From: Jasper Van der Jeugt Date: Wed, 31 Mar 2010 13:51:28 +0200 Subject: Updated tutorial about categoryblog. --- examples/hakyll/images/tutorial6-categories.png | Bin 9377 -> 0 bytes examples/hakyll/images/tutorial6-tags.png | Bin 8631 -> 0 bytes examples/hakyll/images/tutorial8-categories.png | Bin 0 -> 9377 bytes examples/hakyll/images/tutorial8-tags.png | Bin 0 -> 8631 bytes examples/hakyll/tutorials/part07.markdown | 6 ++ examples/hakyll/tutorials/part08.markdown | 97 ++++++++++++++++++++++++ src/Text/Hakyll/HakyllAction.hs | 4 +- 7 files changed, 105 insertions(+), 2 deletions(-) delete mode 100644 examples/hakyll/images/tutorial6-categories.png delete mode 100644 examples/hakyll/images/tutorial6-tags.png create mode 100644 examples/hakyll/images/tutorial8-categories.png create mode 100644 examples/hakyll/images/tutorial8-tags.png create mode 100644 examples/hakyll/tutorials/part08.markdown diff --git a/examples/hakyll/images/tutorial6-categories.png b/examples/hakyll/images/tutorial6-categories.png deleted file mode 100644 index 0567917..0000000 Binary files a/examples/hakyll/images/tutorial6-categories.png and /dev/null differ diff --git a/examples/hakyll/images/tutorial6-tags.png b/examples/hakyll/images/tutorial6-tags.png deleted file mode 100644 index d8ae73e..0000000 Binary files a/examples/hakyll/images/tutorial6-tags.png and /dev/null differ diff --git a/examples/hakyll/images/tutorial8-categories.png b/examples/hakyll/images/tutorial8-categories.png new file mode 100644 index 0000000..0567917 Binary files /dev/null and b/examples/hakyll/images/tutorial8-categories.png differ diff --git a/examples/hakyll/images/tutorial8-tags.png b/examples/hakyll/images/tutorial8-tags.png new file mode 100644 index 0000000..d8ae73e Binary files /dev/null and b/examples/hakyll/images/tutorial8-tags.png differ diff --git a/examples/hakyll/tutorials/part07.markdown b/examples/hakyll/tutorials/part07.markdown index d41450e..3aeb953 100644 --- a/examples/hakyll/tutorials/part07.markdown +++ b/examples/hakyll/tutorials/part07.markdown @@ -58,3 +58,9 @@ A few examples: The benefit of this is simply prettier URL's. That is, if you consider `example.com/about` prettier than `example.com/about.html`. + +## The gist of it + +- Auto-compilation is handy, but a rebuild is recommended before deploying your + site. +- You can enable pretty URL's in Hakyll. It is, however, not the default. diff --git a/examples/hakyll/tutorials/part08.markdown b/examples/hakyll/tutorials/part08.markdown new file mode 100644 index 0000000..b786534 --- /dev/null +++ b/examples/hakyll/tutorials/part08.markdown @@ -0,0 +1,97 @@ +--- +title: CategoryBlog +what: explains how to use categories instead of tags +--- + +## Categories + +Most people familiar with "tags" will also know the concept "categories". + +![Tags illustration]($root/images/tutorial8-tags.png) + +In fact, tags are harder to implement because they have to be represented as a +many-to-many relation, and categories are a simple 1-to-many relation. + +![Tags illustration]($root/images/tutorial8-categories.png) + +This is also the reason you can "simulate" categories using tags. In this +tutorial we will adapt the blog to use categories instead of tags. Here is +[a zip file](examples/categoryblog.zip) containing the files used in this +tutorial. + +## About category support + +Categories are simpler, but they are usually used in custom ways. That's why +Hakyll provides less "standard" functions to deal with them. But this gives us +another chance to learn some of the things we can do with Hakyll. + +## Reading Categories + +Tags are located in the `tags` metadata field. Since one post can only belong +in one category, a different approach was chosen here. The category of a post +is determined by the subfolder it is in. Here you see the directory layout for +our posts using categories: + + posts + |-- coding + | |-- 2009-11-05-a-first-post.markdown + | |-- 2009-11-28-a-third-post.markdown + | `-- 2009-12-04-this-blog-aint-dead.markdown + `-- random + |-- 2009-11-10-another-post.markdown + `-- 2009-12-23-almost-christmas.markdown + +Because we find all our posts in different subdirectories, sorting them is a +little harder: we still want them sorted by date, so it boils down to sorting +them by "base name". I hope it does not surprise you Hakyll provides a function +for that: + +~~~~~{.haskell} +postPaths <- liftM (reverse . sortByBaseName) + (getRecursiveContents "posts") +~~~~~ + +We reverse them again, because we want the most recent posts first. Now, we can +use the `readCategoryMap` function instead of `readTagMap`, which has the same +signature, but assigns categories based on the folders the posts are in. + +~~~~~{.haskell} +categoryMap <- readCategoryMap "categoryMap" renderablePosts +~~~~~ + +The rest of the `hakyll.hs` is very similar to the one in the previous +tutorial, except we want to render a category list instead of a tag cloud. + +## Rendering a category list + +Because rendering a category list is quite easy, and it would be hard to +write a "general" function for this, hakyll does not provide such a function -- +but it is not hard to write. First, we write an auxiliary function that produces +a list item for one category: + +~~~~~{.haskell} +categoryListItem category posts = + "
  • " ++ link category (categoryToUrl category) + ++ " - " ++ show (length posts) ++ " items.
  • " +~~~~~ + +This is nothing more that some basic string concatenation to create a `li` HTML +element. The function that applies this on every element in the `TagMap` is more +interesting: + +~~~~~{.haskell} +categoryList :: HakyllAction TagMap String +categoryList = arr $ uncurry categoryListItem <=< toList +~~~~~ + +This function might seem a little harder to understand if you are not familiar +with the `<=<` operator -- but it's just right-to-left monad composition in the +list monad. `uncurry categoryListItem <=< toList` is a pure function we want to +execute on the `TagMap`. But this is not possible in Hakyll[^1]. We need to make +an arrow of this function. The `arr` function solves this problem easily. + +[^1]: This is a feature, not a bug. It helps dependency handling. + +We then add this to our index page, and we are done. Feel free to hack around +with the source code. If you still have questions, feel free to ask them at the +[google discussion group](http://groups.google.com/group/hakyll). diff --git a/src/Text/Hakyll/HakyllAction.hs b/src/Text/Hakyll/HakyllAction.hs index e12b50b..1310e28 100644 --- a/src/Text/Hakyll/HakyllAction.hs +++ b/src/Text/Hakyll/HakyllAction.hs @@ -70,8 +70,8 @@ runHakyllActionIfNeeded action = do -- | Chain a number of @HakyllAction@ computations. chain :: [HakyllAction a a] -- ^ Actions to chain. -> HakyllAction a a -- ^ Resulting action. -chain [] = id -chain list@(_:_) = foldl1 (>>>) list +chain [] = id +chain list = foldl1 (>>>) list instance Category HakyllAction where id = HakyllAction -- cgit v1.2.3