A Jekyll Plugin for rendering Webmentions via Webmention.io
Ruby JavaScript HTML Shell
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.

README.md

A Jekyll plugin for sending & receiving webmentions via Webmention.io

This gem includes a suite of tools for managing webmentions in Jekyll:

There are also a few JavaScript enhancement features available.

Other topics you might be interested in:

Quickstart

If you just want to get up and running quickly, here’s the rundown of what you need to do:

  1. Add gem 'jekyll-webmention_io' to the :jekyll_plugins group in your Gemfile
  2. Run bundle install
  3. Add the {% webmentions_head %} tag to the head of your site
  4. Add the {% webmentions %} tag to the layout for your posts where you want webmentions displayed
  5. (Optional) Add the {% webmentions_js %} tag to the bottom of your posts template (before the </body> tag)

If you want to customize your install, read on…

Webmention support

All inbound webmentions of your posts are collected (see below for info on adding pages & collections into the mix). The following are able to be distilled and handled separately:

  • bookmarks,
  • links,
  • likes,
  • posts,
  • replies,
  • reposts, and
  • RSVPs.

Configuration

This gem will work well out of the box, but is configurable in a number of ways. Note: all of these configuration options should nest under a webmentions key in your _config.yml file.

  • cache_folder - by default, this gem will cache all files in the .jekyll-cache, but you can specify another location (like _data) if you like. In order to avoid collisions, all cache files will be prefixed with "webmention_io_" unless your cache_folder value contains "webmention" (e.g. .jekyll_cache/webmentions)
  • cache_bad_uris_for - In order to reduce unnecessary requests to servers that aren’t responding, this gem will keep track of them and avoid making new requests to them for 1 day. If you’d like to adjust this up or down, you can use this configuration value. It expects a number corresponding to the number of days you want to wait before trying the domain again.
  • legacy_domains - If you’ve relocated your site from another URL or moved from to HTTPS from HTTP, you can use this configuration option to specify additional domains to append your page.url to. It expects an array.
  • templates - If you would like to roll your own templates, you totally can. You will need to assign a hash of the template paths to use for loading each one.
  • username - Your webmention.io username (for use in the link tags in your head)

Simple Example

webmentions:
  username: YOUR_USERNAME
  # Use my own cache folder
  cache_folder: .cache
  # skip bad URLs for 5 days
  cache_bad_uris_for: 5
  # I moved to www and then to https, so…
  legacy_domains:
    - http://aaron-gustafson.com
    - http://www.aaron-gustafson.com

Exhaustive Example

webmentions:
  username: YOUR_USERNAME
  cache_folder: .cache
  cache_bad_uris_for: 5
  legacy_domains:
    - http://aaron-gustafson.com
    - http://www.aaron-gustafson.com
  templates:
    count: _includes/webmentions/count.html
    likes: _includes/webmentions/likes.html
    links: _includes/webmentions/links.html
    posts: _includes/webmentions/posts.html
    replies: _includes/webmentions/replies.html
    reposts: _includes/webmentions/reposts.html
    webmentions: _includes/webmentions/webmentions.html

Performance Tuning Your Build

Looking up webmentions is a time-consuming process and can really increase your build times. As it’s likely that engagement with your content will go down over time, this plugin enables you to tailor how often you want to look for new webmentions of your posts. Using the webmentions.throttle_lookups key, you can deal with posts in the follwing broad categories:

  • last_week - Posts with a date in the last week
  • last_month - Posts with a date in the last month
  • last_year - Posts with a date in the last year
  • older - Everything else

Each of these accepts one of the following values:

  • daily
  • weekly
  • monthly
  • yearly
  • every <digit> [ days | weeks | months | years]

For instance, it might be sensible to look for webmentions daily for posts you’ve made in the last week, weekly for posts made in the last month, every 2 weeks for posts made in the last year, and monthly thereafter. To do that you’d set up the configuration like this:

webmentions:
  throttle_lookups:
    last_week: daily
    last_month: weekly
    last_year: every 2 weeks
    older: monthly

