atom feed generator, titles
This commit is contained in:
parent
b6b84cfa33
commit
4dfcf1b408
@ -1,7 +1,7 @@
|
|||||||
.blog {
|
.blog {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background-color: rgb(241, 241, 241);
|
background-color: #eee;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: #258fb8;
|
color: #258fb8;
|
||||||
@ -131,17 +131,16 @@
|
|||||||
ul,
|
ul,
|
||||||
ol,
|
ol,
|
||||||
dl {
|
dl {
|
||||||
margin: 0 20px;
|
margin: 1.6em 20px;
|
||||||
line-height: 1.6em;
|
line-height: 1.6em;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin-top: 1.6em;
|
|
||||||
margin-bottom: 1.6em;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__inner {
|
&__inner {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
box-shadow: 1px 2px 3px #ddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__meta {
|
&__meta {
|
||||||
@ -208,7 +207,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: #258fb8;
|
color: #006891;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
@ -225,6 +224,7 @@
|
|||||||
|
|
||||||
&-archives {
|
&-archives {
|
||||||
margin: 50px 0;
|
margin: 50px 0;
|
||||||
|
|
||||||
&__year {
|
&__year {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
font-size: 0.85em;
|
font-size: 0.85em;
|
||||||
@ -245,6 +245,10 @@
|
|||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(3, 1fr);
|
||||||
gap: 1.5rem;
|
gap: 1.5rem;
|
||||||
|
|
||||||
|
@media all and (max-width: 567px) {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__time {
|
&__time {
|
||||||
@ -259,15 +263,12 @@
|
|||||||
&__post {
|
&__post {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
|
box-shadow: 1px 2px 3px #ddd;
|
||||||
|
|
||||||
header {
|
header {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
h1 {
|
|
||||||
margin-top: auto;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,13 @@
|
|||||||
<Meta property="og:locale" content="en_US" />
|
<Meta property="og:locale" content="en_US" />
|
||||||
<Meta property="article:author" content="Evert Prants" />
|
<Meta property="article:author" content="Evert Prants" />
|
||||||
<Meta name="twitter:card" content="summary" />
|
<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>
|
</Head>
|
||||||
<header class="blog__header">
|
<header class="blog__header">
|
||||||
<h1><NuxtLink to="/blog">Blog</NuxtLink></h1>
|
<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;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ export default defineNuxtConfig({
|
|||||||
hooks: {
|
hooks: {
|
||||||
async 'nitro:config'(config) {
|
async 'nitro:config'(config) {
|
||||||
const routes = await generatePaths('/blog/');
|
const routes = await generatePaths('/blog/');
|
||||||
config.prerender.routes.push(...routes);
|
config.prerender.routes.push(...routes, '/blog/atom.xml');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
49
package-lock.json
generated
49
package-lock.json
generated
@ -6,6 +6,7 @@
|
|||||||
"": {
|
"": {
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"feed": "^4.2.2",
|
||||||
"highlight.js": "^11.6.0",
|
"highlight.js": "^11.6.0",
|
||||||
"sass": "^1.55.0"
|
"sass": "^1.55.0"
|
||||||
},
|
},
|
||||||
@ -3320,6 +3321,17 @@
|
|||||||
"reusify": "^1.0.4"
|
"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": {
|
"node_modules/fetch-blob": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
|
||||||
@ -6250,6 +6262,11 @@
|
|||||||
"node": ">=12.0.0"
|
"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": {
|
"node_modules/scule": {
|
||||||
"version": "0.3.2",
|
"version": "0.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/scule/-/scule-0.3.2.tgz",
|
"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": {
|
"node_modules/xxhashjs": {
|
||||||
"version": "0.2.2",
|
"version": "0.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz",
|
||||||
@ -10029,6 +10057,14 @@
|
|||||||
"reusify": "^1.0.4"
|
"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": {
|
"fetch-blob": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
|
"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"
|
"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": {
|
"scule": {
|
||||||
"version": "0.3.2",
|
"version": "0.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/scule/-/scule-0.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/scule/-/scule-0.3.2.tgz",
|
||||||
@ -13114,6 +13155,14 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {}
|
"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": {
|
"xxhashjs": {
|
||||||
"version": "0.2.2",
|
"version": "0.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz",
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
"yaml": "^2.1.3"
|
"yaml": "^2.1.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"feed": "^4.2.2",
|
||||||
"highlight.js": "^11.6.0",
|
"highlight.js": "^11.6.0",
|
||||||
"sass": "^1.55.0"
|
"sass": "^1.55.0"
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
<Meta property="article:author" content="Evert Prants" />
|
<Meta property="article:author" content="Evert Prants" />
|
||||||
<Meta v-for="tag in post.tags" property="article:tag" :content="tag" />
|
<Meta v-for="tag in post.tags" property="article:tag" :content="tag" />
|
||||||
<Meta name="twitter:card" content="summary" />
|
<Meta name="twitter:card" content="summary" />
|
||||||
|
<Title>{{ post.title }} | Evert's Blog | lunasqu.ee</Title>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
<BlogPost :post="post" :detail="true" />
|
<BlogPost :post="post" :detail="true" />
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<NuxtLayout name="blog">
|
<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" />
|
<BlogArchive :posts="posts" />
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
</template>
|
</template>
|
||||||
@ -14,7 +22,6 @@ const { data: posts } = await useFetch<BlogPost[]>(`/api/blog`, {
|
|||||||
year: route.params.year,
|
year: route.params.year,
|
||||||
month: route.params.month,
|
month: route.params.month,
|
||||||
day: route.params.day,
|
day: route.params.day,
|
||||||
body: false,
|
|
||||||
render: false,
|
render: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<NuxtLayout name="blog">
|
<NuxtLayout name="blog">
|
||||||
|
<Head>
|
||||||
|
<Title
|
||||||
|
>Archive: {{ route.params.year }}/{{ route.params.month }} | Evert's
|
||||||
|
Blog | lunasqu.ee</Title
|
||||||
|
>
|
||||||
|
</Head>
|
||||||
<BlogArchive :posts="posts" />
|
<BlogArchive :posts="posts" />
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
</template>
|
</template>
|
||||||
@ -13,7 +19,6 @@ const { data: posts } = await useFetch<BlogPost[]>(`/api/blog`, {
|
|||||||
params: {
|
params: {
|
||||||
year: route.params.year,
|
year: route.params.year,
|
||||||
month: route.params.month,
|
month: route.params.month,
|
||||||
body: false,
|
|
||||||
render: false,
|
render: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<NuxtLayout name="blog">
|
<NuxtLayout name="blog">
|
||||||
|
<Head>
|
||||||
|
<Title
|
||||||
|
>Archive: {{ route.params.year }} | Evert's Blog | lunasqu.ee</Title
|
||||||
|
>
|
||||||
|
</Head>
|
||||||
<BlogArchive :posts="posts" />
|
<BlogArchive :posts="posts" />
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
</template>
|
</template>
|
||||||
@ -12,7 +17,6 @@ const { data: posts } = await useFetch<BlogPost[]>(`/api/blog`, {
|
|||||||
key: `${route.params.year}-archive-page`,
|
key: `${route.params.year}-archive-page`,
|
||||||
params: {
|
params: {
|
||||||
year: route.params.year,
|
year: route.params.year,
|
||||||
body: false,
|
|
||||||
render: false,
|
render: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<NuxtLayout name="blog">
|
<NuxtLayout name="blog">
|
||||||
|
<Head>
|
||||||
|
<Title>Archive | Evert's Blog | lunasqu.ee</Title>
|
||||||
|
</Head>
|
||||||
<BlogArchive :posts="posts" />
|
<BlogArchive :posts="posts" />
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
</template>
|
</template>
|
||||||
@ -10,7 +13,6 @@ import type { BlogPost } from '~~/lib/types/post';
|
|||||||
const { data: posts } = await useFetch<BlogPost[]>(`/api/blog`, {
|
const { data: posts } = await useFetch<BlogPost[]>(`/api/blog`, {
|
||||||
key: `blog-archive`,
|
key: `blog-archive`,
|
||||||
params: {
|
params: {
|
||||||
body: false,
|
|
||||||
render: false,
|
render: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<NuxtLayout name="blog">
|
<NuxtLayout name="blog">
|
||||||
|
<Head>
|
||||||
|
<Title>Tag: {{ route.params.tag }} | Evert's Blog | lunasqu.ee</Title>
|
||||||
|
</Head>
|
||||||
<BlogArchive :posts="posts" />
|
<BlogArchive :posts="posts" />
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
</template>
|
</template>
|
||||||
@ -12,7 +15,6 @@ const { data: posts } = await useFetch<BlogPost[]>(`/api/blog`, {
|
|||||||
key: `${route.params.tag}-tag-page`,
|
key: `${route.params.tag}-tag-page`,
|
||||||
params: {
|
params: {
|
||||||
tag: route.params.tag,
|
tag: route.params.tag,
|
||||||
body: false,
|
|
||||||
render: false,
|
render: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -35,6 +35,6 @@ export default defineEventHandler(async (event) => {
|
|||||||
return readBlogPosts(
|
return readBlogPosts(
|
||||||
include,
|
include,
|
||||||
query.render !== 'false',
|
query.render !== 'false',
|
||||||
query.body !== 'false'
|
query.body === 'true'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
46
server/routes/blog/atom.xml.ts
Normal file
46
server/routes/blog/atom.xml.ts
Normal file
@ -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…
Reference in New Issue
Block a user