Latest Articles

Despite great difficulties updating to Yosemite 10.10.1 over the weekend, Tozier brought a plugin to work.

You’ve seen my um well-deserved and unemotional criticism of what is necessary in Liquid to get the most recent article. We knew we would need a plugin to do a decent job of finding most recents, and that’s what Bill wrote.

Bill would like you to know that he just dashed it off and it worked perfectly. Similarly, I would like you to know that I am Queen of the May. There was a fair amount of struggling with setting up a plugin, and accessing the internal variables of Jekyll and Liquid inside it. The result looks like this:

# insert a link to the latest article in a specified category
# 
class LatestArticle < Liquid::Tag
  def initialize(tag_name, category_name, tokens)
     super
     @category_name = category_name.strip
  end

  # see https://jekyllrb.com/docs/plugins/ ("ProTip" box) for more
  def render(context)
    all_pages = context.registers[:site].pages
    labeled_pages = all_pages.find_all {|page| !page["categories"].nil?}
    filtered_pages = labeled_pages.find_all {|page|  page["categories"].include? @category_name}
    latest = filtered_pages.sort_by {|page| page["date"]}.last

    article_string = "<li>"
    article_string += "<p class=\"page-category\">#{@category_name}</p>"
    article_string += "<p class=\"page-title\"><a class=\"page-link\" href=\"#{context.registers[:site].baseurl}#{latest['url']}\">#{latest['title']}</a></p>"
    article_string += "<p class=\"page-blurb\">#{latest["blurb"]}</p>"
    article_string += "<p class=\"page-link-date\">#{latest["date"]}</p>"
    article_string += "</li>\n"

    return article_string
  end
end

Liquid::Template.register_tag('latest_article_in_category', LatestArticle)

Apologies for the long lines: one has to be a bit careful with spacing when running Liquid. The interesting bits are the Ruby interpolations like #(latest['blurb']), which fetch the blurb YAML from the article latest. There’s nothing particularly tricky in here. You just have to find out all those cryptic phrases that reach inside the system context.

We’d like to be able to say #(latest.blurb) instead of #(latest['blurb']), but that will require a bit of messing about with what comes back from the page collection. Perhaps another day, or perhaps we won’t bother.

There’s also some messing about to be done in case there is no such article, and we might refactor out those individual strings into separate methods one way or another.

A larger objection is that this internal plugin knows the layout of a list item that goes inside a list on the index page, so it mixes up model and view. Our tentative plan is to pass in a control string which will be parsed, and values interpolated, so that formatting remains outside the plugin.

All reasonable stuff, but the first rope bridge has been cast across the chasm and the rest is just engineering. Well done, Bill!

Cleanup

In addition, we refactored the index page and the various layout and include pages internal to the site. There are now just two layouts: default and titled-article and four includes, head, page-header, page-footer, and posts. The latter is the Liquid script that returns the list of Articles on the front page. It looks like this:

<!-- used in index.html to produce full article index -->
 <ul class="post-list">
    {% strip %}
        {% assign date_sorted = (site.pages | sort: 'date') %}
        {% for page in date_sorted reversed %}
          {% unless (page.categories contains "top") or (page.categories contains "Kate Oneal") or (page.title == null) %}
            <li><p class="page-title"><a class="page-link" href="{{ page.url | prepend: site.baseurl }}">{{ page.title }}</a></p>
                <p class="page-link-blurb">{{ page.blurb }}</p>
                <p class="page-link-date">{{ page.date }}</p>
            </li>
          {% endunless %}
        {% endfor %}
    {% endstrip %}
</ul>

Potentially interesting fact: the above code is Liquid, and if you embed Liquid in an article, it will be executed. To stop that, you have to enclose it in tags that say raw, enclosed in Liquid’s trigger brackets, brace-percent. If there’s a way to display that string in an article, I am disinclined to figure it out right now.

Note that the articles list as presently implemented does not include the Kate Oneal articles. It does, however, include all the other articles listed in the “most recent” listing above it. We may want to do something to avoid listing articles twice, but we want to figure out the home page layout first. The original plan had been to pretty much duplicate how the XProgramming home page works but now I think we’ll go to a new format. We’ll ensure that all the XProgramming articles are here but probably adjust the home page for the work I’m doing now.

TL;DR

Bill provided an excellent first plugin to find the latest article in a category, and we hammered it a bit to give us the right content for the index page.

We refactored the index page and the underlying layouts and includes, resulting in a cleaner base for going forward. It was an excellent day. Well, an excellent two hours.

And we ate at Mikey’s. Nom!