You can also completely "pause" lookups by setting pause_lookups to true:

webmentions:
  pause_lookups: true

It’s worth noting that throttling and pausing only apply to looking for new webmentions. Any existing webmentions that have already been gathered and cached will still be used to output the site.

What’s checked

Given the tim-consuming nature of collecting and sending webmentions, by default this plugin will only look at your site’s posts (stuff in the _posts directory or what’s returned in site.posts.docs). In reality, there can be many more content types in a Jekyll site and you may want to include them with outgoing webmentions or look for inbound webmentions to them. You can customize your installation to include arbitrary pages and/or Jekyll Collections by altering your _config.yml.

Add pages by setting pages to true:

webmentions:
  pages: true

You can add all collections by setting collections to true:

webmentions:
  collections: true

Since you can have multiple collections and you may not want to apply the same logic to all of them, you can cherry-pick specific collections you’d like to include by setting the collections value to an array:

webmentions:
  collections:
    - links

Picking Up Redirects

If you’ve ever changed the path to your posts, you may have used the jekyll-redirect-from gem. jekyll-webmention_io will look for a redirect_from key in your YAML front matter and automatically include that original URL in any requests for webmentions so none get left behind.

Tags

The various tag options provided by this gem are focused around display of information about incoming webmentions.

webmention_count

Displays a count of webmentions for the current page.url:

{% webmention_count page.url %}

The output will be a number.

You can optionally filter this number by one or more supported webmention types. For instance, if you only wanted posts and replies, you could use this format:

{% webmention_count page.url posts replies %}

webmentions

You can get a complete list of webmentions for a given page.url using the following liquid tag:

{% webmentions page.url %}

The webmentions found, if any, will be piped into the webmentions template your specified in your configuration or the default one that ships with this gem.

You can optionally filter this list by one or more supported webmention types. For instance, if you only wanted posts and replies, you could use this format:

{% webmentions page.url posts replies %}

Default template info

If you go with the default template, here’s a rundown of elements and class names in use in the template:

  • webmentions - overall container (div)
  • webmentions__list - the list of webmentions (ol)
  • webmentions__item - the webmention container (li)
  • webmention - the webmention itself (article)
    • webmention--[type] - modifier for the type
    • webmention--no-author - added if there’s no author info available
    • webmention--no-photo - added if there’s no photo of the author availble
    • webmention--author-starts - variant for when the author’s name starts the content (as in a tweet interaction such as a favorite or retweet)
    • h-cite - Citation Microformat
  • webmention__author - Author of the webmention (div)
  • u-url - Person Microformat (a)
  • webmention__author__photo - Author’s photo (img)
  • webmention__content - The webmention’s content container (div)
  • webmention__meta - The webmention’s meta information container (div)
  • webmention__pubdate - The publication date (time)
  • webmention__source - The webmention permalink (a)
  • webmentions__not-found - The "no results" message shown if no mentions are found (p)

webmention_bookmarks

You can get a complete list of "bookmark" webmentions for a given page.url using the following liquid tag:

{% webmention_bookmarks page.url %}

The webmentions found, if any, will be piped into the webmentions template your specified in your configuration or the default one that ships with this gem.

webmention_bookmarks template info

If you go with the default template, here’s a rundown of elements and class names in use in the template:

  • webmentions - overall container (div)
    • webmentions--bookmarks - Identifies this as only pertaining to "bookmarks"
  • webmentions__list - the list of webmentions (ol)
  • webmentions__item - the webmention container (li)
    • webmention
    • webmention--bookmark
  • webmention__meta - The webmention’s meta information container (div)
  • webmention__author - Author of the webmention (a)
  • webmention__source - The webmention permalink (a)
  • webmention__pubdate - The publication date (time)
  • webmentions__not-found - The "no results" message shown if no mentions are found (p)

webmention_likes

You can get a complete list of "like" webmentions for a given page.url using the following liquid tag:

{% webmention_likes page.url %}

