Skip to content

Tweaking Frontmatter for sent Webmentions

Making my frontmatter templates more efficient

Published by Vincent Pickering
on

After publishing yesterdays epic post. I had time to think through some of my code in a bit more detail.

In particular the front matter and feed code generated when sending Webmentions.

I originally inserted some front matter at the top of my page like this:

replyUrl: "https://aaronparecki.com/2018/06/30/11/your-first-webmention"
replyName: "aaronparecki.com"

This was overly complicated and verbose.

If I am sending a Webmention I only care about 2 things.

  1. The target URL
  2. The Webmention type (for formatting only)

Lumping the target and type together above was my first mistake.

My second was adding a name that wasn’t needed.

It lead to code like this for my feed “queue”

{% assign publishTime = site.data.published.time %}{
    "published":"{{publishTime}}",
    "webmentions": {% for post in site.posts %}{% assign postTime = post.date | date_to_xmlschema %}{% if postTime >= publishTime %}{% if post.replyUrl or post.like or post.repost or post.rsvp or post.bookmark -%}{
            "source": "{{site.url}}{{ post.url }}",
            "target": "{{post.replyUrl}}{{post.like}}{{post.repost}}{{post.rsvp}}{{post.bookmark}}"{% if forloop.first != true %},{% endif %}
        }{% endif %}{% endif %}{% endfor %}
}

The code had to look for all the types of Webmention just to check if there was anything to send. It meant it would lead to verbose template logic. It’s a bad code smell. At the time I knew it wasn’t the best, getting something running is half the problem, we can refine later. So let’s refine it.

Refactoring the front matter from before, as below, is immediately better.

webmention: "reply"
target: "https://aaronparecki.com/2018/06/30/11/your-first-webmention"

This is easy to read and clearly states what it is doing.

We only care if a target exists to generate the feed item. What type of Webmention we are sending will be determined by the receiver when they validate the page and look at the Microformats embedded in the page.

It means we can refactor the previous feed code to this:

{% assign publishTime = site.data.published.time %}{
    "published":"{{publishTime}}",
    "webmentions": {% for post in site.posts %}{% assign postTime = post.date | date_to_xmlschema %}{% if postTime >= publishTime %}{% if post.target -%}{
            "source": "{{site.url}}{{ post.url }}",
            "target": "{{post.target}}"{% if forloop.first != true %},{% endif %}
        }{% endif %}{% endif %}{% endfor %}
}

Declaring the Webmention type like this webmention: “reply” also results in much cleaner code.

Previously in the header of each article and note page I had an include file called “author” that looked like this:

<div class="u-author h-card dg mini-two-col-grid mb5 align-items-center">
  <img src="{{site.data.author.profilePic}}" width="40" class="u-photo br-circle" alt="Vincent Pickering a Service Designer & UI/UX Consultant, based in Leeds, U.K.">
  <p class="grey fw3 f7">
    Published by <a class="black" href="{{page.url}}">{{ site.data.author.name }}</a>
    {% if page.replyUrl and page.replyUrl != '' -%}<a class="u-in-reply-to" href="{{page.replyUrl}}">in response</a>{% endif %}
    {% if page.like and page.like != '' -%}Favourited: <a class="u-like-of" href="{{page.like}}">this</a>{% endif %}
    {% if page.repost and page.repost != '' -%}Reposted: <a class="u-repost-of" href="{{page.repost}}">this</a>{% endif %}
    {% if page.rsvp and page.rsvp != '' -%}RSVP'd to: <a class="u-rsvp" href="{{page.rsvp}}">this</a>{% endif %}
    {% if page.bookmark and page.bookmark != '' -%}Bookmarked: <a class="u-bookmark-of" href="{{page.bookmark}}">this</a>{% endif %}
    <br>on <a class="u-url black" href="{{page.url}}"><time class="dt-published" datetime="{{ page.date | date_to_xmlschema }}">
        {{ page.date | date_to_string: "ordinal" }} <span>at</span> {{ page.date | date: "%H" }}:{{ page.date | date: "%M%P" }}
    </time></a></p>
</div>

Pretty ugly!

With the refactored code we can do something a bit more elegant like this:

{% case page.webmention %}
    {% when "reply" %}
        {% assign webmentionType = "u-in-reply-to" %}
        {% assign wmExtraText = "in " %}
        {% assign wmText = "response" %}
    {% when "like" %}
        {% assign webmentionType = "u-like-of" %}
        {% assign wmExtraText = "Favourited " %}
        {% assign wmText = "this" %}
    {% when "repost" %}
        {% assign webmentionType = "u-repost-of" %}
        {% assign wmExtraText = "Reposted " %}
        {% assign wmText = "this" %}
    {% when "rsvp" %}
        {% assign webmentionType = "u-rsvp" %}
        {% assign wmExtraText = "RSVP'd " %}
        {% assign wmText = "to this" %}
    {% when "bookmark" %}
        {% assign webmentionType = "u-bookmark-of" %}
        {% assign wmExtraText = "Bookmarked " %}
        {% assign wmText = "this" %}
{% endcase %}

{% capture webmentionText %}
     {{wmExtraText}}<a class="{{webmentionType}}" href="{{page.target}}">{{wmText}}</a>
{% endcapture %}

<div class="u-author h-card mini-two-col-grid mb5 align-items-center">
    <img src="{{site.data.author.profilePic}}" width="40" class="u-photo br-circle" alt="Vincent Pickering">
    <p class="grey fw3 f7">Published by <a class="u-url p-name black" href="{{page.url}}">{{ site.data.author.name }}</a>{% if page.webmention %}{{webmentionText}}{% endif %}
    <br>on <a class="u-url black" href="{{page.url}}"><time class="dt-published" datetime="{{ page.date | date_to_xmlschema }}">
        {{ page.date | date_to_string: "ordinal" }} <span>at</span> {{ page.date | date: "%H" }}:{{ page.date | date: "%M%P" }}
    </time></a>
    </p>
</div>

The include code ends up being longer. But it is far more readable and quicker to execute (about 0.2 seconds faster).

By reducing the if statements looking for multiple variables and simplifying down to the case statement it should be easier to maintain and extend later. Separating the logic for the link and Microformat code inserted away from the HTML code block, keeps things clear and unambiguous.