Keep a social journal of your work progress as you make and learn things.

Hakyll Portfolio/Blog

Hakyll Portfolio/Blog

A portfolio website & blog written in Hakyll, because Haskell is awesome.

February 2017


I’m putting aside my goal of finishing the #hakyll_portfolio_blog by Saturday as a couple things just came up that I didn’t expect:

1) The #MidnightMurderParty animation timeframe suddenly got accelerated, so the animation needs to be completed within the next 4 days. This means, among other things, that I have to dedicate more of my time to being available for quick feedback and have to orchestrate getting the voice line recorded.

2) The For Honor beta just came out, and, frankly, I just really want to play it while it’s still free.

That said, I still plan to work on the blog, just not as much as I initially intended.

Tonight, I also got feedback on the current animation, scheduled a time to record that voice line so I can get it to the animator by the end of Saturday, and wrote a #shortstory (flash fiction).


Didn’t think I’d get any programming done tonight considering I spent until 11:30pm cleaning my apartment, but I wanted to try One Quick Thing™. Two hours later, I have a very solid commit on my #hakyll_portfolio_blog and more pending sleep deprivation.

I did two things in this commit:

  • Introduced implicit parameters for my config value and two other values that are passed into a lot of different functions. Cleaned up the code quite nicely.
  • Created a Context for lists of tags. #Hakyll has a built-in tag module which is convenient for getting up and running quickly and not so convenient for customizing at all. It generates the HTML to display tags for you instead of giving you a Context with values you can utilize in your templates. Seems odd that this one bit of Hakyll is hard-coded, but hey, with enough digging through types, I got the tag data into a Context.

All in all, not bad for an accidental coding session.


Styled the home page of my #hakyll_portfolio_blog, and I think it looks pretty good. Despite this, the styles are taking longer than I’d hoped, so I probably won’t be able to launch tomorrow (today, at this point) as planned. I still need to build a deploy script too, which would be easy if I weren’t developing on Windows which doesn’t have rsync. I’m setting my new goal for the end of Saturday. I think I can finish it sooner still, but hopefully that will give me some time to polish it up a bit.


Tonight I filled out the author-data.yaml config file, which is basically a #yaml representation of my resume. The goal is to eventually generate both a PDF and HTML page by just changing this one file, thus always keeping my site and my PDF resume in sync and up-to-date. The PDF generation looks like it will be tricky (and involve me learning #LaTeX), but I rigged up the new config data with my #hakyll Context and can now display any of that data on a web page. That finishes the last of the necessary features for a minimal release of my #hakyll_portfolio_blog. Not sure if I’ll be able to throw together a design and style the whole site before the MMP beta ends on Tuesday, but that remains the goal.


Somehow I managed to waste most of the day and still get a lot done.

  • Spoke with my cousin about voicing a character for the #MidnightMurderParty promo animation. We’re meeting sometime this week to record the line, which is really exciting.
  • Made a bunch of commits to the #hakyll_portfolio_blog:
    • Changed the way URL fixing is handled to not rely on post-processing the page.
    • Added an RSS feed to the site.
    • Restructured the Config record to better handle reading in multiple config files.
    • Refactored the Contexts module to more easily handle all the various parameters needed to generate a Context. For example, to generate the Context for a post, I used to have to write something like postCtx tags categories <> configCtx config <> defaultCtx, but after doing some mconcats and introducing a new record, I can do something like postCtx contextParams and it does all of the above. Pretty neat!

Spent the whole night playing with different comment system widgets because I’m getting tired of Disqus (guests can never figure out how to leave a comment, and I don’t blame them; Disqus makes it so hard to find the submit button for a guest). I couldn’t find anything to suit the needs of #MidnightMurderParty any better, though, since I need the AJAX thread loading Disqus has. While Widget Pack has that too, its admin interface seems weaker than Disqus’s, and it bundles a star-rating system in with the comment stream, which I don’t want. Couldn’t find a way to disable it, but maybe I’m missing something.

On the bright side, my #hakyll_portfolio_blog does not need AJAX thread loading, so tonight I installed IntenseDebate on there. For the functionality it does have, it’s behaving faster and more reliably than Disqus, which is nice.


Tonight I added tags and categories to my #hakyll_portfolio_blog with some custom behavior outside of what #Hakyll already offers. That was the easy part.

I spent the last four hours trying to get the Contexts for posts and projects to contain one another such that a post page can display any projects mentioned in the post and a project page can show a list of posts that discuss that project. The actual Contexts weren’t too hard to code (despite having to delve into the docs and fit types together), but the recursive dependencies were a nightmare. I spent at least two hours fixing just that.

In the end, I did get it all working, but I’ll save just how I did that for a full-length blog post. For now, I think the hardest parts of the wiring are done. There are more Contexts and config files to rig up, as well as an RSS feed, but I don’t think anything I have left to do will be as complicated and confusing as tonight’s features. All in all, it’s coming along.