The webmentions found, if any, will be piped into the webmentions template your specified in your configuration or the default one that ships with this gem.

webmention_likes template info

If you go with the default template, here’s a rundown of elements and class names in use in the template:

  • webmentions - overall container (div)
    • webmentions--likes - Identifies this as only pertaining to "likes"
  • webmentions__list - the list of webmentions (ol)
  • webmentions__item - the webmention container (li)
    • webmention
    • webmention--like
  • webmention__author - Author of the webmention (div)
  • u-url - Person Microformat (a)
  • webmention__author__photo - Author’s photo (img)
  • webmentions__not-found - The "no results" message shown if no mentions are found (p)

webmention_links

You can get a complete list of "link" webmentions for a given page.url using the following liquid tag:

{% webmention_links page.url %}

The webmentions found, if any, will be piped into the webmentions template your specified in your configuration or the default one that ships with this gem.

webmention_links template info

If you go with the default template, here’s a rundown of elements and class names in use in the template:

  • webmentions - overall container (div)
    • webmentions--links - Identifies this as only pertaining to "links"
  • webmentions__list - the list of webmentions (ol)
  • webmentions__item - the webmention container (li)
    • webmention
    • webmention--like
  • webmention__meta - The webmention’s meta information container (div)
  • webmention__author - Author of the webmention (a)
  • webmention__source - The webmention permalink (a)
  • webmention__pubdate - The publication date (time)
  • webmentions__not-found - The "no results" message shown if no mentions are found (p)

webmention_posts

You can get a complete list of "posts" webmentions for a given page.url using the following liquid tag:

{% webmention_posts page.url %}

The webmentions found, if any, will be piped into the webmentions template your specified in your configuration or the default one that ships with this gem.

webmention_posts template info

If you go with the default template, here’s a rundown of elements and class names in use in the template:

  • webmentions - overall container (div)
    • webmentions--posts - Identifies this as only pertaining to "posts"
  • webmentions__list - the list of webmentions (ol)
  • webmentions__item - the webmention container (li)
    • webmention
    • webmention--post
  • webmention__title - The title of the post (a)
  • webmention__meta - The webmention’s meta information container (div)
  • webmention__pubdate - The publication date (time)
  • webmentions__not-found - The "no results" message shown if no mentions are found (p)

webmention_replies

You can get a complete list of "reply" webmentions for a given page.url using the following liquid tag:

{% webmention_replies page.url %}

The webmentions found, if any, will be piped into the webmentions template your specified in your configuration or the default one that ships with this gem.

webmention_replies template info

If you go with the default template, here’s a rundown of elements and class names in use in the template:

  • webmentions - overall container (div)
    • webmentions--replies - Identifies this as only pertaining to "replies"
  • webmentions__list - the list of webmentions (ol)
  • webmentions__item - the webmention container (li)
    • webmention
    • webmention--reply
  • webmention__meta - The webmention’s meta information container (div)
  • webmention__author - Author of the webmention (a)
  • webmention__author__photo - Author’s photo (img)
  • p-name - Author’s name (b)
  • webmention__source - The webmention permalink (a)
  • webmention__pubdate - The publication date (time)
  • webmentions__not-found - The "no results" message shown if no mentions are found (p)

webmention_reposts

You can get a complete list of "repost" webmentions for a given page.url using the following liquid tag:

{% webmention_reposts page.url %}

The webmentions found, if any, will be piped into the webmentions template your specified in your configuration or the default one that ships with this gem.

webmention_reposts template info

If you go with the default template, here’s a rundown of elements and class names in use in the template:

  • webmentions - overall container (div)
    • webmentions--reposts - Identifies this as only pertaining to "likes"
  • webmentions__list - the list of webmentions (ol)
  • webmentions__item - the webmention container (li)
    • webmention
    • webmention--repost
  • webmention__author - Author of the webmention (div)
  • u-url - Person Microformat (a)
  • webmention__author__photo - Author’s photo (img)
  • webmentions__not-found - The "no results" message shown if no mentions are found (p)

webmention_rsvps

