Skip to content

Commit

Permalink
prevent hammering the process of filtering webmentions
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisburnell committed Feb 5, 2023
1 parent 3d2375a commit 8720f2f
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 103 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ trim_trailing_whitespace = true

[*.md]
indent_style = space
indent_size = 4
indent_size = 2
trim_trailing_whitespace = false
4 changes: 4 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
semi: false
printWidth: 9999
tabWidth: 4
overrides:
- files: "*.md"
options:
tabWidth: 2
180 changes: 90 additions & 90 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ I wrote a quicker and simpler guide to getting this Eleventy plugin working that

## Installation

- **With npm:** `npm install @chrisburnell/eleventy-cache-webmentions`
- **Direct download:** [https://github.com/chrisburnell/eleventy-cache-webmentions/archive/master.zip](https://github.com/chrisburnell/eleventy-cache-webmentions/archive/master.zip)
- **With npm:** `npm install @chrisburnell/eleventy-cache-webmentions`
- **Direct download:** [https://github.com/chrisburnell/eleventy-cache-webmentions/archive/master.zip](https://github.com/chrisburnell/eleventy-cache-webmentions/archive/master.zip)

Once installed there are **two** more **required** set-up steps:

Expand All @@ -21,12 +21,12 @@ Inside your Eleventy config file (typically `.eleventy.js`), use `addPlugin`:
const pluginWebmentions = require("@chrisburnell/eleventy-cache-webmentions")

module.exports = function (eleventyConfig) {
eleventyConfig.addPlugin(pluginWebmentions, {
// these 3 fields are all required!
domain: "https://example.com",
feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
key: "children",
})
eleventyConfig.addPlugin(pluginWebmentions, {
// these 3 fields are all required!
domain: "https://example.com",
feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
key: "children",
})
}
```

Expand All @@ -38,51 +38,51 @@ Advanced control over how the Webmentions are cached and processed is done by pa
const pluginWebmentions = require("@chrisburnell/eleventy-cache-webmentions")

module.exports = function (eleventyConfig) {
eleventyConfig.addPlugin(pluginWebmentions, {
// domain: required or the plugin will not function
// this is the website that you want to pull in Webmentions for
domain: "https://example.com",
// feed: required or the plugin will not function
// defines the URL of your Webmention server where a feed of Webmentions for your domain can be found
feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
// key: required or the plugin will not function
// dictates the key inside the feed where the array of Webmentions is located
key: "children",
// directory: ".cache" by default
// see https://www.11ty.dev/docs/plugins/cache/#cache-directory for more info
directory: ".cache",
// duration: "1d" by default
// see https://www.11ty.dev/docs/plugins/cache/#change-the-cache-duration for more info
duration: "1d",
// uniquekey: "webmentions" by default
// dictates the name sent to eleventy-fetch to name the file
uniqueKey: "webmentions",
// allowedHTML: Object by default
// see https://www.npmjs.com/package/sanitize-html for more info
allowedHTML: {
allowedTags: ["b", "i", "em", "strong", "a"],
allowedAttributes: {
a: ["href"],
},
},
// allowlist: [] by default
// array of root URLs from which webmentions are wanted exclusively
allowlist: [],
// blocklist: [] by default
// array of root URLs from which webmentions are not wanted
// exclusively
blocklist: [],
// urlReplacements: {} by default
// object of key:value pairs containing from:to URL replacements
urlReplacements: {},
// maximumHtmlLength: 2000 by default
// number of characters in the HTML content at which a different
// message is shown instead of the content
maximumHtmlLength: 2000,
// maximumHtmlText: "mentioned this in" by default
// message shown when maximumHtmlLength is reached
maximumHtmlText: "mentioned this in",
})
eleventyConfig.addPlugin(pluginWebmentions, {
// domain: required or the plugin will not function
// this is the website that you want to pull in Webmentions for
domain: "https://example.com",
// feed: required or the plugin will not function
// defines the URL of your Webmention server where a feed of Webmentions for your domain can be found
feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
// key: required or the plugin will not function
// dictates the key inside the feed where the array of Webmentions is located
key: "children",
// directory: ".cache" by default
// see https://www.11ty.dev/docs/plugins/cache/#cache-directory for more info
directory: ".cache",
// duration: "1d" by default
// see https://www.11ty.dev/docs/plugins/cache/#change-the-cache-duration for more info
duration: "1d",
// uniquekey: "webmentions" by default
// dictates the name sent to eleventy-fetch to name the file
uniqueKey: "webmentions",
// allowedHTML: Object by default
// see https://www.npmjs.com/package/sanitize-html for more info
allowedHTML: {
allowedTags: ["b", "i", "em", "strong", "a"],
allowedAttributes: {
a: ["href"],
},
},
// allowlist: [] by default
// array of root URLs from which webmentions are wanted exclusively
allowlist: [],
// blocklist: [] by default
// array of root URLs from which webmentions are not wanted
// exclusively
blocklist: [],
// urlReplacements: {} by default
// object of key:value pairs containing from:to URL replacements
urlReplacements: {},
// maximumHtmlLength: 2000 by default
// number of characters in the HTML content at which a different
// message is shown instead of the content
maximumHtmlLength: 2000,
// maximumHtmlText: "mentioned this in" by default
// message shown when maximumHtmlLength is reached
maximumHtmlText: "mentioned this in",
})
}
```

Expand All @@ -92,9 +92,9 @@ Accessing the plugin in JavaScript in the way shown below will give you an Objec

```javascript
const Webmentions = require("@chrisburnell/eleventy-cache-webmentions")(null, {
domain: "https://example.com",
feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
key: "children",
domain: "https://example.com",
feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
key: "children",
})

const webmentionsByUrl = await Webmentions()
Expand All @@ -104,40 +104,40 @@ This can prove to be very useful when building out your pages. Using [Eleventy

```javascript
const Webmentions = require("@chrisburnell/eleventy-cache-webmentions")(null, {
domain: "https://example.com",
feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
key: "children",
domain: "https://example.com",
feed: "https://webmentions.example.com?token=S3cr3tT0k3n",
key: "children",
})

module.exports = async () => {
const webmentionsByUrl = await Webmentions()

return {
eleventyComputed: {
webmentions: (data) => {
const webmentionsForUrl = webmentionsByUrl["https://example.com" + data.page.url] || []

if (webmentionsForUrl.length) {
return webmentionsForUrl.sort((a, b) => {
return (b.data.published || b.verified_date) - (a.data.published || a.verified_date)
})
}
return []
},
},
}
const webmentionsByUrl = await Webmentions()

return {
eleventyComputed: {
webmentions: (data) => {
const webmentionsForUrl = webmentionsByUrl["https://example.com" + data.page.url] || []

if (webmentionsForUrl.length) {
return webmentionsForUrl.sort((a, b) => {
return (b.data.published || b.verified_date) - (a.data.published || a.verified_date)
})
}
return []
},
},
}
}
```

You can now use this data in a number of useful ways, not limited to things like creating a collection of pages ordered by number of Webmentions:

```javascript
module.exports = (eleventyConfig) => {
eleventyConfig.addCollection("popular", (collection) => {
return collection.sort((a, b) => {
return b.data.webmentions.length - a.data.webmentions.length
})
})
eleventyConfig.addCollection("popular", (collection) => {
return collection.sort((a, b) => {
return b.data.webmentions.length - a.data.webmentions.length
})
})
}
```

Expand Down Expand Up @@ -190,11 +190,11 @@ WEBMENTION_IO_TOKEN=njJql0lKXnotreal4x3Wmd
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",
})
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",
})
}
```

Expand All @@ -216,11 +216,11 @@ GO_JAMMING_TOKEN=njJql0lKXnotreal4x3Wmd
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",
})
eleventyConfig.addPlugin(pluginWebmentions, {
domain: "https://example.com",
feed: `https://jam.example.com/webmention/example.com/${process.env.GO_JAMMING_TOKEN}`,
key: "json",
})
}
```

Expand Down
27 changes: 16 additions & 11 deletions eleventy-cache-webmentions.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,19 +74,19 @@ const defaults = {

const fetchWebmentions = async (options) => {
if (!options.domain) {
throw new Error("domain is a required field when attempting to retrieve Webmentions. See https://chrisburnell.com/eleventy-cache-webmentions/#installation for more information.")
throw new Error("domain is a required field when attempting to retrieve Webmentions. See https://www.npmjs.com/package/@chrisburnell/eleventy-cache-webmentions#installation for more information.")
}

if (!options.feed) {
throw new Error("feed is a required field when attempting to retrieve Webmentions. See https://chrisburnell.com/eleventy-cache-webmentions/#installation for more information.")
throw new Error("feed is a required field when attempting to retrieve Webmentions. See https://www.npmjs.com/package/@chrisburnell/eleventy-cache-webmentions#installation for more information.")
}

if (!options.key) {
throw new Error("key is a required field when attempting to retrieve Webmentions. See https://chrisburnell.com/eleventy-cache-webmentions/#installation for more information.")
throw new Error("key is a required field when attempting to retrieve Webmentions. See https://www.npmjs.com/package/@chrisburnell/eleventy-cache-webmentions#installation for more information.")
}

if (!options.uniqueKey) {
throw new Error("uniqueKey is a required field when attempting to retrieve Webmentions. See https://chrisburnell.com/eleventy-cache-webmentions/#installation for more information.")
throw new Error("uniqueKey is a required field when attempting to retrieve Webmentions. See https://www.npmjs.com/package/@chrisburnell/eleventy-cache-webmentions#installation for more information.")
}

let asset = new AssetCache(options.uniqueKey, options.directory)
Expand Down Expand Up @@ -127,9 +127,13 @@ const fetchWebmentions = async (options) => {
return webmentions
}

let filtered = {}
const filteredWebmentions = async (options) => {
if (Object.entries(filtered).length) {
return filtered
}

let rawWebmentions = await fetchWebmentions(options)
let webmentions = {}

// Process the blocklist, if it has any entries
if (options.blocklist.length) {
Expand Down Expand Up @@ -166,21 +170,22 @@ const filteredWebmentions = async (options) => {
rawWebmentions.forEach((webmention) => {
let url = baseUrl(fixUrl(getTarget(webmention).replace(/\/?$/, "/"), options.urlReplacements))

if (!webmentions[url]) {
webmentions[url] = []

if (!filtered[url]) {
filtered[url] = []
}

webmentions[url].push(webmention)
filtered[url].push(webmention)
})

// Remove duplicates by source URL
for (let url in webmentions) {
webmentions[url] = uniqBy(webmentions[url], (entry) => {
for (let url in filtered) {
filtered[url] = uniqBy(filtered[url], (entry) => {
return getSource(entry)
})
}

return webmentions
return filtered
}

const getWebmentions = async (options, url, allowedTypes = {}) => {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@chrisburnell/eleventy-cache-webmentions",
"version": "1.1.4",
"version": "1.1.5",
"description": "Fetch and cache webmentions using eleventy-fetch.",
"author": "Chris Burnell <me@chrisburnell.com>",
"license": "MIT",
Expand Down

0 comments on commit 8720f2f

Please sign in to comment.