Did some more work on my #hakyll_portfolio_blog tonight. I made some progress on the design/css, made some custom routes (they convert default routes like /content/posts/a-blog-post.html to /posts/a-blog-post/index.html to get rid of parent directories and hide ugly .html extensions), added some functionality to direct all links to the “clean” routes instead of the index.html ones, and got started on a #yaml config file which I’m successfully reading in and parsing (turns out this is pretty easy in #Haskell with the right libraries). All in all, a pretty good start after the initial setup yesterday.


I’ll make this a quick post since it’s late. Since the #MidnightMurderParty beta is now in progress, I’ve shifted gears a bit and started working on my #hakyll_portfolio_blog again. Really, I restarted it from scratch since the first version was a mess. Maybe I’ll be able to launch a minimal version before the MMP beta ends–that’s my hope, anyway. Other than that, I started reading my third book of the year and got some #writing done on a #shortstory.

September 2016


Still a bit under the weather, but I sucked it up and got a good start on the #CSS refactor for my #hakyll_portfolio_blog.

  • Replaced the fixed sidebar with a static sidebar.
  • Changed the overall layout of the site to use #flexbox.
  • Made the site responsive for different screen sizes / mobile devices.
  • Tinkered with some other design ideas.

Aside from that, I’ve been trying to get a consistent 8 hours of sleep per night this week. So far, I’ve just woken up more tired and have had less time to get stuff done. When can I get a robotic replacement body?


Somehow I got a full night of sleep last night and woke up more tired than ever this morning. Took half the day and a good amount of tea to shake that off. I do feel better than yesterday, but still not great, so I decided to take it easy again tonight. However, since I’d be remiss to take a complete night off, I added a CSS autoprefixer to the build system. Pretty neat that #hakyll has command line access through the unixFilter function. So the #hakyll_portfolio_blog should now have all the vendor prefixes it needs!


I haven’t been feeling well all day, so I didn’t do too much tonight. I finished styling the post page for my #hakyll_portfolio_blog and added social media share buttons.

It’s pretty early for me right now, but I think I’ll try to sleep anyway. Hopefully this headache will go away and I’ll be more productive tomorrow.


I didn’t get to post all weekend, but I haven’t been slacking. Promise! I actually got a lot done with my #hakyll_portfolio_blog.

  • Friday. Added logic to conditionally show fields based on metadata. Turns out it was tricky, but not impossible, @josh. I had to go on a type safari through #hakyll docs and source to figure it out. Since I couldn’t find any resources on doing this, I’ll write up an explanation in a blog post once my blog is done.
  • Saturday. I got the résumé JSON into a #hakyll Context and displayed in the template. I also figured out how to get #pandoc to inject values from the JSON into a #LaTeX template and render that template to PDF. All from #Haskell! Also, went to a diner for dinner.
  • Sunday. Tried to learn #LaTeX and ended up breaking my entire installation. Spent the first half of the day fixing it. Spent the rest of the day hanging out with @JorfimusPrime. Went to the diner again. I might like diners too much.

I’m writing up my log now to encourage myself to actually stop working for tonight.

Today I was told that the failed #OpenCart upgrade I attempted actually did leave behind some errors. Not too surprising. I don’t know OpenCart; I’m just that “hey, you’re good with computers, right?” guy. So, it’s kind of broken now. It looks like OpenCart has somehow managed to render a smaller version of itself inside one of its own templates. I dug through the templates and saw no trace of what was causing this, and I’m not about to blindly debug thousands of lines of #php. For now, it still works. It just looks stupid. I’ll look at it again over the weekend.

On a brighter note, I spent a good amount of time reading up on #aeson today and managed to get it to parse a JSON version of my résumé for my #hakyll_portfolio_blog. Tomorrow, I’ll try to get that data into my #hakyll template.

For now, I’m gonna make some popcorn, finish Twin Peaks, maybe read for a while, and get some much-needed sleep.


Got #Disqus working on my #hakyll_portfolio_blog tonight. Had to append the window.location.protocol to the beginning of the variable, which I’ve never had to do before (and I’ve set up Disqus two or three times before this). Weird.

I moved some stuff around the home page as well. I’m thinking of making it a résumé page instead of just blog posts. Still getting the balance between portfolio and blog right.

The biggest thing left, aside from continued design, is generating a résumé from JSON as a PDF and as HTML on the home page. Going to try to use #pandoc for that, I think, but I’m still very hazy on how to transition from JSON -> LaTeX -> PDF. All I know is that #Haskell’s aeson library will probably come in handy.


