summaryrefslogtreecommitdiff
path: root/web/tutorials/02-basics.markdown
diff options
context:
space:
mode:
authorJasper Van der Jeugt <m@jaspervdj.be>2012-12-15 18:17:12 +0100
committerJasper Van der Jeugt <m@jaspervdj.be>2012-12-15 18:17:12 +0100
commitcb79c45d040f38b6d49abf2298250c19e5d9cea7 (patch)
tree8bed36969d08bc4bd00841ffcd0cde1270195587 /web/tutorials/02-basics.markdown
parente633df17dd72703a541c46d829096dfe40b75e50 (diff)
downloadhakyll-cb79c45d040f38b6d49abf2298250c19e5d9cea7.tar.gz
Finish first tutorial... I think
Diffstat (limited to 'web/tutorials/02-basics.markdown')
-rw-r--r--web/tutorials/02-basics.markdown264
1 files changed, 31 insertions, 233 deletions
diff --git a/web/tutorials/02-basics.markdown b/web/tutorials/02-basics.markdown
index f4d781b..b4c5e22 100644
--- a/web/tutorials/02-basics.markdown
+++ b/web/tutorials/02-basics.markdown
@@ -86,248 +86,46 @@ more customization. You want to route `contact.markdown` to
customRoute $ reverse . toFilePath
```
+Basic compilers
+---------------
+
More information can be found in the [Routes] module.
[Routes]: /reference/Hakyll-Core-Routes.html
-## Images
-
-Let's start of with the `images/haskell-logo.png` file, because the processing
-of this file is very simple: it is simply copied to the output directory. Let's
-look at the relevant lines in the `hakyll.hs` file:
-
-~~~~~{.haskell}
-match "images/*" $ do
- route idRoute
- compile copyFileCompiler
-~~~~~
-
-The first line specifies we will describe the process for compiling everything
-in the `images/` folder: hakyll uses globs for this [^pattern].
-
-[^pattern]: A little caveat is that these globs are not `String`s but
- `Pattern`s, so you need the `OverloadedStrings` extension.
-
-We can see two simple rules next: [route] and [compile].
-
-- [route] determines how the input file(s) get mapped to the output files.
- [route] only deals with file names -- not with the actual content!
-- [compile], on the other hand, determines how the file content is processed.
-
-[route]: /reference/Hakyll-Core-Rules.html#v:route
-[compile]: /reference/Hakyll-Core-Rules.html#v:compile
-
-In this case, we select the [idRoute]: which means the file name will be kept
-the same (`_site` will always be prepended automatically). This explains the
-name of [idRoute]: much like the `id` function in Haskell, it also maps values
-to themselves.
-
-[idRoute]: /reference/Hakyll-Core-Routes.html#v:idRoute
-
-For our compiler, we use [copyFileCompiler], meaning that we don't process the
-content at all, we just copy the file.
-
-[copyFileCompiler]: /reference/Hakyll-Core-Writable-CopyFile.html#v:copyFileCompiler
-
-## CSS
-
-If we look at how the two CSS files are processed, we see something which looks
-very familiar:
-
-~~~~~{.haskell}
-match "css/*" $ do
- route idRoute
- compile compressCssCompiler
-~~~~~
-
-Indeed, the only difference with the images is that have now chosen for
-[compressCssCompiler] -- a compiler which *does* process the content. Let's have
-a quick look at the type of [compressCssCompiler]:
-
-[compressCssCompiler]: /reference/Hakyll-Web-CompressCss.html#v:compressCssCompiler
-
-~~~~~{.haskell}
-compressCssCompiler :: Compiler Resource String
-~~~~~
-
-Intuitively, we can see this as a process which takes a `Resource` and produces
-a `String`.
-
-- A `Resource` is simply the Hakyll representation of an item -- usually just a
- file on the disk.
-- The produced string is the processed CSS.
-
-We can wonder what Hakyll does with the resulting `String`. Well, it simply
-writes this to the file specified in the `route`! As you can see, routes and
-compilers work together to produce your site.
-
-## Templates
-
-Next, we can see that the templates are compiled:
-
-~~~~~{.haskell}
-match "templates/*" $ compile templateCompiler
-~~~~~
-
-Let's start with the basics: what is a template? An example template gives us a
-good impression:
-
-~~~~~
-<html>
- <head>
- <title>Hakyll Example - $$title$$</title>
- </head>
- <body>
- <h1>$$title$$</h1>
-
- $$body$$
- </body>
-</html>
-~~~~~
-
-A template is a text file to lay out some content. The content it lays out is
-called a page -- we'll see that in the next section. The syntax for templates is
-intentionally very simplistic. You can bind some content by referencing the name
-of the content *field* by using `$$field$$`, and that's it.
-
-You might have noticed how we specify a compiler (`compile`), but we don't set
-any `route`. Why is this?
-
-We need to compile the template because we will need it later. If we compile a
-page later using `templates/default.html`, Hakyll needs to know what
-`templates/default.html` is. Note that we could move template compilation to the
-bottom of our code. The order doesn't matter -- Hakyll will determine that for
-you. But if you don't compile `templates/default.html` as a template, Hakyll
-will not be able to take it into account when deciding the compilation order.
+The `compile` function determines how the content is produced for a certain
+item. `compile` takes a value of the type `Compiler (Item a)`. Let's look at
+some common examples:
-So, the `compile` needs to be there -- but why don't we set a `route` here?
-Precisely because we don't want to our template to end up anywhere in our site
-directory! We want to use it to lay out other items -- so we need to load
-(compile) it, but we don't want to give it a real destination.
+- `copyFileCompiler` is self-explanatory, the output is exactly the same as the
+ input;
+- `compressCssCompiler` performs some simple build-in compression
+ transformations for CSS;
+- `pandocCompiler` reads markdown, reStructuredText, or another input format and
+ renders it as HTML (if you want to pass specific options to pandoc, use
+ `pandocCompilerWith`).
-By using the `templates/*` pattern, we compile all templates in one go.
+Compilers are very flexible: `Compiler` is a [Monad] and `Item` is a [Functor].
-## Pages
+[Monad]: http://learnyouahaskell.com/a-fistful-of-monads
+[Functor]: http://learnyouahaskell.com/functors-applicative-functors-and-monoids
-The code for pages looks suspiciously more complicated:
+A good example to illustrate the `Monad` instance for `Compiler` is
-~~~~~~{.haskell}
-match (list ["about.rst", "index.markdown", "code.lhs"]) $ do
- route $ setExtension "html"
- compile $ pageCompiler
- >>> applyTemplateCompiler "templates/default.html"
- >>> relativizeUrlsCompiler
-~~~~~~
-
-But we'll see shortly that this actually fairly straightforward. Let's begin by
-exploring what a *page* is.
-
-~~~~~~
----
-title: Home
-author: Jasper
----
-
-So, I decided to create a site using Hakyll and...
-~~~~~~
-
-A page consists of two parts: a body, and metadata. As you can see above, the
-syntax is not hard. The metadata part is completely optional, this is the same
-page without metadata:
-
-~~~~~~
-So, I decided to create a site using Hakyll and...
-~~~~~~
-
-Hakyll supports a number of formats for the page body. Markdown, HTML and RST
-are probably the most common. Hakyll will automatically guess the right format
-if you use the right extension for your page.
-
-~~~~~~{.haskell}
-match (list ["about.rst", "index.markdown", "code.lhs"]) $ do
-~~~~~~
-
-We see a more complicated pattern here. Some sets of files cannot be described
-easily by just one pattern, and here the [list] function can help us out. In
-this case, we have three specific pages we want to compile.
-
-[list]: /reference/Hakyll-Core-Identifier-Pattern.html#v:list
-
-~~~~~~{.haskell}
-route $ setExtension "html"
-~~~~~~
-
-For our pages, we do not want to use `idRoute` -- after all, we want to generate
-`.html` files, not `.markdown` files or something similar! The [setExtension]
-route allows you to simply replace the extension of an item, which is what we
-want here.
-
-[setExtension]: /reference/Hakyll-Core-Routes.html#v:setExtension
-
-~~~~~~{.haskell}
-compile $ pageCompiler
- >>> applyTemplateCompiler "templates/default.html"
- >>> relativizeUrlsCompiler
-~~~~~~
-
-How should we process these pages? [pageCompiler] is the default compiler for
-pages. [pageCompiler] does a few things:
-
-- It parses the page into body and metadata
-- It adds some extra metadata fields such as `$$url$$` and `$$path$$` (you
- shouldn't worry about these for now)
-- It fill in possible `$$key$$`'s in it's own body
-- It renders the page using pandoc
-
-Which basically means that we end up with a `Page` that has the HTML content we
-want as body. But we don't just want the plain content on our website -- we want
-to decorate it with a template, for starters.
-
-[pageCompiler]: /reference/Hakyll-Web-Page.html#v:pageCompiler
-
-Different compilers can be chained in a pipeline-like way using Arrows. Arrows
-form a complicated subject, but fortunately, most Hakyll users need not be
-concerned with the details. If you are interested, you can find some information
-on the [Understanding arrows] page -- but the only thing you really *need* to
-know is that you can chain compilers using the `>>>` operator.
-
-[Understanding arrows]: http://en.wikibooks.org/wiki/Haskell/Understanding_arrows
-
-The `>>>` operator is a lot like a flipped function composition (`flip (.)`) in
-Haskell, with the important difference that `>>>` is more general and works on
-all Arrows -- including Hakyll compilers.
-
-Here, we apply three compilers sequentially:
-
-1. We load and render the page using `pageCompiler`
-2. We apply the template we previously loaded using [applyTemplateCompiler]
-3. We relativize the URL's on the page using [relativizeUrlsCompiler]
-
-[applyTemplateCompiler]: /reference/Hakyll-Web-Template.html#v:applyTemplateCompiler
-[relativizeUrlsCompiler]: /reference/Hakyll-Web-RelativizeUrls.html#v:relativizeUrlsCompiler
-
-Relativizing URL's is a very handy feature. It means that we can just use
-absolute URL's everywhere in our templates and code, e.g.:
-
-~~~~~{.haskell}
-<link rel="stylesheet" type="text/css" href="/css/default.css" />
-~~~~~
-
-Using the [relativizeUrlsCompiler], Hakyll will change this to:
-
-~~~~~{.haskell}
-<link rel="stylesheet" type="text/css" href="css/default.css" />
-~~~~~
-
-when we are compiling `index.html`, or
+```haskell
+relativizeUrls :: Item String -> Compiler (Item String)
+```
-~~~~~{.haskell}
-<link rel="stylesheet" type="text/css" href="../css/default.css" />
-~~~~~
+This compiler traverses your HTML and changes absolute URLs (e.g.
+`/posts/foo.markdown` into relative ones: `../posts/foo.markdown`). This is
+extremely useful if you want to deploy your site in a subdirectory (e.g.
+`jaspervdj.be/hakyll` instead of `jaspervdj.be`). Combining this with the
+`pandocCompiler` gives us:
-when we are compiling (some imaginary) `posts/foo.html`. So Hakyll will
-translate this to a relative URL for each page. This means we can host our site
-at `example.com` and `example.com/subdir` without changing a single line of
-code.
+```haskell
+pandocCompiler >>= relativizeUrls :: Compiler (Item String)
+```
-More tutorials are in the works...
+For a real website, you probably also want to use templates in order to give
+your pages produced by pandoc a nice layout. We tackle this in the next
+tutorial.