fix webmentions & css
This commit is contained in:
BIN
_cache/.DS_Store
vendored
Normal file
BIN
_cache/.DS_Store
vendored
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -1,4 +1,5 @@
|
||||
import { DateTime } from "luxon";
|
||||
import sanitizeHtml from 'sanitize-html';
|
||||
|
||||
export default function(eleventyConfig) {
|
||||
eleventyConfig.addFilter("readableDate", (dateObj, format, zone) => {
|
||||
@@ -6,6 +7,10 @@ export default function(eleventyConfig) {
|
||||
return DateTime.fromJSDate(dateObj, { zone: zone || "utc" }).toFormat(format || "dd LLLL yyyy");
|
||||
});
|
||||
|
||||
eleventyConfig.addFilter('dateFromTimestamp', (timestamp) => {
|
||||
return DateTime.fromISO(timestamp, { zone: 'America/New_York' }).toJSDate()
|
||||
})
|
||||
|
||||
eleventyConfig.addFilter("htmlDateString", (dateObj) => {
|
||||
// dateObj input: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-date-string
|
||||
return DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat('yyyy-LL-dd');
|
||||
@@ -36,7 +41,7 @@ export default function(eleventyConfig) {
|
||||
const clean = (entry) => {
|
||||
const { html, text } = entry.content
|
||||
if (html) {
|
||||
entry.content.value = sanitizeHTML(text, allowedHTML)
|
||||
entry.content.value = sanitizeHtml(text, allowedHTML)
|
||||
};
|
||||
return entry;
|
||||
}
|
||||
@@ -82,6 +87,7 @@ export default function(eleventyConfig) {
|
||||
return mentions.filter(entry => !!entry['mentionType'])
|
||||
});
|
||||
|
||||
|
||||
// Return the smallest number argument
|
||||
eleventyConfig.addFilter("min", (...numbers) => {
|
||||
return Math.min.apply(null, numbers);
|
||||
@@ -97,3 +103,4 @@ export default function(eleventyConfig) {
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1,95 +1,91 @@
|
||||
import "dotenv/config.js";
|
||||
import Fetch from "@11ty/eleventy-fetch";
|
||||
import 'dotenv/config';
|
||||
import fs from "fs";
|
||||
import fetch from "node-fetch";
|
||||
import unionBy from "lodash-es/unionBy.js";
|
||||
import domain from "./metadata.js";
|
||||
|
||||
|
||||
// Configuration Parameters
|
||||
const CACHE_DIR = '_cache';
|
||||
const API_ORIGIN = 'https://webmention.io/api/mentions.jf2';
|
||||
const TOKEN = process.env.WEBMENTION_IO_TOKEN;
|
||||
|
||||
async function fetchWebmentions(since, perPage = 10000) {
|
||||
// If we don't have a domain name or token, abort
|
||||
if (!domain || !TOKEN) {
|
||||
if (!domain || !TOKEN) {
|
||||
console.warn('>>> unable to fetch webmentions: missing domain or token');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
let url = `${API_ORIGIN}?token=${TOKEN}&per-page=${perPage}`;
|
||||
if (since) url += `&since=${since}`; // only fetch new mentions
|
||||
const response = await fetch(url);
|
||||
if (response.ok) {
|
||||
let feed = await response.json();
|
||||
console.log(`>>> ${feed.children.length} new webmentions fetched from ${API_ORIGIN}`);
|
||||
return feed;
|
||||
}
|
||||
|
||||
let url = `${API_ORIGIN}?domain=${domain}&token=${TOKEN}&per-page=${perPage}`;
|
||||
if (since) url += `&since=${since}`; // only fetch new mentions
|
||||
|
||||
const response = await fetch(url);
|
||||
if (response.ok) {
|
||||
const feed = await response.json();
|
||||
console.log(`>>> ${feed.children.length} new webmentions fetched from ${API_ORIGIN}`);
|
||||
return feed;
|
||||
}
|
||||
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Merge fresh webmentions with cached entries, unique per id
|
||||
function mergeWebmentions(a, b) {
|
||||
return unionBy(a.children, b.children, 'wm-id');
|
||||
return unionBy(a.children, b.children, 'wm-id');
|
||||
}
|
||||
|
||||
// save combined webmentions in cache file
|
||||
function writeToCache(data) {
|
||||
const filePath = `${CACHE_DIR}/webmentions.json`;
|
||||
const fileContent = JSON.stringify(data, null, 2);
|
||||
const filePath = `${CACHE_DIR}/webmentions.json`;
|
||||
const fileContent = JSON.stringify(data, null, 2);
|
||||
|
||||
// create cache folder if it doesnt exist already
|
||||
if (!fs.existsSync(CACHE_DIR)) {
|
||||
// create cache folder if it doesnt exist already
|
||||
if (!fs.existsSync(CACHE_DIR)) {
|
||||
fs.mkdirSync(CACHE_DIR);
|
||||
}
|
||||
// write data to cache json file
|
||||
fs.writeFile(filePath, fileContent, err => {
|
||||
}
|
||||
// write data to cache json file
|
||||
fs.writeFile(filePath, fileContent, err => {
|
||||
if (err) throw err;
|
||||
console.log(`>>> webmentions cached to ${filePath}`);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// get cache contents from json file
|
||||
function readFromCache() {
|
||||
const filePath = `${CACHE_DIR}/webmentions.json`;
|
||||
const filePath = `${CACHE_DIR}/webmentions.json`;
|
||||
|
||||
if (fs.existsSync(filePath)) {
|
||||
if (fs.existsSync(filePath)) {
|
||||
const cacheFile = fs.readFileSync(filePath);
|
||||
return JSON.parse(cacheFile);
|
||||
};
|
||||
// no cache found
|
||||
return {
|
||||
};
|
||||
// no cache found
|
||||
return {
|
||||
lastFetched: null,
|
||||
children: []
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export default async function() {
|
||||
console.log('>>> Reading webmentions from cache...');
|
||||
console.log('>>> Reading webmentions from cache...');
|
||||
|
||||
const cache = readFromCache();
|
||||
const cache = readFromCache();
|
||||
|
||||
if (cache.children.length) {
|
||||
console.log(`>>> ${cache.children.length} webmentions loaded from cache`);
|
||||
};
|
||||
if (cache.children.length) {
|
||||
console.log(`>>> ${cache.children.length} webmentions loaded from cache`);
|
||||
};
|
||||
|
||||
// Only fetch new mentions in production
|
||||
if (process.env.ELEVENTY_ENV === 'production') {
|
||||
console.log('>>> Checking for new webmentions...');
|
||||
// Only fetch new mentions in production
|
||||
if (process.env.ELEVENTY_ENV === 'production') {
|
||||
console.log('>>> Checking for new webmentions...');
|
||||
const feed = await fetchWebmentions(cache.lastFetched);
|
||||
|
||||
if (feed) {
|
||||
const webmentions = {
|
||||
const webmentions = {
|
||||
lastFetched: new Date().toISOString(),
|
||||
children: mergeWebmentions(cache, feed)
|
||||
}
|
||||
}
|
||||
|
||||
writeToCache(webmentions);
|
||||
return webmentions;
|
||||
writeToCache(webmentions);
|
||||
return webmentions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cache;
|
||||
return cache;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,10 @@
|
||||
{#- Add an arbitrary string to the bundle #}
|
||||
{%- css %}/* This is an arbitrary CSS string added to the bundle */{% endcss %}
|
||||
{#- Add the contents of a file to the bundle #}
|
||||
{%- css %}{% include "public/css/index.css" %}{% endcss %}
|
||||
{% css %}{% include "public/css/index.css" %}{% endcss %}
|
||||
{% css %}{% include "public/css/webmentions.css" %}{% endcss %}
|
||||
{% css %}{% include "public/css/message-box.css" %}{% endcss %}
|
||||
{% css %}{% include "public/css/prism-diff.css" %}{% endcss %}
|
||||
{#- Or you can add from node_modules #}
|
||||
{# {%- css %}{% include "node_modules/prismjs/themes/prism-okaidia.css" %}{% endcss %} #}
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@ layout: layouts/base.njk
|
||||
|
||||
<hyvor-talk-comments website-id="9100" page-id="{{ permalink }}"></hyvor-talk-comments>
|
||||
|
||||
{% include 'webmentionlist.njk' %}
|
||||
{% include 'webmentions.njk' %}
|
||||
|
||||
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
|
||||
@@ -5,37 +5,36 @@
|
||||
<h4>{{ likes.length }} Like{% if likes.length != 1 %}s{% endif %}</h4>
|
||||
<div class="webmentions__facepile">
|
||||
{% for webmention in likes %}
|
||||
|
||||
|
||||
{% if webmention.url != "" %}
|
||||
<a class="h-card u-url link-u-exempt" href="{{ webmention.url }}" target="_blank" rel="noopener noreferrer">
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if webmention.author.photo %}
|
||||
<img src="{{ webmention.author.photo }}" alt="{{ webmention.author.name }}" title="{{ webmention.author.name }}" alt="" class="webmentions__face" loading="lazy" />
|
||||
<img eleventy:ignore class="webmention__author__photo" src="{{ webmention.author.photo }}" alt="{{ webmention.author.name }}" title="{{ webmention.author.name }}" class="webmentions__face" loading="lazy" />
|
||||
{% else %}
|
||||
<img class="webmention__author__photo" src="{{ '/img/default_avatar.png' | url }}" alt="{{ webmention.author.name }}" title="{{ webmention.author.name }}" alt="" class="webmentions__face" />
|
||||
<img eleventy:ignore class="webmention__author__photo" src="{{ '/img/default_avatar.png' | url }}" alt="{{ webmention.author.name }}" title="{{ webmention.author.name }}" class="webmentions__face" />
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if webmention.url != "" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if reposts.length > 0 %}
|
||||
|
||||
{% if reposts.length > 0 %}
|
||||
<h4>{{ reposts.length }} Repost{% if reposts.length != 1 %}s{% endif %}</h4>
|
||||
<div class="webmentions__facepile">
|
||||
{% for webmention in reposts %}
|
||||
{% if webmention.url != "" %}
|
||||
<a class="h-card u-url link-u-exempt" href="{{ webmention.url }}" target="_blank" rel="noopener noreferrer">
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if webmention.author.photo %}
|
||||
<img src="{{ webmention.author.photo }}" alt="{{ webmention.author.name }}" title="{{ webmention.author.name }}" alt="" class="webmentions__face" loading="lazy" />
|
||||
<img eleventy:ignore class="webmention__author__photo" src="{{ webmention.author.photo }}" alt="{{ webmention.author.name }}" title="{{ webmention.author.name }}" class="webmentions__face" loading="lazy" />
|
||||
{% else %}
|
||||
<img class="webmention__author__photo" src="{{ '/img/default_avatar.png' | url }}" alt="{{ webmention.author.name }}" title="{{ webmention.author.name }}" alt="" class="webmentions__face" />
|
||||
<img eleventy:ignore class="webmention__author__photo" src="{{ '/img/default_avatar.png' | url }}" alt="{{ webmention.author.name }}" title="{{ webmention.author.name }}" class="webmentions__face" />
|
||||
{% endif %}
|
||||
{% if webmention.url != "" %}
|
||||
</a>
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
{% if webmention.author %}
|
||||
<a class="webmention__author p-author h-card u-url" href="{{ webmention.url }}" target="_blank" rel="noopener noreferrer">
|
||||
{% if webmention.author.photo %}
|
||||
<img class="webmention__author__photo u-photo" src="{{ webmention.author.photo }}" alt="{{ webmention.author.name }}">
|
||||
<img eleventy:ignore class="webmention__author__photo u-photo" src="{{ webmention.author.photo }}" alt="{{ webmention.author.name }}">
|
||||
{% else %}
|
||||
<img class="webmention__author__photo" src="{{ '/img/webmention-avatar-default.svg' | url }}" alt="">
|
||||
<img eleventy:ignore class="webmention__author__photo" src="{{ '/blog/img/default_avatar.png' | url }}" alt="">
|
||||
{% endif %}
|
||||
<strong class="p-name">{{ webmention.author.name }}</strong>
|
||||
</a>
|
||||
{% else %}
|
||||
<span class="webmention__author">
|
||||
<img class="webmention__author__photo" src="{{ '/img/webmention-avatar-default.svg' | url }}" alt="">
|
||||
<img class="webmention__author__photo" src="{{ '/blog/img/default_avatar.png' | url }}" alt="">
|
||||
<strong>Anonymous</strong>
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if webmention.published %}
|
||||
<time class="webmention__pubdate dt-published" datetime="{{ webmention.published }}">{{ webmention.published | dateFromTimestamp | readableDate("dd LLL yyyy - HH:mm") }}</time>
|
||||
{% endif %}
|
||||
@@ -23,4 +23,4 @@
|
||||
<div class="webmention__content p-content">
|
||||
{{ webmention.content.text | safe }}
|
||||
</div>
|
||||
</article>
|
||||
</article>
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
{%- set absoluteUrl -%}{{ page.url | url | absoluteUrl(metadata.url) }}{%- endset -%}
|
||||
{%- set mentions = webmentions.children | mentionsForUrl(absoluteUrl) -%}
|
||||
<div class="webmentions" id="webmentions">
|
||||
<h3>Webmentions</h3>
|
||||
<h3>Webmentions</h3>
|
||||
|
||||
{% if mentions | length %}
|
||||
<h4>{{ mentions.length }} {% if mentions.length == "1" %}Reply{% else %}Replies{% endif %}</h4>
|
||||
{% if mentions | length %}
|
||||
<h4>{{ mentions.length }} {% if mentions.length == "1" %}Reply{% else %}Replies{% endif %}</h4>
|
||||
<ol class="webmentions__list">
|
||||
{% for webmention in mentions | reverse %}
|
||||
{% for webmention in mentions | reverse %}
|
||||
<li class="webmentions__item">
|
||||
{% include 'webmention.njk' %}
|
||||
{% include 'webmention.njk' %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</ol>
|
||||
|
||||
{% else %}
|
||||
{% else %}
|
||||
<p>No replies yet.</p>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% include 'likes.njk' %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -92,9 +92,9 @@ export default async function(eleventyConfig) {
|
||||
extensions: "html",
|
||||
|
||||
// Output formats for each image.
|
||||
formats: ["jpeg", "png"],
|
||||
formats: ["jpeg", "png", "webp"],
|
||||
|
||||
widths: ["600"],
|
||||
widths: ["auto", 400, 600],
|
||||
|
||||
urlPath: "/img/",
|
||||
|
||||
@@ -102,6 +102,7 @@ export default async function(eleventyConfig) {
|
||||
// e.g. <img loading decoding> assigned on the HTML tag will override these values.
|
||||
loading: "lazy",
|
||||
decoding: "async",
|
||||
sizes: "100vw",
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"description": "A starter repository for a blog web site using the Eleventy site generator.",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "npx @11ty/eleventy --incremental",
|
||||
"build": "npx @11ty/eleventy --incremental --quiet",
|
||||
"build-full": "npx @11ty/eleventy",
|
||||
"build-nocolor": "cross-env NODE_DISABLE_COLORS=1 npx @11ty/eleventy",
|
||||
"build-ghpages": "npx @11ty/eleventy --pathprefix=/eleventy-base-blog/",
|
||||
@@ -51,6 +51,7 @@
|
||||
"@fontsource/atkinson-hyperlegible": "^5.0.3",
|
||||
"@zachleat/heading-anchors": "^1.0.1",
|
||||
"dotenv": "^16.3.1",
|
||||
"lodash-es": "^4.17.21"
|
||||
"lodash-es": "^4.17.21",
|
||||
"sanitize-html": "^2.13.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,4 +50,4 @@
|
||||
}
|
||||
.webmention__pubdate {
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user