To kick off my code reading blog series for the year, I write about my first impression hacking on category pages to the Shiori theme that I use for my sites. You can view the demo for now for details about what I made – basically, the theme didn’t show the categories that the post belongs to, so I added those.

First, a code example to look at:

  # Adds some extra filters used during the category creation process.
  module Filters

    # Outputs a list of categories as comma-separated <a> links. This is used
    # to output the category list for each post on a category page.
    #  +categories+ is the list of categories to format.
    # Returns string
    def category_links(categories)
      categories = categories.sort!.map do |category|
        capitalized_category = category.split(' ').each { |word|
        }.join(' ')
        category_dir = category_link(category)
        "<a class='category' href='#{category_dir}/'>#{capitalized_category}</a>"

      case categories.length
      when 0
      when 1
        categories.join(', ')

It feels really nice to be able to chain apply transformations on categories as in the beginning of category_links. It flows a little bit nicer with the map attached to the List, so you can just type away, just a little nicer than Python map. Having done a lot of bash scripting in past months, the pattern is very familiar to the pipe chains feeding into while loops. It’s also familiar to be able to substitute variables into strings on the spot, too. Also, the return value being the value of the last expression in the block is familiar.

The other part that I really felt home with was working with Liquid.

<h1 class="category">Categories in Shiori</h1>
<ul class="posts">
{% for post in site.categories[page.category] %}
    <li><a class="post-title-archive" href="{{ post.url | prepend:site.baseurl }}">{{ post.title }}</a>
    <small class="text-muted">{{ | date_to_string }}</small>
{% endfor %}

You can iterate over data and apply filters with a familiar pipe syntax, and that’s about it, which is a good idea. It forces you to write a custom filter if you need anything, which is straightforward (e.g. the first snippet defines the category_links filter).

When I was making reports a few months ago, I actually opted to use Jinja, which is Python’s Liquid. I didn’t really pursue it and wrote out a whole set of bash scripts because filesystem manipulation and unix tool usage was too clunky, but looking at what Ruby has [1] [2] strikes me as very nice. I really must take the plunge with Ruby for an object-oriented pipeline experience that I’m missing out on working with just bash.