From 4dfcf1b40813f6883b3fbf9ab95530f1a8b335ac Mon Sep 17 00:00:00 2001 From: Evert Prants Date: Sun, 16 Oct 2022 15:50:21 +0300 Subject: [PATCH] atom feed generator, titles --- assets/styles/components/_blog.scss | 19 +++---- layouts/blog.vue | 7 +++ lib/blog/read-posts.ts | 2 + nuxt.config.ts | 2 +- package-lock.json | 49 +++++++++++++++++++ package.json | 1 + pages/blog/[year]/[month]/[day]/[slug].vue | 1 + .../archive/[year]/[month]/[day]/index.vue | 9 +++- pages/blog/archive/[year]/[month]/index.vue | 7 ++- pages/blog/archive/[year]/index.vue | 6 ++- pages/blog/archive/index.vue | 4 +- pages/blog/tags/[tag].vue | 4 +- server/api/blog/index.ts | 2 +- server/routes/blog/atom.xml.ts | 46 +++++++++++++++++ 14 files changed, 143 insertions(+), 16 deletions(-) create mode 100644 server/routes/blog/atom.xml.ts diff --git a/assets/styles/components/_blog.scss b/assets/styles/components/_blog.scss index 658f22e..0d3f4e4 100644 --- a/assets/styles/components/_blog.scss +++ b/assets/styles/components/_blog.scss @@ -1,7 +1,7 @@ .blog { width: 100%; min-height: 100vh; - background-color: rgb(241, 241, 241); + background-color: #eee; a { color: #258fb8; @@ -131,17 +131,16 @@ ul, ol, dl { - margin: 0 20px; + margin: 1.6em 20px; line-height: 1.6em; padding: 0; - margin-top: 1.6em; - margin-bottom: 1.6em; } } &__inner { overflow: hidden; background-color: #fff; + box-shadow: 1px 2px 3px #ddd; } &__meta { @@ -208,7 +207,7 @@ } a { - color: #258fb8; + color: #006891; } ul { @@ -225,6 +224,7 @@ &-archives { margin: 50px 0; + &__year { margin-bottom: 1em; font-size: 0.85em; @@ -245,6 +245,10 @@ display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; + + @media all and (max-width: 567px) { + grid-template-columns: 1fr; + } } &__time { @@ -259,15 +263,12 @@ &__post { padding: 20px; background-color: #fff; + box-shadow: 1px 2px 3px #ddd; header { display: flex; flex-direction: column; height: 100%; - - h1 { - margin-top: auto; - } } } } diff --git a/layouts/blog.vue b/layouts/blog.vue index 4a1ddcc..4b88d9f 100644 --- a/layouts/blog.vue +++ b/layouts/blog.vue @@ -8,6 +8,13 @@ + + Evert's Blog | lunasqu.ee

Blog

diff --git a/lib/blog/read-posts.ts b/lib/blog/read-posts.ts index c4746c7..1a52b88 100644 --- a/lib/blog/read-posts.ts +++ b/lib/blog/read-posts.ts @@ -107,6 +107,8 @@ export async function getTags(): Promise { } } + obj.sort((a, b) => a.name.localeCompare(b.name, 'en')); + return obj; } diff --git a/nuxt.config.ts b/nuxt.config.ts index 9d7f2b0..e0dee95 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -37,7 +37,7 @@ export default defineNuxtConfig({ hooks: { async 'nitro:config'(config) { const routes = await generatePaths('/blog/'); - config.prerender.routes.push(...routes); + config.prerender.routes.push(...routes, '/blog/atom.xml'); }, }, }); diff --git a/package-lock.json b/package-lock.json index e2f4f28..c75ff3e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,6 +6,7 @@ "": { "hasInstallScript": true, "dependencies": { + "feed": "^4.2.2", "highlight.js": "^11.6.0", "sass": "^1.55.0" }, @@ -3320,6 +3321,17 @@ "reusify": "^1.0.4" } }, + "node_modules/feed": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", + "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", + "dependencies": { + "xml-js": "^1.6.11" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/fetch-blob": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", @@ -6250,6 +6262,11 @@ "node": ">=12.0.0" } }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, "node_modules/scule": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/scule/-/scule-0.3.2.tgz", @@ -7494,6 +7511,17 @@ } } }, + "node_modules/xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "dependencies": { + "sax": "^1.2.4" + }, + "bin": { + "xml-js": "bin/cli.js" + } + }, "node_modules/xxhashjs": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", @@ -10029,6 +10057,14 @@ "reusify": "^1.0.4" } }, + "feed": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", + "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", + "requires": { + "xml-js": "^1.6.11" + } + }, "fetch-blob": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", @@ -12165,6 +12201,11 @@ "source-map-js": ">=0.6.2 <2.0.0" } }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, "scule": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/scule/-/scule-0.3.2.tgz", @@ -13114,6 +13155,14 @@ "dev": true, "requires": {} }, + "xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "requires": { + "sax": "^1.2.4" + } + }, "xxhashjs": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", diff --git a/package.json b/package.json index 75a03b8..3d329c1 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "yaml": "^2.1.3" }, "dependencies": { + "feed": "^4.2.2", "highlight.js": "^11.6.0", "sass": "^1.55.0" } diff --git a/pages/blog/[year]/[month]/[day]/[slug].vue b/pages/blog/[year]/[month]/[day]/[slug].vue index 153aa4e..802d089 100644 --- a/pages/blog/[year]/[month]/[day]/[slug].vue +++ b/pages/blog/[year]/[month]/[day]/[slug].vue @@ -16,6 +16,7 @@ + {{ post.title }} | Evert's Blog | lunasqu.ee diff --git a/pages/blog/archive/[year]/[month]/[day]/index.vue b/pages/blog/archive/[year]/[month]/[day]/index.vue index b511d1a..d1a2962 100644 --- a/pages/blog/archive/[year]/[month]/[day]/index.vue +++ b/pages/blog/archive/[year]/[month]/[day]/index.vue @@ -1,5 +1,13 @@ @@ -14,7 +22,6 @@ const { data: posts } = await useFetch(`/api/blog`, { year: route.params.year, month: route.params.month, day: route.params.day, - body: false, render: false, }, }); diff --git a/pages/blog/archive/[year]/[month]/index.vue b/pages/blog/archive/[year]/[month]/index.vue index 2a290c0..b44c14f 100644 --- a/pages/blog/archive/[year]/[month]/index.vue +++ b/pages/blog/archive/[year]/[month]/index.vue @@ -1,5 +1,11 @@ @@ -13,7 +19,6 @@ const { data: posts } = await useFetch(`/api/blog`, { params: { year: route.params.year, month: route.params.month, - body: false, render: false, }, }); diff --git a/pages/blog/archive/[year]/index.vue b/pages/blog/archive/[year]/index.vue index 17f6126..f750408 100644 --- a/pages/blog/archive/[year]/index.vue +++ b/pages/blog/archive/[year]/index.vue @@ -1,5 +1,10 @@ @@ -12,7 +17,6 @@ const { data: posts } = await useFetch(`/api/blog`, { key: `${route.params.year}-archive-page`, params: { year: route.params.year, - body: false, render: false, }, }); diff --git a/pages/blog/archive/index.vue b/pages/blog/archive/index.vue index a7187c3..3d21591 100644 --- a/pages/blog/archive/index.vue +++ b/pages/blog/archive/index.vue @@ -1,5 +1,8 @@ @@ -10,7 +13,6 @@ import type { BlogPost } from '~~/lib/types/post'; const { data: posts } = await useFetch(`/api/blog`, { key: `blog-archive`, params: { - body: false, render: false, }, }); diff --git a/pages/blog/tags/[tag].vue b/pages/blog/tags/[tag].vue index 65c8fa5..2ed7400 100644 --- a/pages/blog/tags/[tag].vue +++ b/pages/blog/tags/[tag].vue @@ -1,5 +1,8 @@ @@ -12,7 +15,6 @@ const { data: posts } = await useFetch(`/api/blog`, { key: `${route.params.tag}-tag-page`, params: { tag: route.params.tag, - body: false, render: false, }, }); diff --git a/server/api/blog/index.ts b/server/api/blog/index.ts index f73efe9..cf10d77 100644 --- a/server/api/blog/index.ts +++ b/server/api/blog/index.ts @@ -35,6 +35,6 @@ export default defineEventHandler(async (event) => { return readBlogPosts( include, query.render !== 'false', - query.body !== 'false' + query.body === 'true' ); }); diff --git a/server/routes/blog/atom.xml.ts b/server/routes/blog/atom.xml.ts new file mode 100644 index 0000000..f7b27c6 --- /dev/null +++ b/server/routes/blog/atom.xml.ts @@ -0,0 +1,46 @@ +import { Feed } from 'feed'; +import { readBlogPosts } from '~~/lib/blog/read-posts'; + +const BASE_URL = 'https://lunasqu.ee/blog'; + +export default defineEventHandler(async (event) => { + const posts = await readBlogPosts(undefined, true, false); + const feed = new Feed({ + title: "Evert's Blog", + description: 'Projects and Tutorials', + id: BASE_URL, + link: BASE_URL, + copyright: 'Evert "Diamond" Prants 2022', + language: 'en', + updated: new Date(posts[0].date), + generator: 'https://gitlab.icynet.eu/evert/lunasqu.ee-nuxt', + feedLinks: { + atom: `${BASE_URL}/atom.xml`, + }, + }); + + posts.forEach((post) => { + const description = post.html + .replace(/<[^>]*>?/gm, '') + .replace('\n', ' ') + .substring(0, 240); + + feed.addItem({ + title: post.title, + id: `${BASE_URL}/${post.fullSlug}`, + link: `${BASE_URL}/${post.fullSlug}`, + description, + content: post.html, + date: new Date(post.date), + published: new Date(post.date), + category: post.tags.map((tag) => ({ + term: tag, + scheme: `${BASE_URL}/tags/${tag}`, + })), + }); + }); + + appendResponseHeader(event, 'Content-Type', 'text/xml'); + + return feed.atom1(); +});