351 lines
12 KiB
Markdown
351 lines
12 KiB
Markdown
---
|
||
author: "Chris Burnell"
|
||
title: "eleventy-cache-webmentions"
|
||
source: https://chrisburnell.com/eleventy-cache-webmentions/
|
||
clipped: 2024-06-25
|
||
published: 2022-01-15
|
||
topics:
|
||
tags: [clipping]
|
||
---
|
||
|
||
# eleventy-cache-webmentions
|
||
|
||
Cache webmentions using eleventy-fetch and make them available to use in collections, layouts, pages, etc. in Eleventy.
|
||
There are 21 stargazers [on GitHub](https://github.com/chrisburnell/eleventy-cache-webmentions) and it has over 9,150 downloads [on npm](https://www.npmjs.com/package/@chrisburnell/eleventy-cache-webmentions).
|
||
|
||
![A hand with a tattoo reading, “Cache up Sucker” with a dollar sign in the middle](https://chrisburnell.com/images/built/eleventy-cache-webmentions-395.png "A hand with a tattoo reading, “Cache up Sucker” with a dollar sign in the middle")
|
||
|
||
[![eleventy-cache-webmentions on GitHub](https://img.shields.io/static/v1?label=chrisburnell&message=eleventy-cache-webmentions&color=5f8aa6&logo=github)](https://github.com/chrisburnell/eleventy-cache-webmentions "Go to Repository: @chrisburnell/eleventy-cache-webmentions") [![eleventy-cache-webmentions Releases](https://img.shields.io/github/release/chrisburnell/eleventy-cache-webmentions?include_prereleases=&sort=semver&color=5f8aa6)](https://github.com/chrisburnell/eleventy-cache-webmentions/releases "Go to Releases: @chrisburnell/eleventy-cache-webmentions") [![eleventy-cache-webmentions License](https://img.shields.io/badge/License-MIT-5f8aa6)](https://github.com/chrisburnell/eleventy-cache-webmentions/blob/main/LICENSE "Go to License: @chrisburnell/eleventy-cache-webmentions")
|
||
|
||
Breaking changes for v2.0.0!
|
||
|
||
Version 2.0.0 introduces a breaking change for those migrating from earlier versions of the plugin. This affects usage of the plugin from JavaScript files; specifically, you will need to make a small change to the way that you `require()` the plugin by removing an extra set of parentheses:
|
||
|
||
**v1.2.5 and below**
|
||
|
||
```
|
||
require("@chrisburnell/eleventy-cache-webmentions")()
|
||
```
|
||
|
||
**v2.0.0 and above**
|
||
|
||
```
|
||
require("@chrisburnell/eleventy-cache-webmentions")
|
||
```
|
||
|
||
## Installation [Permalink ¶](#installation "Permalink for Installation")
|
||
|
||
[Available on npm](https://www.npmjs.com/package/@chrisburnell/eleventy-cache-webmentions):
|
||
|
||
```
|
||
npm install @chrisburnell/eleventy-cache-webmentions --save-dev
|
||
```
|
||
|
||
You can also download it directly [from GitHub](https://github.com/chrisburnell/eleventy-cache-webmentions):
|
||
|
||
[https://github.com/chrisburnell/eleventy-cache-webmentions/archive/main.zip](https://github.com/chrisburnell/eleventy-cache-webmentions/archive/main.zip)
|
||
|
||
Inside your Eleventy config file, use `addPlugin()` to add it to your project:
|
||
|
||
```
|
||
const pluginWebmentions = require("@chrisburnell/eleventy-cache-webmentions")
|
||
|
||
module.exports = function(eleventyConfig) {
|
||
eleventyConfig.addPlugin(pluginWebmentions, {
|
||
|
||
domain: "https://example.com",
|
||
feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
|
||
key: "array_of_webmentions"
|
||
})
|
||
}
|
||
```
|
||
|
||
Full options list
|
||
|
||
```
|
||
const pluginWebmentions = require("@chrisburnell/eleventy-cache-webmentions")
|
||
|
||
module.exports = function(eleventyConfig) {
|
||
eleventyConfig.addPlugin(pluginWebmentions, {
|
||
|
||
domain: "https://example.com",
|
||
|
||
|
||
feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
|
||
|
||
|
||
|
||
key: "array_of_webmentions",
|
||
|
||
|
||
|
||
directory: ".cache",
|
||
|
||
|
||
|
||
duration: "1d",
|
||
|
||
|
||
uniqueKey: "webmentions",
|
||
|
||
|
||
|
||
|
||
|
||
allowedHTML: {
|
||
allowedTags: ["b", "i", "em", "strong", "a"],
|
||
allowedAttributes: {
|
||
a: ["href"],
|
||
},
|
||
},
|
||
|
||
|
||
allowlist: [],
|
||
|
||
|
||
blocklist: [],
|
||
|
||
|
||
|
||
urlReplacements: {},
|
||
|
||
|
||
|
||
|
||
maximumHtmlLength: 2000,
|
||
|
||
|
||
|
||
maximumHtmlText: "mentioned this in",
|
||
})
|
||
}
|
||
```
|
||
|
||
## Usage [Permalink ¶](#usage "Permalink for Usage")
|
||
|
||
`eleventy-cache-webmentions` comes with a number of ways of accessing your Webmentions as [Global Data](https://www.11ty.dev/docs/data-global-custom/) in both JavaScript and Liquid/Nunjucks as well as a series of [Eleventy Filters](https://www.11ty.dev/docs/filters/) and JavaScript Functions for filtering, sorting, and reading properties about each Webmention:
|
||
|
||
### Global Data
|
||
|
||
JavaScript
|
||
|
||
```
|
||
const {
|
||
defaults,
|
||
webmentionsByUrl,
|
||
} = require("@chrisburnell/eleventy-cache-webmentions")
|
||
```
|
||
|
||
Liquid / Nunjucks
|
||
|
||
```
|
||
|
||
{{ webmentionsDefaults }}
|
||
|
||
{{ webmentionsByUrl }}
|
||
```
|
||
|
||
### Filters
|
||
|
||
JavaScript
|
||
|
||
```
|
||
const {
|
||
getWebmentions,
|
||
getWebmentionsByTypes,
|
||
getWebmentionPublished,
|
||
getWebmentionContent,
|
||
getWebmentionSource,
|
||
getWebmentionTarget,
|
||
getWebmentionType,
|
||
} = require("@chrisburnell/eleventy-cache-webmentions")
|
||
|
||
|
||
|
||
const webmentions = getWebmentions({
|
||
domain: "https://example.com",
|
||
feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
|
||
key: "array_of_webmentions"
|
||
}, "https://example.com/specific-page/")
|
||
|
||
const responsesOnly = getWebmentionsByTypes(webmentions, ['mention-of', 'in-reply-to'])
|
||
|
||
webmentions.forEach((webmention) => {
|
||
const published = getWebmentionPublished(webmention)
|
||
const content = getWebmentionContent(webmention)
|
||
const source = getWebmentionSource(webmention)
|
||
const target = getWebmentionTarget(webmention)
|
||
const type = getWebmentionType(webmention)
|
||
})
|
||
```
|
||
|
||
Liquid / Nunjucks
|
||
|
||
```
|
||
|
||
{% set webmentions = ('https://example.com' + page.url) | getWebmentions %}
|
||
|
||
|
||
{{ set responses = webmentions | getWebmentionsByTypes(['mention-of', 'in-reply-to']) }}
|
||
|
||
{% for webmention in webmentions %}
|
||
|
||
{{ webmentions | getWebmentionPublished }}
|
||
|
||
{{ webmentions | getWebmentionContent }}
|
||
|
||
{{ webmentions | getWebmentionSource }}
|
||
|
||
{{ webmentions | getWebmentionTarget }}
|
||
|
||
{{ webmentions | getWebmentionType }}
|
||
{% endfor %}
|
||
```
|
||
|
||
## Attach Webmentions to Pages using Directory Data [Permalink ¶](#attach-webmentions "Permalink for Attach Webmentions to Pages using Directory Data")
|
||
|
||
Using [Eleventy’s Data Cascade](https://www.11ty.dev/docs/data-cascade/), you can attach Webmentions to each page by using [Directory Specific Data Files](https://www.11ty.dev/docs/data-template-dir/).
|
||
|
||
For example, if you have a folder, `/pages/`, and want to attach Webmentions to each page, create or add the following to a `pages.11tydata.js` file within the folder:
|
||
|
||
```
|
||
const { getWebmentions, getPublished } = require("@chrisburnell/eleventy-cache-webmentions")
|
||
|
||
module.exports = {
|
||
eleventyComputed: {
|
||
webmentions: (data) => {
|
||
|
||
const webmentionsForUrl = getWebmentions({
|
||
domain: "https://example.com",
|
||
feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
|
||
key: "array_of_webmentions"
|
||
}, "https://example.com" + data.page.url)
|
||
|
||
|
||
if (webmentionsForUrl.length) {
|
||
|
||
return webmentionsForUrl.sort((a, b) => {
|
||
return getPublished(b) - getPublished(a)
|
||
})
|
||
}
|
||
|
||
return []
|
||
},
|
||
},
|
||
}
|
||
```
|
||
|
||
This attaches an Array containing Webmentions to each page (based on its URL). You can then access this Array of Webmentions with the variable, webmentions, within a [Layout](https://www.11ty.dev/docs/layouts/), [Include](https://www.11ty.dev/docs/includes/), or from the page itself:
|
||
|
||
```
|
||
{% for webmention in webmentions %}
|
||
|
||
{% endfor %}
|
||
```
|
||
|
||
These Arrays of Webmentions can even be accessed when building [Collections](https://www.11ty.dev/docs/collections/), allowing you to create a Collection of pages sorted by their number of Webmentions, for example:
|
||
|
||
```
|
||
module.exports = (eleventyConfig) => {
|
||
eleventyConfig.addCollection("popular", (collection) => {
|
||
return collection
|
||
.sort((a, b) => {
|
||
return b.data.webmentions.length - a.data.webmentions.length
|
||
})
|
||
})
|
||
}
|
||
```
|
||
|
||
## Without Directory Data [Permalink ¶](#without-directory-data "Permalink for Without Directory Data")
|
||
|
||
If you would rather get Webmentions for a given page directly from a Layout/Include/Page itself, you can do so using the Filter, `getWebmentions`:
|
||
|
||
```
|
||
{% set webmentions = ('https://example.com' + page.url) | getWebmentions %}
|
||
{% for webmention in webmentions %}
|
||
...
|
||
{% endfor %}
|
||
```
|
||
|
||
## Get specific types of Webmentions [Permalink ¶](#allowed-types "Permalink for Get specific types of Webmentions")
|
||
|
||
Instead of getting all the Webmentions for a given page, you may want to grab only certain types of Webmentions. This is useful if you want to display different types of Webmentions separately, e.g.:
|
||
|
||
```
|
||
{% set bookmarks = webmentions | getWebmentionsByTypes(['bookmark-of']) %}
|
||
{% set likes = webmentions | getWebmentionsByTypes(['like-of']) %}
|
||
{% set reposts = webmentions | getWebmentionsByTypes(['repost-of']) %}
|
||
|
||
{% set replies = webmentions | getWebmentionsByTypes(['mention-of', 'in-reply-to']) %}
|
||
```
|
||
|
||
## Get all Webmentions at once [Permalink ¶](#all-webmentions "Permalink for Get all Webmentions at once")
|
||
|
||
If you need it, the plugin also makes available an Object containing your cached Webmentions organised in key:value pairs, where each key is a full URL on your website and its value is an Array of Webmentions sent to that URL:
|
||
|
||
```
|
||
{% set count = 0 %}
|
||
{% for url, array in webmentionsByUrl %}
|
||
{% set count = array.length + count %}
|
||
{% endfor %}
|
||
<p>This website has received {{ count }} Webmentions!</p>
|
||
```
|
||
|
||
## Webmention.io [Permalink ¶](#webmention-io "Permalink for Webmention.io")
|
||
|
||
[Webmention.io](https://webmention.io/) is a in-place Webmention receiver solution that you can use by authenticating yourself via [IndieAuth](https://indieauth.com/) (or host it yourself), and, like *so much* other publicly-available IndieWeb software, is built and hosted by [Aaron Parecki](https://aaronparecki.com/).
|
||
|
||
### Add your token
|
||
|
||
Get set up on [Webmention.io](https://webmention.io/) and add your **API Key** (found on your [settings page](https://webmention.io/settings)) to your project as an environment variable, i.e. in a `.env` file in the root of your project:
|
||
|
||
```
|
||
WEBMENTION_IO_TOKEN=njJql0lKXnotreal4x3Wmd
|
||
```
|
||
|
||
### Set your feed and key config options
|
||
|
||
The example below requests the [JF2](https://www.w3.org/TR/jf2/) file format, which I highly recommend using; although, there is a JSON format available from [Webmention.io](https://webmention.io/) as well. The [official documentation](https://github.com/aaronpk/webmention.io) has more information on how to use these two formats.
|
||
|
||
The key difference between the two feed formats is in the *naming* of the keys: the JF2 format holds the array of Webmentions in the `children` key, whereas the JSON format holds them in the `links` key. The JF2 format, however, provides keys and values that more tightly-align with [microformats](https://indieweb.org/microformats), the method I recommend the most for marking up HTML such that it can be consumed and understood by search engines, aggregators, and other tools across the IndieWeb.
|
||
|
||
```
|
||
const pluginWebmentions = require("@chrisburnell/eleventy-cache-webmentions")
|
||
|
||
module.exports = function(eleventyConfig) {
|
||
eleventyConfig.addPlugin(pluginWebmentions, {
|
||
domain: "https://example.com",
|
||
feed: `https://webmention.io/api/mentions.jf2?domain=example.com&per-page=9001&token=${process.env.WEBMENTION_IO_TOKEN}`,
|
||
key: "children"
|
||
})
|
||
}
|
||
```
|
||
|
||
If you want to use the JSON format instead, make sure that you replace `mentions.jf2` in the URL with `mentions.json` and change the value of the key from `children` to `links`.
|
||
|
||
## go-jamming [Permalink ¶](#go-jamming "Permalink for go-jamming")
|
||
|
||
[go-jamming](https://git.brainbaking.com/wgroeneveld/go-jamming) is a self-hosted Webmention sender and receiver, built in Go by [Wouter Groeneveld](https://brainbaking.com/) and available with more information on his [personal git instance](https://git.brainbaking.com/wgroeneveld/go-jamming).
|
||
|
||
### Add your token
|
||
|
||
Once you’ve set up your *go-jamming* server and you’ve defined your token, you’ll need add it to your project as an environment variable, i.e. in a `.env` file in the root of your project:
|
||
|
||
```
|
||
GO_JAMMING_TOKEN=njJql0lKXnotreal4x3Wmd
|
||
```
|
||
|
||
### Set your feed and key config options
|
||
|
||
```
|
||
const pluginWebmentions = require("@chrisburnell/eleventy-cache-webmentions")
|
||
|
||
module.exports = function(eleventyConfig) {
|
||
eleventyConfig.addPlugin(pluginWebmentions, {
|
||
domain: "https://example.com",
|
||
feed: `https://jam.example.com/webmention/example.com/${process.env.GO_JAMMING_TOKEN}`,
|
||
key: "json"
|
||
})
|
||
}
|
||
```
|