Skip to content

Commit 19a15ab

Browse files
committed
add boost & like count to blog
1 parent e289db0 commit 19a15ab

File tree

11 files changed

+529
-21
lines changed

11 files changed

+529
-21
lines changed

.eleventy.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ module.exports = (eleventyConfig) => {
2121
eleventyConfig.addFilter("date_to_rfc3339", rss.dateToRfc3339)
2222
eleventyConfig.addFilter("date_to_rfc822", rss.dateToRfc822)
2323
eleventyConfig.addFilter("html_to_absolute_urls", rss.convertHtmlToAbsoluteUrls)
24+
eleventyConfig.addFilter("domain", (str) => new URL(str).hostname)
2425

2526
eleventyConfig.setLibrary(
2627
"md",
@@ -40,12 +41,12 @@ module.exports = (eleventyConfig) => {
4041
eleventyConfig.addGlobalData("discord", "https://discord.gg/CqhDNXepDV")
4142
eleventyConfig.addGlobalData("baseurl", "https://webcomponents.guide")
4243
eleventyConfig.addGlobalData("repository", "https://github.com/WebComponentsGuide/webcomponents.guide")
44+
eleventyConfig.addGlobalData("mastodon", "https://fosstodon.org/@webcomponentsguide")
4345

4446
const customGroups = require("./_data/groups.json")
4547

4648
for (const [type, groups] of Object.entries(customGroups)) {
4749
for (const group of groups) {
48-
console.log(`adding ${type} ${group}`)
4950
eleventyConfig.addCollection(group, (api) => {
5051
return api
5152
.getFilteredByGlob(`${type}/**/*.md`)
@@ -61,7 +62,8 @@ module.exports = (eleventyConfig) => {
6162

6263
const icon = (icon) =>
6364
`<svg width="24" height="24" class="icon icon-${icon}"><use xlink:href="/images/icons.svg#${icon}"></use></svg>`
64-
const callout = (content, style = "info") => dedent`
65+
const callout = (content, style = "info") =>
66+
dedent`
6567
<div class="callout ${style}">
6668
${content}
6769
${icon(style)}
@@ -82,12 +84,12 @@ module.exports = (eleventyConfig) => {
8284
menu: icon("menu"),
8385
}
8486
const menu = (first, ...rest) => [menumap[first] || `<strong>${first}</strong>`, ...rest].join(icon("chevron-right"))
85-
const picture = (name) => `
86-
<picture>
87-
<source srcset="/images/${name}.avif" type="image/avif">
88-
<source srcset="/images/${name}.webp" type="image/webp">
89-
<img src="/images/${name}.jpg">
90-
</picture>
87+
const picture = (name) =>
88+
`<picture>
89+
<source srcset="/images/${name}.avif" type="image/avif">
90+
<source srcset="/images/${name}.webp" type="image/webp">
91+
<img src="/images/${name}.jpg">
92+
</picture>
9193
`
9294

9395
eleventyConfig.addShortcode("icon", icon)
@@ -140,7 +142,6 @@ module.exports = (eleventyConfig) => {
140142
${html}
141143
</div>
142144
`
143-
console.log(out)
144145
return out
145146
})
146147
}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ node_modules
22
_site
33
guide/.obsidian
44
*.kra
5+
.cache

_includes/blog-index.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
layout: main.html
3+
css: [content.css, blog.css]
4+
script: [relative-time.js]
5+
---
6+
7+
<h1>{{ title }}</h1>
8+
9+
<section class="content">{{ content }}</section>

_includes/blog.html

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,11 @@
44
script: [relative-time.js]
55
---
66

7-
{% if title == "Blog" %}
8-
<h1>{{ title }}</h1>
9-
{%- else %}
107
<header>
118
<h1>{{ title }}</h1>
129
{{ imageslug | picture }}
1310
<aside class="excerpt">{{ excerpt }}</aside>
14-
<div class="author-block">
11+
<aside class="author-block">
1512
{%- for author in authors %}
1613
<a href="/blog/by-author/{{ author | slugify }}" class="avatar">
1714
<img
@@ -27,8 +24,32 @@ <h1>{{ title }}</h1>
2724
<a href="/blog/by-author/{{ author | slugify }}"> {{ author }}{% unless forloop.last %}, {% endunless %} </a>
2825
{%- endfor %}<br />
2926
<relative-time format="datetime" datetime="{{ page.date | iso8601 }}"> {{ page.date | iso8601 }} </relative-time>
30-
</div>
27+
</aside>
28+
<aside class="mentions">
29+
<a href="{{ announcePost }}" class="reposts" aria-label="{{ reposts | size }} Boosts">
30+
{% icon "repeat" %}{{ reposts | size }}
31+
</a>
32+
<a href="{{ announcePost }}" class="likes" aria-label="{{ likes | size }} Likes">
33+
{% icon "heart" %}{{ likes | size }}
34+
</a>
35+
</aside>
3136
</header>
32-
{%- endif %}
3337

3438
<section class="content">{{ content }}</section>
39+
40+
<section class="mentions">
41+
<div class="reposts">
42+
<span class="type"> {% icon "repeat" %} {{ reposts | size }} reposts: {% for repost in reposts %} </span>
43+
<a href="{{ repost.author.url }}" class="avatar">
44+
<img src="{{ repost.author.photo }}" loading="lazy" decoding="async " width="50" height="50" />
45+
</a>
46+
{% endfor %}
47+
</div>
48+
<div class="likes">
49+
<span class="type"> {% icon "heart" %} {{ likes | size }} likes: {% for like in likes %} </span>
50+
<a href="{{ like.author.url }}" class="avatar">
51+
<img src="{{ like.author.photo }}" loading="lazy" decoding="async " width="50" height="50" />
52+
</a>
53+
{% endfor %}
54+
</div>
55+
</section>

blog/blog.11tydata.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
const { AssetCache } = require("@11ty/eleventy-fetch")
2+
module.exports = {
3+
layout: "blog.html",
4+
permalink: "/blog/{{ page.fileSlug }}/",
5+
tags: ["blog"],
6+
eleventyComputed: {
7+
async mentions(data) {
8+
const fetch = (await import("node-fetch")).default
9+
const url = `${data.baseurl}/blog/${data.page.fileSlug}/`
10+
const apiUrl = `https://webmention.io/api/mentions.jf2?target=${url}&per-page=1000`
11+
console.log("Fetching web mentions", apiUrl)
12+
let asset = new AssetCache(apiUrl)
13+
if (asset.isCacheValid("1h")) {
14+
console.log("Returning now data from cache")
15+
return await asset.getCachedValue()
16+
}
17+
const res = await fetch(apiUrl)
18+
const json = await res.json()
19+
const { children } = json
20+
await asset.save(children, "json")
21+
return children
22+
},
23+
async likes(data) {
24+
const mentions = (await data.mentions) || []
25+
return mentions.filter((mention) => mention["wm-property"] === "like-of")
26+
},
27+
async reposts(data) {
28+
const mentions = (await data.mentions) || []
29+
return mentions.filter((mention) => mention["wm-property"] === "repost-of")
30+
},
31+
async replies(data) {
32+
const mentions = (await data.mentions) || []
33+
return mentions.filter((mention) => mention["wm-property"] === "in-reply-to")
34+
},
35+
async announcePost(data) {
36+
const mentions = (await data.mentions) || []
37+
for (const mention of mentions) {
38+
if (mention.url.startsWith(data.mastodon)) {
39+
const url = new URL(mention.url)
40+
url.hash = ""
41+
return url.toString()
42+
}
43+
}
44+
return ""
45+
},
46+
},
47+
}

blog/blog.json

Lines changed: 0 additions & 5 deletions
This file was deleted.

blog/index.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
permalink: /blog/
3+
layout: blog-index.html
34
override:tags:
45
title: Blog
56
---
@@ -30,6 +31,14 @@ title: Blog
3031
{{ post.date | iso8601 }}
3132
</relative-time>
3233
</div>
34+
<aside class="mentions">
35+
<a href="{{ post.data.announcePost }}" class="reposts" aria-label="{{ post.data.reposts | size }} Boosts">
36+
{% icon "repeat" %}{{ post.data.reposts | size }}
37+
</a>
38+
<a href="{{ post.data.announcePost }}" class="likes" aria-label="{{ post.data.likes | size }} Likes">
39+
{% icon "heart" %}{{ post.data.likes | size }}
40+
</a>
41+
</aside>
3342
</li>
3443
{% endunless %}{% endfor %}
3544
</ol>

css/blog.css

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,92 @@
2929
}
3030
}
3131

32+
.mentions {
33+
border-block-start: var(--border-size-2) solid var(--brand-color-dark);
34+
max-width: 100ch;
35+
36+
& :where(.reposts, .likes, .replies) {
37+
display: flex;
38+
align-items: center;
39+
margin: var(--size-4) 0;
40+
41+
& .type {
42+
display: inline-block;
43+
inline-size: 130px;
44+
}
45+
46+
& svg {
47+
margin-inline-end: var(--size-2);
48+
}
49+
50+
& a {
51+
display: inline-block;
52+
margin-inline-start: calc(var(--size-4) * -1);
53+
54+
&:first-of-type {
55+
margin-inline-start: var(--size-1);
56+
}
57+
}
58+
59+
& .avatar img {
60+
border-radius: var(--radius-round);
61+
border: var(--border-size-1) solid var(--surface-2);
62+
background: var(--surface-1);
63+
box-shadow: var(--shadow-3);
64+
}
65+
}
66+
67+
& .reposts {
68+
color: var(--blue-6);
69+
}
70+
71+
& .likes {
72+
color: var(--red-6);
73+
}
74+
75+
& .replies {
76+
align-items: start;
77+
flex-direction: column;
78+
79+
& .reply {
80+
margin-block: var(--size-3);
81+
display: grid;
82+
gap: var(--size-2);
83+
align-items: center;
84+
grid-template:
85+
"icon avatar name aside" auto
86+
"post post post post" auto
87+
/ auto 50px auto 1fr;
88+
89+
& a {
90+
margin: 0;
91+
padding: 0;
92+
}
93+
94+
& svg {
95+
grid-area: icon;
96+
}
97+
98+
& .avatar {
99+
grid-area: avatar;
100+
padding-inline-start: var(--size-1);
101+
}
102+
103+
& .name {
104+
grid-area: name;
105+
}
106+
107+
& section {
108+
grid-area: post;
109+
}
110+
111+
& aside {
112+
grid-area: aside;
113+
}
114+
}
115+
}
116+
}
117+
32118
main {
33119
padding: var(--size-8);
34120

@@ -51,7 +137,7 @@ main {
51137
"title title" auto
52138
"picture picture" auto
53139
"excerpt excerpt" auto
54-
"author author" auto
140+
"author mentions" auto
55141
/ 1fr 1fr;
56142

57143
& > h1 {
@@ -71,6 +157,18 @@ main {
71157
grid-area: author;
72158
margin: 0;
73159
}
160+
161+
& > .mentions {
162+
border: 0;
163+
padding: 0;
164+
grid-area: mentions;
165+
display: flex;
166+
justify-content: flex-end;
167+
168+
& :where(.reposts, .likes) {
169+
margin: 0 var(--size-2);
170+
}
171+
}
74172
}
75173
}
76174

@@ -109,6 +207,13 @@ main {
109207
margin: 0;
110208
}
111209

210+
& .mentions {
211+
grid-area: mentions;
212+
display: flex;
213+
justify-content: flex-end;
214+
padding: 0;
215+
border: 0;
216+
}
112217
}
113218

114219
@media (--lg-n-above) {

images/icons.svg

Lines changed: 12 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)