Today was strangely busy even for me. Things I did:

  • Walked 3-4 miles.
  • Collected feedback on a significantly revised opening hook for #midnightmurderparty.
  • Went food shopping / cleaned kitchen / did dishes.
  • Attempted to upgrade #OpenCart as a favor to my old Boy Scout troop. As it happens, OpenCart’s upgrade process is completely broken, and I had to roll the whole thing back. No progress was made there, unfortunately, after 3 hours of working on it.
  • Nearly completed the design of the posts for my #hakyll_portfolio_blog. Also added #Disqus, but it’s giving me odd iframe issues I’ve never seen from #Disqus before.
  • Somehow managed to squeeze in a couple episodes of Twin Peaks (I take breaks… sometimes…).

All in all, I did a bunch of unrelated but nonetheless productive things today. Well, yesterday. It’s now 2am. Goodnight.


Looks like I’m starting this week by going to bed too late again. Oops.

Today I continued working on the #hakyll_portfolio_blog.

  • Added an #RSS feed. This is actually really simple in #hakyll, but I wanted the URLs in the feed formatted a certain way which complicated the process. Spent a while digging through #hakyll docs and mapping function compositions into monads to “alter” strings. Eventually, I got it working.
  • Added link to resume as well as social media links in the sidebar.
  • Sidebar now handles scrolling in a more aesthetically pleasant manner.
  • Removed banner from the home page since it looked too busy and confusing.
  • Added banner support to posts and post teasers.

I still have lots to add (Disqus, social share buttons, Google Analytics, better post formatting, etc.), but it’s coming along. Honestly, though, I’m pretty tired of #css and #design in general. I’m trying to finish this quickly so I can get back to logic programming and #writing.


Pushing hard on this #hakyll_portfolio_blog:

  • Improved a lot of the #CSS and fixed a nasty wrapping-under-fixed-sidebar issue.
  • Added navigation links to the sidebar as well as a conditional “return to home” button.
  • Added skills list with bars that indicate proficiency as well as a tag cloud to the sidebar.
  • Hakyll now generates a Portfolio page, which lists all my projects.

Aside from that, I’ve been gathering feedback about the first episode of #midnightmurderparty. @larouxn and I have been putting a ton of time into the site, but it doesn’t mean much if the story’s hook is weak. After hearing the feedback about the current version and the heavily revised version I proposed, it seems both versions have merit. I’m definitely going to rewrite the episode, so I guess I’ll have to find a happy medium. Can’t wait to get back to #writing!


Made a good amount of progress on my #hakyll_portfolio_blog:

  • Added support for tags, which are shared between projects and blog posts.
  • Added support for teasers / “read more” links in the post listings.
  • Redid all the dependency handling with Stack.
  • Split the #Haskell source code into its own repo, apart from all the generated HTML. Now I can see my #Haskell code actually counted in the code breakdown (this makes me happier than it should).
  • Replaced over-complicated #CircleCI deploy process with a simple shell script.

All in all, I’ve got some new features, and building and deploying is now simpler. I declare today a success!


Added some basic support for projects to the #hakyll_portfolio_blog tonight. Rigging it up wasn’t too bad even though I did have to dig through a lot of docs to get some cool but largely unnecessary functionality in there. It’s all learning (and #Haskell), though, which is fine by me.

Speaking of learning, I learned, after many wasted hours, that it is either tricky or impossible to get metadata out of the MonadMetadata monad in order to do a simple comparison. I wanted a Bool. All I could get was a MonadMetadata Bool. Or maybe it was a Compiler Bool. I’m not sure. All I know is I absolutely could not figure out how to extract a value from that monad.

I did post in the #hakyll Google Group to ask about it, but it seems Google Groups ate my post. Either it’s awaiting moderation (as a new member) or it’s gone forever. No idea which.

August 2016


Did some more work on my #hakyll_portfolio_blog tonight. Initially intended to work on actually designing the site, but got caught up prettying up my routes so they would look like /posts/my-blog-post/ instead of /posts/2016-12-08-my-blog-post.html. Between learning a new library and figuring out how to do #regex in #Haskell, it was more challenging than expected. And that’s before I realized I was modifying external URLs as well as my own. Woops!

But all in all, I don’t really mind the extra time spent. It’s nice to be venturing into the world of #Haskell again… especially after the nightmare that was cross-browser #JavaScript (shudders).


After all of @JorfimusPrime’s talk of blogging, I got it in my head to convert my portfolio website into a portfolio website / blog. It’s seriously due for an update anyway. Spent a good portion of the day looking at Jekyll, a simple Ruby-based static blog generator which #GitHub will build for you automatically on push. But, me being me, I had to look up a #Haskell alternative. And what do you know? I found #Hakyll, which is basically a #Haskell clone of Jekyll with a bunch more configuration options. Neat.

Spoiler alert: #GitHub does not support automatic #Hakyll builds to gh-pages.

So, tonight I dug through a bunch of #Hakyll + #CircleCI build tutorials, spent several hours configuring git submodules, orphan branches, and SSH keys as well as fixing mismatched dependency versions, and finally got the first automatic build and deploy of my #hakyll_portfolio_blog working!