Daily Learning Notes for May 30th, 2017

I loved my daily learning notes habit, but for a while I stopped publishing them here. A recent conversation with a soon-to-be-blogging friend reminded me that my own blog has a somewhat inconvenient setup, which is probably a major deterrent to my blogging habit. Just like how I’m more likely to exercise if I prepare my gym bag the night before, I think I’ll be more likely to resume my daily learning notes if my blog’s category system is already set up to make them easy to organize!

So the other day, I started learning more about Jekyll collections and categories to see what my options are. (Jekyll is the static site generator built into GitHub, so that’s why I use it – free web hosting through GitHub Pages!)

General Resources for Jekyll Collections:

I’m still debating whether I should be using posts or a custom collection for these daily learning notes, so I made a couple of quick pro/con lists.

Issues with Posts:

  • I don’t think I want them all to show up in my site’s RSS feed! (Is there another way to exclude posts from the RSS feed in Jekyll?)
  • Jekyll doesn’t seem to support multiple categories on each blog post; if I assign multiple categories to a post, Jekyll treats them as a hierarchy and the generated permalink would look like category1/category2/post-name/, which is not what I want! (I’m not using categories in the permalinks right now, but if I wanted to in the future, that would be very annoying!)

Issues with Collections:

  • Collections aren’t ordered by date, so I’d have to find a workaround.
  • I’d have to create/maintin more files, and maybe it’s more overhead than necesary for what’s essentially just another category of my blog.

Now I find myself wondering: is there another way to exclude posts from the RSS feed in Jekyll? I’ll do a little research…

Yes, there certainly is! These Jekyll RSS Feed Templates on GitHub provide some good examples. My blog already has an atom.xml file, which I could easily modify to exclude certain categories. Good to know! There’s also the jekyll-feed plugin, which probably isn’t too hard to customize either.

I’ll tackle the low-hanging fruit first. I think I can solve my major pain points with just two small fixes:

  • Edit the breadcrumbs functionality of my theme to list all categories associated with the current page, using a code snippet like this one

  • Exclude the “daily” category of posts from the Atom/RSS feed template file with something like ` create feed! `

And… done! I even added one extra bit of functionality: now I can exclude any post from my Atom/RSS feed by simply including nofeed: true in the front matter of any post, in addition to excluding the “daily” category. Nifty!

OK, next problem to solve: categories! With the quick fix I just made, I can now use multiple categories on all my blog posts (as long as I don’t use categories for the permalinks). But it could still be so much better! Right now, if I want the “daily” category to have the name “Daily Learning Notes” but use “daily” for the category page permalink, I’d have to create a separate data file or something that links the long and short names of every category.

So how do I solve this problem and make Jekyll categories behave the way I want? Time for a little more research…

First option: I could always use plugins to customize Jekyll and change how it handles categories. The only downside to that is since GitHub doesn’t support custom plugins, I’d have to always build my blog locally, then push the static site files to GitHub. That’s not a big deal at all, since I could use an easy enough work-around as described in blog posts like “Jekyll + Plugins + GitHub + You”. But I wouldn’t be able to edit my blog from my phone or from other computers like I can right now, taking advantage of GitHub’s web interface for editing files and letting their servers rebuild my Jekyll blog automatically.

Second option: I could create a Jekyll collection for my tags/categories, as suggested in this blog post from Siteleaf, this blog post by Kyle Banks, and this other blog post by Stephan Grob. Plus, there are a couple extra benefits to using collections: I could then assign metadata to categories themselves, like theme colors, category descriptions, or whatever else I can think of! And this workaround would also solve a well-known bug with Jekyll: if a category name contains spaces, it generates an ugly permalink. With metadata for each category, I could name my categories whatever I want and set their permalinks separately.

I’m defintiely leaning towards this second option, but are the benefits worth the extra work? Following the example from this blog post by Siteleaf, I outlined a list of steps.

Steps for Setting Up My Categories Collection

  • First, decide on the name for the collection! (It sort of works if I name it “categories”, but there are some potential conflicts between my custom collection and Jekyll’s built-in categories.) So I settled on “cats” for short.

  • Update the config file to register the “cats” collection, set output: true so Jekyll will create a page for each category, and set the default values for each category (like layout and permalink structure).

  • Create a _cats folder, containing a file for each category.

  • Each category file should have in its front matter: a “name” for its short identifier/permalink, a “title” for its longer name, and any other metadata.

  • Update every blog post to use the new “cats” metadata in the front matter. (Be sure to test out multiple categories per blog post!)

  • Create a default layout file for category pages, which will list all posts that belong to the given category.

  • Create an include file that displays all categories on my blog, in case I want to display that list somewhere for improved site navigation.

  • Update the breadcrumbs file to properly display a list of all categories on each post, and take advantage of how collections now let me set metadata for each category!

  • Update the Atom/RSS feed file to exclude all posts in the “daily” collection.

It’s a bit of work, but very doable! OK, so far I’ve set everything up as needed, and now I just need to figure out how to use the right Liquid code (the template language used by Jekyll) for these last steps.

Liquid Code Snippets

List all categories on my blog:

  {% for cat in site.cats %}
    <li><a href="{{ cat.url }}">{{ cat.title }}</a></li>
  {% endfor %}

List all the posts in a given category (supports multiple categories on each post):

<div class="tiles">

  {% for post in site.posts %}
    {% if post.cats contains page.name %}
      {% include post-list.html %}
    {% endif %}
  {% endfor %}

</div><!-- /.tiles -->

List breadcrumb links for all of the current blog post’s categories (modified code from Skinny Bones theme):

{% if page.cats and page.cats != empty %}
  <nav class="breadcrumbs">
    <span itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
      <a class="bold" href="{{ site.url }}" itemprop="url">
        <span itemprop="title">Home</span>
      </a><span class="bold" style="margin-left: 10px;">Categories:</span>  
    {% for cat in page.cats %}
      {% assign currentcat = site.cats | where: 'name', cat | first %}
        {% if currentcat %}
        <span itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
          <a href="{{ site.url }}/{{ currentcat.url }}" itemprop="url" style="margin: 0 5px;">
            <span itemprop="title">{{ currentcat.title }}</span>
        </span>{% unless forloop.last %}  <span style="font-weight:700;">/</span>  {% endunless %}
        {% endif %}
    {% endfor %}    
  </nav><!-- /.breadcrumbs -->
{% endif %}

Exclude posts from my Atom/RSS feed (from the “daily” collection or where “nofeed” property is true):

{% for post in site.posts limit: page.limit %}
    {% unless post.cats contains 'daily' or post.nofeed %}
    ...include post content here...
    {% endunless %}
  {% endfor %}

Phew, it finally all seems to work! Woohoo! Well, time to save all these changes and call it a day. (Although technically it did take me more than one day to get all this working, haha.) I’ll just average it out and publish it for the day on which I did most of the work, which was actually yesterday (Tuesday, May 30th). But yeah, here it is: my first daily learning blog post in a long time! It’ll be interesting to see if this new setup actually encourages me to share more of my raw learning notes.

Oh yeah, and before I forget, here’s something to try next: implement a feature for grouping posts into a series, following this blog post!

OK, bye for now!