feat: add a tags field to the New Blog Post form

This commit is contained in:
wilson 2026-04-28 21:58:09 +01:00
parent ee5733275b
commit 1cf54809bd
2 changed files with 66 additions and 45 deletions

View file

@ -1,15 +1,15 @@
import { BlogController } from '$lib/blog/BlogController.js'; import { BlogController } from "$lib/blog/BlogController.js";
import type { Actions } from '@sveltejs/kit'; import type { Actions } from "@sveltejs/kit";
import { error, redirect } from '@sveltejs/kit'; import { error, redirect } from "@sveltejs/kit";
import { dump as dumpYaml } from 'js-yaml'; import { dump as dumpYaml } from "js-yaml";
import { resolve } from 'path'; import { resolve } from "path";
export const prerender = false; export const prerender = false;
const thisDirectory = import.meta.url const thisDirectory = import.meta.url
.replace('file://', '') .replace("file://", "")
.split('/') .split("/")
.filter((part) => part !== '+server.ts') .filter((part) => part !== "+server.ts")
.join('/'); .join("/");
export const actions = { export const actions = {
default: async ({ getClientAddress, request }) => { default: async ({ getClientAddress, request }) => {
@ -19,38 +19,53 @@ export const actions = {
let title: string; let title: string;
let slug: string; let slug: string;
let author: string; let author: string;
let commaSeparatedTags: string;
try { try {
const requestBody = await request.formData(); const requestBody = await request.formData();
markdownContent = requestBody.get('content') as string; markdownContent = requestBody.get("content") as string;
title = requestBody.get('title') as string; title = requestBody.get("title") as string;
slug = requestBody.get('slug') as string; slug = requestBody.get("slug") as string;
author = requestBody.get('author') as string; author = requestBody.get("author") as string;
commaSeparatedTags = requestBody.get("tags") as string;
} catch (e: any) { } catch (e: any) {
console.log(`Caught error destructuring request body`); console.log(`Caught error destructuring request body`);
console.error(e); console.error(e);
error(400, 'Error in request body.'); error(400, "Error in request body.");
} }
if ([markdownContent, title, slug, author].includes(undefined)) { if ([markdownContent, title, slug, author].includes(undefined)) {
error(400, `Missing parameters.`); error(400, `Missing parameters.`);
} else if (!['127.0.0.1', '::1'].includes(address)) { } else if (!["127.0.0.1", "::1"].includes(address)) {
console.log(address); console.log(address);
error(403, `Forbidden.`); error(403, `Forbidden.`);
} }
const controller = await BlogController.singleton(); const controller = await BlogController.singleton();
const worryinglyManualFrontMatter = [`---`, dumpYaml({ title, date: new Date(), slug, author }), `---`].join( const tags = commaSeparatedTags
`\n` .split(",")
.map((s) => s.trim())
.filter((s) => s.length > 0);
const worryinglyManualFrontMatter = [
`---`,
dumpYaml({ title, date: new Date(), slug, author, tags }),
`---`,
].join(`\n`);
const escapedMarkdown = markdownContent.replaceAll(/\\n/g, "\n");
const contentWithFrontmatter = [
worryinglyManualFrontMatter,
escapedMarkdown,
].join(`\n`);
const resolvedFileName = resolve(
thisDirectory,
`../../../../content/blog/${slug}.md`,
); );
const escapedMarkdown = markdownContent.replaceAll(/\\n/g, '\n');
const contentWithFrontmatter = [worryinglyManualFrontMatter, escapedMarkdown].join(`\n`);
const resolvedFileName = resolve(thisDirectory, `../../../../content/blog/${slug}.md`);
console.log({ resolvedFileName }); console.log({ resolvedFileName });
console.log(`\n${contentWithFrontmatter}\n`); console.log(`\n${contentWithFrontmatter}\n`);

View file

@ -6,6 +6,7 @@
let date = new Date(); let date = new Date();
let content = $state(""); let content = $state("");
let slug = $state(""); let slug = $state("");
let tags = $state("");
let blogPost: BlogPost | null = null; let blogPost: BlogPost | null = null;
function slugifyString(originalString: string): string { function slugifyString(originalString: string): string {
@ -63,6 +64,11 @@
<input type="text" name="slug" id="slug" required bind:value={slug} /> <input type="text" name="slug" id="slug" required bind:value={slug} />
</div> </div>
<div class="field">
<label class="field__label" for="tags">Tags (comma-separate)</label>
<input type="text" name="tags" id="slitags" bind:value={tags} />
</div>
<div class="field"> <div class="field">
<label class="field__label" for="content">Content</label> <label class="field__label" for="content">Content</label>
<textarea <textarea