You can get a complete list of "RSVP" webmentions for a given page.url using the following liquid tag:

{% webmention_rsvps page.url %}

The webmentions found, if any, will be piped into the webmentions template your specified in your configuration or the default one that ships with this gem.

webmention_rsvps template info

If you go with the default template, here’s a rundown of elements and class names in use in the template:

  • webmentions - overall container (div)
    • webmentions--rsvps - Identifies this as only pertaining to "RSVPs"
  • webmentions__list - the list of webmentions (ol)
  • webmentions__item - the webmention container (li)
    • webmention
    • webmention--rsvp
  • webmention__author - Author of the webmention (div)
  • u-url - Person Microformat (a)
  • webmention__author__photo - Author’s photo (img)
  • p-name - Author’s name (b)
  • webmentions__not-found - The "no results" message shown if no mentions are found (p)

webmentions_head

To insert bits and bobs that will help webmention-enable your site, you’ll want to include this in the head of your pages. If you include a username in your configuration, it will automatically generate the link elements necessary to notify webmention clients of the webmention.io endpoint where webmentions should be sent. It will also drop in information about any redirects in play for the current page and insert Client Hints that will make the JavaScript enhancements faster.

<head>
  …
  {% webmentions_head %}
</head>

Commands

Webmentions are not automatically sent when building your Jekyll project as that may not always be desirable. That said, this gem does automatically collect mentions made in your posts. It caches them and makes them available to you to send using the following command:

$> jekyll webmention

Generators

This gem includes two generators. One collects any webmentions referencing your posts. The other collects any webmentions you may have made in order to queue them up for sending using the jekyll webmention command.

JavaScript enhancements

Because static websites are, well, static, it’s possible webmentions might have accrued since your site was last built. This gem includes JavaScript code to pipe those webmentions into your pages asynchronously. These features are turned on by default, but require some tags in order to work:

  …
  {% webmentions_js %}
</body>

Include this tag before your post layout’s </body> and the plugin will render in a script tag pointing to the JekyllWebmentionIO.js file and generate template tags corresponding to the various Liquid templates (default or custom) being used to render your webmentions.

We are using liquid.js, a JavaScript port of Liquid by Matt McCray, to render these webmentions.

If you use Content Security Policy, you need to add these values:

script-src https://webmention.io
connect-src ws://webmention.io:8080

The JavaScript file

By default, this gem will render a new file, JekyllWebmentionIO.js, into the js directory in your source folder. The file will be compressed using a Ruby port of Uglify. This file will also get added to your deployment build (even on the first run). For most use cases, this approach plus the webmentions_js Liquid tag will be perfectly adequate, but if you need more control, there are a few configuration options available. All are nested in webmentions.js:

  • deploy - If you would rather manage the deployment of this JavaScript file independently, add this property and set it to false. The file will not be added to your site build. If you do this, you will likely also want to set the destination to a directory Jekyll excludes.
  • destination - Where you want the file to be put within your site’s source folder. If you don’t explicitly name a location, the file will be placed in SOURCE_FOLDER/js.
  • source - If you do not want the JavaScript file added to your Jekyll install’s source folder, set this to false
  • uglify - If you would prefer to minify the file yourself using another tool, add this property and set it to false.

Here’s an example that deploys to an ignored folder and doesn’t bother with minification or deployment (as I use a Gulp task to build and minify my JavaScript files):

webmentions:
  cache_folder: _data
  cache_bad_uris_for: 5
  legacy_domains:
    - http://aaron-gustafson.com
    - http://www.aaron-gustafson.com
  js:
    destination: _javascript/posts
    uglify: false
    deploy: false

You can also disable all JavaScript-related actions of this gem globally:

webmentions:
  cache_folder: _data
  cache_bad_uris_for: 5
  legacy_domains:
    - http://aaron-gustafson.com
    - http://www.aaron-gustafson.com
  js: false

Streaming Mentions

Coming Soon!

Debugging

To enable debugging, add debug: true to the config:

webmentions:
  debug: true