atom feed generator, titles

blog-generator
Evert Prants 4 months ago
parent b6b84cfa33
commit 4dfcf1b408
Signed by: evert
GPG Key ID: 1688DA83D222D0B5

@ -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;
}
}
}
}

@ -8,6 +8,13 @@
<Meta property="og:locale" content="en_US" />
<Meta property="article:author" content="Evert Prants" />
<Meta name="twitter:card" content="summary" />
<Link
rel="alternate"
href="/blog/atom.xml"
title="Evert's Blog"
type="application/atom+xml"
/>
<Title>Evert's Blog | lunasqu.ee</Title>
</Head>
<header class="blog__header">
<h1><NuxtLink to="/blog">Blog</NuxtLink></h1>

@ -107,6 +107,8 @@ export async function getTags(): Promise<BlogPostTag[]> {
}
}
obj.sort((a, b) => a.name.localeCompare(b.name, 'en'));
return obj;
}

@ -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');
},
},
});

49
package-lock.json generated

@ -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",

@ -15,6 +15,7 @@
"yaml": "^2.1.3"
},
"dependencies": {
"feed": "^4.2.2",
"highlight.js": "^11.6.0",
"sass": "^1.55.0"
}

@ -16,6 +16,7 @@
<Meta property="article:author" content="Evert Prants" />
<Meta v-for="tag in post.tags" property="article:tag" :content="tag" />
<Meta name="twitter:card" content="summary" />
<Title>{{ post.title }} | Evert's Blog | lunasqu.ee</Title>
</Head>
<BlogPost :post="post" :detail="true" />

@ -1,5 +1,13 @@
<template>
<NuxtLayout name="blog">
<Head>
<Title
>Archive: {{ route.params.year }}/{{ route.params.month }}/{{
route.params.day
}}
| Evert's Blog | lunasqu.ee</Title
>
</Head>
<BlogArchive :posts="posts" />
</NuxtLayout>
</template>
@ -14,7 +22,6 @@ const { data: posts } = await useFetch<BlogPost[]>(`/api/blog`, {
year: route.params.year,
month: route.params.month,
day: route.params.day,
body: false,
render: false,
},
});

@ -1,5 +1,11 @@
<template>
<NuxtLayout name="blog">
<Head>
<Title
>Archive: {{ route.params.year }}/{{ route.params.month }} | Evert's
Blog | lunasqu.ee</Title
>
</Head>
<BlogArchive :posts="posts" />
</NuxtLayout>
</template>
@ -13,7 +19,6 @@ const { data: posts } = await useFetch<BlogPost[]>(`/api/blog`, {
params: {
year: route.params.year,
month: route.params.month,
body: false,
render: false,
},
});

@ -1,5 +1,10 @@
<template>
<NuxtLayout name="blog">
<Head>
<Title
>Archive: {{ route.params.year }} | Evert's Blog | lunasqu.ee</Title
>
</Head>
<BlogArchive :posts="posts" />
</NuxtLayout>
</template>
@ -12,7 +17,6 @@ const { data: posts } = await useFetch<BlogPost[]>(`/api/blog`, {
key: `${route.params.year}-archive-page`,
params: {
year: route.params.year,
body: false,
render: false,
},
});

@ -1,5 +1,8 @@
<template>
<NuxtLayout name="blog">
<Head>
<Title>Archive | Evert's Blog | lunasqu.ee</Title>
</Head>
<BlogArchive :posts="posts" />
</NuxtLayout>
</template>
@ -10,7 +13,6 @@ import type { BlogPost } from '~~/lib/types/post';
const { data: posts } = await useFetch<BlogPost[]>(`/api/blog`, {
key: `blog-archive`,
params: {
body: false,
render: false,
},
});

@ -1,5 +1,8 @@
<template>
<NuxtLayout name="blog">
<Head>
<Title>Tag: {{ route.params.tag }} | Evert's Blog | lunasqu.ee</Title>
</Head>
<BlogArchive :posts="posts" />
</NuxtLayout>
</template>
@ -12,7 +15,6 @@ const { data: posts } = await useFetch<BlogPost[]>(`/api/blog`, {
key: `${route.params.tag}-tag-page`,
params: {
tag: route.params.tag,
body: false,
render: false,
},
});

@ -35,6 +35,6 @@ export default defineEventHandler(async (event) => {
return readBlogPosts(
include,
query.render !== 'false',
query.body !== 'false'
query.body === 'true'
);
});

@ -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();
});
Loading…
Cancel
Save