Adding webmentions to blog

This commit is contained in:
Dan 2026-01-15 18:30:49 +00:00
parent d29d1fbb1b
commit b34b16d8e0
2 changed files with 103 additions and 9 deletions

View file

@ -94,17 +94,99 @@ class WebmentionUtils {
} }
/** /**
* Auto-initialize elements with data-webmention-list attribute * Auto-initialize all webmention elements
*/ */
autoInit() { async autoInit() {
const elements = document.querySelectorAll("[data-webmention-list]"); // Group elements by target URL to avoid duplicate API calls
const targetGroups = new Map();
elements.forEach(async (element) => { const selectors = [
const targetUrl = "[data-webmention-list]",
element.dataset.webmentionList || window.location.href; "[data-webmention-show]",
const mentions = await this.fetch(targetUrl); "[data-webmention-hide]",
element.innerHTML = this.asCommaSeparatedList(mentions); "[data-webmention-text]",
];
selectors.forEach((selector) => {
document.querySelectorAll(selector).forEach((element) => {
const targetUrl = this.getTargetUrl(element) || window.location.href;
if (!targetGroups.has(targetUrl)) {
targetGroups.set(targetUrl, []);
}
targetGroups.get(targetUrl).push(element);
});
}); });
// Fetch and process each target URL
for (const [targetUrl, elements] of targetGroups) {
const mentions = await this.fetch(targetUrl);
const hasMentions = mentions.length > 0;
elements.forEach((element) => {
this.processElement(element, mentions, hasMentions);
});
}
}
/**
* Get the target URL from an element's data attributes or parent container
*/
getTargetUrl(element) {
// First check the element's own attributes for a non-empty value
const ownUrl =
element.dataset.webmentionList ||
element.dataset.webmentionShow ||
element.dataset.webmentionHide ||
element.dataset.webmentionText ||
"";
if (ownUrl) {
return ownUrl;
}
// Check for parent container with data-webmention-target
const container = element.closest("[data-webmention-target]");
if (container) {
return container.dataset.webmentionTarget;
}
return "";
}
/**
* Process a single element based on its data attributes
*/
processElement(element, mentions, hasMentions) {
// Handle data-webmention-list
if (element.hasAttribute("data-webmention-list")) {
element.innerHTML = this.asCommaSeparatedList(mentions);
}
// Handle data-webmention-show (visible only if mentions exist)
if (element.hasAttribute("data-webmention-show")) {
element.style.display = hasMentions ? "" : "none";
}
// Handle data-webmention-hide (hidden if mentions exist)
if (element.hasAttribute("data-webmention-hide")) {
element.style.display = hasMentions ? "none" : "";
}
// Handle data-webmention-text (different text based on count)
if (element.hasAttribute("data-webmention-text")) {
const textConfig = element.dataset.webmentionText;
// Format: "none text|single text|plural text" or just check for pipe
if (textConfig.includes("|")) {
const parts = textConfig.split("|");
if (mentions.length === 0) {
element.textContent = parts[0] || "";
} else if (mentions.length === 1) {
element.textContent = parts[1] || parts[0] || "";
} else {
element.textContent = parts[2] || parts[1] || parts[0] || "";
}
}
}
} }
} }

View file

@ -22,7 +22,19 @@
{{ end }} {{ end }}
<div class="blog-summary">{{ .Content }}</div> <div class="blog-summary">{{ .Content }}</div>
<div class="blog-footer"> <div class="blog-footer">
🛜 <a href="/blog/feed.xml">Available via RSS</a> 🛜 <a href="/blog/feed.xml">Available via RSS</a> <br /><br />
You can respond to this post via
<a
href="https://indieweb.org/Webmention"
target="_blank"
rel="noopener noreferrer"
>webmentions</a
>. <br /><br />
<div data-webmention-target>
<span data-webmention-show>
Mentioned by: <span data-webmention-list></span
></span>
</div>
</div> </div>
</article> </article>