Add tag listings
This commit is contained in:
parent
eb62bfd1c9
commit
53707bb085
110
src/_data/_postData.js
Normal file
110
src/_data/_postData.js
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const merge = require('lodash/merge')
|
||||||
|
|
||||||
|
const wordpressPassword = process.env.WORDPRESS_PASSWORD;
|
||||||
|
const auth = Buffer.from(`lewis:${wordpressPassword}`).toString('base64');
|
||||||
|
|
||||||
|
class PostCache {
|
||||||
|
constructor() {
|
||||||
|
this.readCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
readCache() {
|
||||||
|
if (!fs.existsSync(".cache")) {
|
||||||
|
fs.mkdirSync(".cache");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fs.existsSync(".cache/wordpress_post_fetch.json")) {
|
||||||
|
this.last_read_date = null;
|
||||||
|
this.posts = {};
|
||||||
|
} else {
|
||||||
|
const data = JSON.parse(fs.readFileSync(".cache/wordpress_post_fetch.json"));
|
||||||
|
this.last_read_date = new Date(data.last_read_date);
|
||||||
|
this.posts = data.posts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeCache() {
|
||||||
|
fs.writeFileSync(".cache/wordpress_post_fetch.json", JSON.stringify(this, null, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchCommentsByType(type = "comment") {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
params.set("per_page", 100);
|
||||||
|
params.set("type", type);
|
||||||
|
|
||||||
|
if (this.last_read_date) {
|
||||||
|
params.set("modified_after", this.last_read_date.toISOString());
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(`https://cms.lewisdale.dev/wp-json/wp/v2/comments?${params.toString()}`, {
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Basic ${auth}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return await response.json()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchComments() {
|
||||||
|
const likes = await this.fetchCommentsByType("like");
|
||||||
|
const mentions = await this.fetchCommentsByType();
|
||||||
|
const reposts = await this.fetchCommentsByType("repost");
|
||||||
|
|
||||||
|
const comments = [...likes, ...mentions, ...reposts];
|
||||||
|
|
||||||
|
comments.forEach(comment => {
|
||||||
|
if (this.posts[comment.post]) {
|
||||||
|
this.posts[comment.post].comments[comment.id] = comment;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchPosts() {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
params.set("per_page", 100);
|
||||||
|
|
||||||
|
if (this.last_read_date) {
|
||||||
|
params.set("modified_after", this.last_read_date.toISOString());
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(`https://cms.lewisdale.dev/wp-json/wp/v2/posts?${params.toString()}`, {
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Basic ${auth}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const posts = await response.json();
|
||||||
|
|
||||||
|
posts.forEach(post => {
|
||||||
|
this.posts[post.id] = merge({ comments: {} }, this.posts[post.id], post);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchLatest() {
|
||||||
|
await this.fetchPosts();
|
||||||
|
await this.fetchComments();
|
||||||
|
await this.fetchTags();
|
||||||
|
|
||||||
|
this.last_read_date = new Date();
|
||||||
|
this.writeCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchTags() {
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
params.set("per_page", 100);
|
||||||
|
|
||||||
|
const response = await fetch(`https://cms.lewisdale.dev/wp-json/wp/v2/tags?${params.toString()}`, {
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Basic ${auth}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const tags = await response.json();
|
||||||
|
this.tags = tags.reduce((tagMap, tag) => ({...tagMap, [tag.id]: tag }), {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cache = new PostCache();
|
||||||
|
|
||||||
|
module.exports = async function() {
|
||||||
|
await cache.fetchLatest();
|
||||||
|
return cache;
|
||||||
|
}
|
@ -1,96 +1,7 @@
|
|||||||
const EleventyFetch = require('@11ty/eleventy-fetch');
|
const postCache = require('./_postData');
|
||||||
const fs = require('fs');
|
|
||||||
const merge = require('lodash/merge')
|
|
||||||
|
|
||||||
const wordpressPassword = process.env.WORDPRESS_PASSWORD;
|
|
||||||
const auth = Buffer.from(`lewis:${wordpressPassword}`).toString('base64');
|
|
||||||
|
|
||||||
const dateSort = (a, b) => new Date(b.date) - new Date(a.date);
|
const dateSort = (a, b) => new Date(b.date) - new Date(a.date);
|
||||||
|
|
||||||
class PostCache {
|
|
||||||
constructor() {
|
|
||||||
this.readCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
readCache() {
|
|
||||||
if (!fs.existsSync(".cache")) {
|
|
||||||
fs.mkdirSync(".cache");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fs.existsSync(".cache/wordpress_post_fetch.json")) {
|
|
||||||
this.last_read_date = null;
|
|
||||||
this.posts = {};
|
|
||||||
} else {
|
|
||||||
const data = JSON.parse(fs.readFileSync(".cache/wordpress_post_fetch.json"));
|
|
||||||
this.last_read_date = new Date(data.last_read_date);
|
|
||||||
this.posts = data.posts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
writeCache() {
|
|
||||||
fs.writeFileSync(".cache/wordpress_post_fetch.json", JSON.stringify(this, null, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetchCommentsByType(type = "comment") {
|
|
||||||
const params = new URLSearchParams();
|
|
||||||
params.set("per_page", 100);
|
|
||||||
params.set("type", type);
|
|
||||||
|
|
||||||
if (this.last_read_date) {
|
|
||||||
params.set("modified_after", this.last_read_date.toISOString());
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await fetch(`https://cms.lewisdale.dev/wp-json/wp/v2/comments?${params.toString()}`, {
|
|
||||||
headers: {
|
|
||||||
"Authorization": `Basic ${auth}`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return await response.json()
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetchComments() {
|
|
||||||
const likes = await this.fetchCommentsByType("like");
|
|
||||||
const mentions = await this.fetchCommentsByType();
|
|
||||||
const reposts = await this.fetchCommentsByType("repost");
|
|
||||||
|
|
||||||
const comments = [...likes, ...mentions, ...reposts];
|
|
||||||
|
|
||||||
comments.forEach(comment => {
|
|
||||||
if (this.posts[comment.post]) {
|
|
||||||
this.posts[comment.post].comments[comment.id] = comment;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetchPosts() {
|
|
||||||
const params = new URLSearchParams();
|
|
||||||
params.set("per_page", 100);
|
|
||||||
|
|
||||||
if (this.last_read_date) {
|
|
||||||
params.set("modified_after", this.last_read_date.toISOString());
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await fetch(`https://cms.lewisdale.dev/wp-json/wp/v2/posts?${params.toString()}`, {
|
|
||||||
headers: {
|
|
||||||
"Authorization": `Basic ${auth}`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const posts = await response.json();
|
|
||||||
|
|
||||||
posts.forEach(post => {
|
|
||||||
this.posts[post.id] = merge({ comments: {} }, this.posts[post.id], post);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetchLatest() {
|
|
||||||
await this.fetchPosts();
|
|
||||||
await this.fetchComments();
|
|
||||||
|
|
||||||
this.last_read_date = new Date();
|
|
||||||
this.writeCache();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const mapComment = comment => ({
|
const mapComment = comment => ({
|
||||||
author: {
|
author: {
|
||||||
name: comment.author_name,
|
name: comment.author_name,
|
||||||
@ -104,8 +15,7 @@ const mapComment = comment => ({
|
|||||||
|
|
||||||
|
|
||||||
module.exports = async () => {
|
module.exports = async () => {
|
||||||
const cache = new PostCache();
|
const cache = await postCache();
|
||||||
await cache.fetchLatest();
|
|
||||||
|
|
||||||
const posts = Object.values(cache.posts)
|
const posts = Object.values(cache.posts)
|
||||||
.sort(dateSort)
|
.sort(dateSort)
|
||||||
@ -120,7 +30,12 @@ module.exports = async () => {
|
|||||||
|
|
||||||
comments[comment.type].push(mapComment(comment));
|
comments[comment.type].push(mapComment(comment));
|
||||||
return comments;
|
return comments;
|
||||||
}, { like: [], reply: [], repost: [] })
|
}, { like: [], reply: [], repost: [] }),
|
||||||
|
tags: post.tags.map(tag => ({
|
||||||
|
name: cache.tags[tag].name,
|
||||||
|
slug: cache.tags[tag].slug,
|
||||||
|
link: cache.tags[tag].link
|
||||||
|
}))
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return posts;
|
return posts;
|
||||||
|
15
src/_data/tags.js
Normal file
15
src/_data/tags.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
const postCache = require('./_postData');
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = async () => {
|
||||||
|
const cache = await postCache();
|
||||||
|
|
||||||
|
return Object.values(cache.tags).map(tag => {
|
||||||
|
const posts = Object.values(cache.posts).filter(post => post.tags.includes(tag.id));
|
||||||
|
|
||||||
|
return {
|
||||||
|
...tag,
|
||||||
|
posts,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
@ -12,6 +12,14 @@ eleventyComputed:
|
|||||||
<div class="e-content stack-md">
|
<div class="e-content stack-md">
|
||||||
{{ content | safe }}
|
{{ content | safe }}
|
||||||
</div>
|
</div>
|
||||||
|
{% if post.tags | length %}
|
||||||
|
<ul role="list">
|
||||||
|
<h2>Tags:</h2>
|
||||||
|
{% for tag in post.tags %}
|
||||||
|
<li><a href="/post/tag/{{ tag.slug }}" rel="tag">#{{ tag.name }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<section class="stack-sm">
|
<section class="stack-sm">
|
||||||
|
25
src/blog/tag.html
Normal file
25
src/blog/tag.html
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
title: Blog
|
||||||
|
layout: base.njk
|
||||||
|
pagination:
|
||||||
|
data: tags
|
||||||
|
size: 1
|
||||||
|
alias: tag
|
||||||
|
eleventyComputed:
|
||||||
|
permalink: "/post/tag/{{ tag.slug }}/"
|
||||||
|
---
|
||||||
|
|
||||||
|
<main class="wrapper-md stack-lg">
|
||||||
|
<h1>Posts tagged “{{ tag.name }}”</h1>
|
||||||
|
|
||||||
|
<ol class="stack-xl" role='list'>
|
||||||
|
{% for item in tag.posts %}
|
||||||
|
<li class="stack-xs">
|
||||||
|
<h2><a href="/post/{{ item.slug }}">{{ item.title.rendered | safe }}</a></h2>
|
||||||
|
<time class="block">{{ item.date | parseDate | dateDisplay }}</time>
|
||||||
|
{{ item.excerpt.rendered | safe }}
|
||||||
|
<a href="/post/{{ item.slug }}" class="inline-block">Read more</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ol>
|
||||||
|
</main>
|
8
src/css/exceptions/tags.css
Normal file
8
src/css/exceptions/tags.css
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
li:has(a[rel="tag"]) {
|
||||||
|
display: inline-block;
|
||||||
|
margin-inline-end: 1ch;
|
||||||
|
|
||||||
|
&:not(:last-child):after {
|
||||||
|
content: ",";
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user