<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Passing Curiosity: Posts tagged hakyll</title>
    <link href="https://passingcuriosity.com/tags/hakyll/hakyll.xml" rel="self" />
    <link href="https://passingcuriosity.com" />
    <id>https://passingcuriosity.com/tags/hakyll/hakyll.xml</id>
    <author>
        <name>Thomas Sutton</name>
        
        <email>me@thomas-sutton.id.au</email>
        
    </author>
    <updated>2013-10-25T00:00:00Z</updated>
    <entry>
    <title>Post banner images with Hakyll</title>
    <link href="https://passingcuriosity.com/2013/hakyll-post-banners/" />
    <id>https://passingcuriosity.com/2013/hakyll-post-banners/</id>
    <published>2013-10-25T00:00:00Z</published>
    <updated>2013-10-25T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>I’ve just created a new <a href="https://github.com/thsutton/hakyll-banner-images-demo">hakyll-banner-images-demo</a> repository on GitHub
which demonstrates how your <a href="http://hackage.haskell.org/package/hakyll">Hakyll</a> site can:</p>
<ol type="1">
<li><p>Associate a banner image with each post.</p></li>
<li><p>Generate multiple versions (sizes) of these banner images.</p></li>
<li><p>Provide the generated images in variables for use in post templates.</p></li>
</ol>
<p>Each post in the site is represented by a directory containing an <code>index.md</code>
Markdown file and, optionally, a <code>banner.png</code> image file. This repository
contains two posts, one with and one without an image:</p>
<pre><code>posts/2013-10-23-post-without-banner/index.md
posts/2013-10-24-post-with-banner/banner.png
posts/2013-10-24-post-with-banner/index.md</code></pre>
<p>The <a href="https://github.com/thsutton/hakyll-banner-images-demo/blob/master/site.hs"><code>site.hs</code></a> Haskell program contains only the most basic Hakyll
directives to process the Markdown files (indeed, I haven’t even bothered to
override the date code; you’ll need to put the date in the Markdown file
metadata). In addition, it contains the proof-of-concept code to handle the
banner images.</p>
<p>The <code>imageProcessor</code> function is a helper to construct the Hakyll <code>Rules ()</code> to
process a set of banner images and the <code>Context a</code> allowing them to be used in
the associated posts and templates. This function takes a <code>Pattern</code> which
matches the banner images and a list describing the different versions to
generate of each image.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> (postImages, postImageField) <span class="ot">=</span> imageProcessor <span class="st">&quot;posts/*/banner.png&quot;</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>                                     [ (<span class="st">&quot;small&quot;</span> , <span class="dt">Just</span> (<span class="dv">200</span>,<span class="dv">100</span>))</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>                                     , (<span class="st">&quot;medium&quot;</span>, <span class="dt">Just</span> (<span class="dv">600</span>,<span class="dv">300</span>))</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>                                     , (<span class="st">&quot;full&quot;</span>  , <span class="dt">Nothing</span>)</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>                                     ]</span></code></pre></div>
<p>The first argument to <code>imageProcessor</code> is the pattern identifying the image to
be processed. This pattern <em>must</em> end in a full filename. The second argument
is a list of versions to create. Each version has a name (the <code>String</code>) and
image processing instructions (<code>Nothing</code> to copy the image, <code>Just (x,y)</code> to
scale and crop the image to the given dimensions using ImageMagick’s <code>convert</code>
command). This generates a <code>Rules ()</code> value to process the images (<code>postImages</code>
in the code) and a <code>Context a</code> to make them available in posts and templates.</p>
<p>The <code>Rules ()</code> value can be “run” just like any <code>create</code> or <code>match</code> statement
and the <code>Context a</code> value can be used in the context of post with a path that
matches the image pattern (ignoring the filename). This context defines one
variable for each of the image versions being generated. In this code, the
variables are:</p>
<ul>
<li><code>banner-small</code> is a 200x100 image.</li>
<li><code>banner-medium</code> is a 600x300 image.</li>
<li><code>banner-full</code> is the original image.</li>
</ul>
<p>These names are generated from the filename <code>banner.png</code> in the image pattern
(this is why the pattern must have a filename) and the name of each version.</p>
<p>With this configuration, the posts included in the repository result in the
following files being generated:</p>
<pre><code>posts/2013-10-23-post-without-banner/index.html
posts/2013-10-24-post-with-banner/index.html
posts/2013-10-24-post-with-banner/full-banner.png
posts/2013-10-24-post-with-banner/medium-banner.png
posts/2013-10-24-post-with-banner/small-banner.png</code></pre>
<p>As expected, each post has an <code>index.html</code> file and the single banner image has
<code>small</code>, <code>medium</code>, and <code>full</code> versions.</p>
<p>The implementation of <code>imageField</code> and the assumption that the pattern ends in
a file name are pretty crappy but, overall, I’m quite happy with this approach.</p>]]></summary>
</entry>

</feed>
