Add blog generation from Markdown.

Also tweak README, and homepage title font.
This commit is contained in:
Sage Vaillancourt 2022-09-02 15:40:07 -04:00
parent 691a8a72eb
commit 199a38a6f2
12 changed files with 287 additions and 24 deletions

View File

@ -1,22 +1,10 @@
# create-svelte
# Kafka Dance Site
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte).
## Creating a project
If you're seeing this, you've probably already done this step. Congrats!
```bash
# create a new project in the current directory
npm create svelte@latest
# create a new project in my-app
npm create svelte@latest my-app
```
Powered by Svelte!
## Developing
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
Once you've downloaded the project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
```bash
npm run dev
@ -27,12 +15,12 @@ npm run dev -- --open
## Building
To create a production version of your app:
To build out the production version:
```bash
npm run build
```
You can preview the production build with `npm run preview`.
This is currently configured to build as a completely static app.
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.
You can preview the production build with `npm run preview`.

113
package-lock.json generated
View File

@ -11,6 +11,7 @@
"@sveltejs/adapter-auto": "next",
"@sveltejs/adapter-static": "^1.0.0-next.41",
"@sveltejs/kit": "next",
"mdsvex": "^0.10.6",
"svelte": "^3.44.0",
"svelte-check": "^2.7.1",
"typescript": "^4.7.4",
@ -293,6 +294,12 @@
"@types/node": "*"
}
},
"node_modules/@types/unist": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
"integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==",
"dev": true
},
"node_modules/@vercel/nft": {
"version": "0.22.0",
"resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.22.0.tgz",
@ -1339,6 +1346,21 @@
"semver": "bin/semver.js"
}
},
"node_modules/mdsvex": {
"version": "0.10.6",
"resolved": "https://registry.npmjs.org/mdsvex/-/mdsvex-0.10.6.tgz",
"integrity": "sha512-aGRDY0r5jx9+OOgFdyB9Xm3EBr9OUmcrTDPWLB7a7g8VPRxzPy4MOBmcVYgz7ErhAJ7bZ/coUoj6aHio3x/2mA==",
"dev": true,
"dependencies": {
"@types/unist": "^2.0.3",
"prism-svelte": "^0.4.7",
"prismjs": "^1.17.1",
"vfile-message": "^2.0.4"
},
"peerDependencies": {
"svelte": "3.x"
}
},
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@ -1644,6 +1666,21 @@
"node": "^10 || ^12 || >=14"
}
},
"node_modules/prism-svelte": {
"version": "0.4.7",
"resolved": "https://registry.npmjs.org/prism-svelte/-/prism-svelte-0.4.7.tgz",
"integrity": "sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==",
"dev": true
},
"node_modules/prismjs": {
"version": "1.29.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
"integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@ -2201,12 +2238,39 @@
"node": ">=12.18"
}
},
"node_modules/unist-util-stringify-position": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
"integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==",
"dev": true,
"dependencies": {
"@types/unist": "^2.0.2"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true
},
"node_modules/vfile-message": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz",
"integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==",
"dev": true,
"dependencies": {
"@types/unist": "^2.0.0",
"unist-util-stringify-position": "^2.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/vite": {
"version": "3.1.0-beta.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.1.0-beta.1.tgz",
@ -2525,6 +2589,12 @@
"@types/node": "*"
}
},
"@types/unist": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
"integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==",
"dev": true
},
"@vercel/nft": {
"version": "0.22.0",
"resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.22.0.tgz",
@ -3220,6 +3290,18 @@
}
}
},
"mdsvex": {
"version": "0.10.6",
"resolved": "https://registry.npmjs.org/mdsvex/-/mdsvex-0.10.6.tgz",
"integrity": "sha512-aGRDY0r5jx9+OOgFdyB9Xm3EBr9OUmcrTDPWLB7a7g8VPRxzPy4MOBmcVYgz7ErhAJ7bZ/coUoj6aHio3x/2mA==",
"dev": true,
"requires": {
"@types/unist": "^2.0.3",
"prism-svelte": "^0.4.7",
"prismjs": "^1.17.1",
"vfile-message": "^2.0.4"
}
},
"merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@ -3424,6 +3506,18 @@
"source-map-js": "^1.0.2"
}
},
"prism-svelte": {
"version": "0.4.7",
"resolved": "https://registry.npmjs.org/prism-svelte/-/prism-svelte-0.4.7.tgz",
"integrity": "sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==",
"dev": true
},
"prismjs": {
"version": "1.29.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
"integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==",
"dev": true
},
"queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@ -3786,12 +3880,31 @@
"integrity": "sha512-c8HsD3IbwmjjbLvoZuRI26TZic+TSEe8FPMLLOkN1AfYRhdjnKBU6yL+IwcSCbdZiX4e5t0lfMDLDCqj4Sq70g==",
"dev": true
},
"unist-util-stringify-position": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
"integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==",
"dev": true,
"requires": {
"@types/unist": "^2.0.2"
}
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true
},
"vfile-message": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz",
"integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==",
"dev": true,
"requires": {
"@types/unist": "^2.0.0",
"unist-util-stringify-position": "^2.0.0"
}
},
"vite": {
"version": "3.1.0-beta.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.1.0-beta.1.tgz",

View File

@ -13,6 +13,7 @@
"@sveltejs/adapter-auto": "next",
"@sveltejs/adapter-static": "^1.0.0-next.41",
"@sveltejs/kit": "next",
"mdsvex": "^0.10.6",
"svelte": "^3.44.0",
"svelte-check": "^2.7.1",
"typescript": "^4.7.4",

View File

@ -1,4 +1,4 @@
@import url('https://fonts.googleapis.com/css2?family=Fira+Sans&family=Montserrat:wght@500&family=Roboto&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Fira+Sans&family=Inter:wght@700&family=Montserrat:wght@500&family=Roboto&display=swap');
:root {
font-family: 'Fira Sans', Arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
@ -176,8 +176,8 @@ h1 {
}
h1 .fun {
/*font-family: sans-serif;*/
font-weight: 600;
font-family: 'Inter', sans-serif;
font-weight: 700;
color: var(--accent-color);
}
@ -255,7 +255,7 @@ button:focus:not(:focus-visible) {
@media (min-width: 720px) {
h1 {
font-size: 5rem;
font-size: 6rem;
}
h2 {
font-size: 2rem;

View File

@ -3,7 +3,7 @@
const routes = [
{ path: '/', name: 'Home' },
{ path: '/download', name: 'Download' },
//{ path: '/about', name: 'About' }
{ path: '/blog', name: 'Blog' },
]
</script>

View File

@ -0,0 +1,28 @@
import { json } from '@sveltejs/kit'
const fetchMarkdownPosts = async () => {
const allPostFiles = import.meta.glob('/src/routes/blog/*.md')
const iterablePostFiles = Object.entries(allPostFiles)
return Promise.all(
iterablePostFiles.map(async ([path, resolver]) => {
const { metadata } = await resolver()
const postPath = path.slice(11, -3)
return {
meta: metadata,
path: postPath,
}
})
)
}
export const GET = async () => {
const allPosts = await fetchMarkdownPosts()
const sortedPosts = allPosts.sort((a, b) => {
return new Date(b.meta.date) - new Date(a.meta.date)
})
return json(sortedPosts)
}

4
src/routes/blog/+page.js Normal file
View File

@ -0,0 +1,4 @@
export async function load ({ fetch }) {
const response = await fetch('/api/posts')
return await response.json()
}

View File

@ -0,0 +1,63 @@
<script>
export let data = {}
$: dataList = Object.values(data)
</script>
<h1>Blog</h1>
<div class="content">
{#each dataList as datum}
<a href={datum.path}>
<div class="with-image">
<div class="blog-entry">
<div class="metadata">
<h2>{datum.meta.title}</h2>
<p>{datum.meta.date}</p>
</div>
<p class="description">{datum.meta.description}</p>
</div>
<img src={datum.meta.headerImage} alt={datum.meta.headerImageAlt}>
</div>
</a>
{/each}
</div>
<style>
.with-image {
background-color: rgba(0, 0, 0, 0.03);
padding: 1em;
transition: background-color 300ms;
}
.with-image:hover {
background-color: rgba(0, 0, 0, 0.08);
}
.blog-entry {
display: flex;
flex-direction: column;
}
.metadata {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.metadata * {
margin: 0;
}
.content {
flex-grow: 1;
display: flex;
flex-direction: column;
align-items: center;
}
a {
text-decoration: none;
}
@media (min-width: 720px) {
.blog-entry {
max-width: 70vw;
}
}
</style>

View File

@ -0,0 +1,9 @@
export async function load({ params }){
const post = await import(/* @vite-ignore */ `../${params.post}.md`)
const content = post.default
return {
content,
metadata: post.metadata,
}
}

View File

@ -0,0 +1,40 @@
<script>
export let data
</script>
<div class="title-with-image">
<h1>{data.metadata.title}</h1>
<img src={data.metadata.headerImage} alt={data.metadata.headerImageAlt}/>
</div>
<svelte:component this={data.content} />
<style>
.title-with-image {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: center;
line-height: 100%;
}
.title-with-image img {
margin: 2em 2em 0;
}
/*
.title-with-image h1 {
flex-grow: 1;
}
.title-with-image img {
flex-grow: 1;
max-width: 100%;
}
*/
.title-with-image img {
max-width: 80vw;
}
@media (min-width: 720px) {
.title-with-image img {
max-width: 30vw;
}
}
</style>

View File

@ -0,0 +1,9 @@
---
title: What is Kafka?
date: "2022-09-02"
description: "A brief description of the increasingly-popular event system, Apache Kafka."
headerImage: "/kafka-logo.png"
headerImageAlt: "Kafka's logo"
---
Initially built by LinkedIn, Kafka

View File

@ -1,4 +1,5 @@
import adapter from '@sveltejs/adapter-static';
import { mdsvex } from "mdsvex";
/** @type {import('@sveltejs/kit').Config} */
const config = {
@ -9,7 +10,14 @@ const config = {
fallback: null,
precompress: false
}),
}
},
extensions: ['.svelte', '.svx', '.md'],
preprocess: [
mdsvex({
extensions: ['.svx', '.md']
})
],
};
export default config;